Installing Armory in the Google Kubernetes Engine using the Armory Operator

Learn how to install Armory or Spinnaker in a Google Kubernetes Engine cluster using the Armory Operator.

This guide contains instructions for installing Armory on a Google Kubernetes Engine (GKE) cluster using the Armory Operator. Refer to the Armory Operator Reference for manifest entry details.

If you want to install SpinnakerTM, use the open source Operator, which you can download from its GitHub repo.

Prerequisites for installing Armory and the Armory Operator

  • You have a machine configured to use the gcloud CLI tool and a recent version of the kubectl tool
  • You have logged into the gcloud CLI and have permissions to create GKE clusters and a service account

Armory installation summary

Installing Armory using the Armory Operator consists of the following steps:

  • Create a cluster where Armory and the Armory Operator will reside
  • Deploy Armory Operator pods to the cluster
  • Create a GCS service account
  • Create a Kubernetes service account
  • Create a Google Cloud Storage (GCS) bucket
  • Modify the Armory Operator kustomize files for your installation
  • Deploy Armory using the Armory Operator

Create a GKE cluster

This creates a minimal GKE cluster in your default region and zone.

gcloud container clusters create spinnaker-cluster
export KUBECONFIG=kubeconfig-gke
gcloud container clusters get-credentials spinnaker-cluster

Check that namespaces have been created:

kubectl --kubeconfig kubeconfig-gke get namespaces

Output is similar to:

default Active 2m24s
kube-node-lease Active 2m26s
kube-public Active 2m26s
kube-system Active 2m26s

Install the Armory Operator

The Armory Operator has two distinct modes:

  • Basic: Installs Armory into a single namespace. This mode does not perform pre-flight checks before applying a manifest.
  • Cluster: Installs Armory across namespaces with pre-flight checks to prevent common misconfigurations. This mode requires a ClusterRole.

Get the latest release from

mkdir -p spinnaker-operator && cd spinnaker-operator
bash -c 'curl -L | tar -xz'

# Install or update CRDs cluster wide kubectl apply -f deploy/crds/

# We'll install in the spinnaker-operator namespace kubectl create ns spinnaker-operator

Next, install Operator in either cluster or basic mode:

# Install Operator cluster mode
kubectl -n spinnaker-operator apply -f deploy/operator/cluster
# OR install Operator in basic mode
# kubectl -n spinnaker-operator apply -f deploy/operator/basic

After installation, you can verify that the Operator is running with the following command:

kubectl -n spinnaker-operator get pods

The command returns output similar to the following if the pod for the Operator is running:

NAMESPACE                             READY         STATUS       RESTARTS      AGE
spinnaker-operator-7cd659654b-4vktl   2/2           Running      0             6s

If you want to use a namespace other than spinnaker-operator in cluster mode, you’ll also need to edit the namespace in deploy/operator/cluster/role_binding.yaml.

Create a GCS service account

export SERVICE_ACCOUNT_NAME=<name-for-your-service-account>
export SERVICE_ACCOUNT_FILE=<name=for-your-service-account.json>
export PROJECT=$(gcloud info --format='value(config.project)')

gcloud --project ${PROJECT} iam service-accounts create \
    --display-name ${SERVICE_ACCOUNT_NAME}

SA_EMAIL=$(gcloud --project ${PROJECT} iam service-accounts list \
    --filter="displayName:${SERVICE_ACCOUNT_NAME}" \

gcloud --project ${PROJECT} projects add-iam-policy-binding ${PROJECT} \
    --role roles/storage.admin --member serviceAccount:${SA_EMAIL}

mkdir -p $(dirname ${SERVICE_ACCOUNT_FILE})

gcloud --project ${PROJECT} iam service-accounts keys create ${SERVICE_ACCOUNT_FILE} \
    --iam-account ${SA_EMAIL}

Create Kubernetes service account

CONTEXT=$(kubectl config current-context)

# This service account uses the ClusterAdmin role -- this is not necessary,
# more restrictive roles can by applied.
curl -s | \
  sed "s/spinnaker-service-account/${SERVICE_ACCOUNT_NAME}/g" | \
  kubectl apply --context $CONTEXT -f -

TOKEN=$(kubectl get secret --context $CONTEXT \
   $(kubectl get serviceaccount ${SERVICE_ACCOUNT_NAME} \
       --context $CONTEXT \
       -n spinnaker \
       -o jsonpath='{.secrets[0].name}') \
   -n spinnaker \
   -o jsonpath='{.data.token}' | base64 --decode)

kubectl config set-credentials ${CONTEXT}-token-user --token $TOKEN

kubectl config set-context $CONTEXT --user ${CONTEXT}-token-user

Create a GCS bucket

Use the Cloud Console to create your bucket. If you’re going to put secrets in the bucket, make sure to create a secrets directory in that bucket. Also, make sure that the Kubernetes service account you created can access the bucket.

Configure Kustomize patches and install Armory

Many common configuration options for Armory and SpinnakerTM are available in the spinnaker-kustomize-patches repository. This gives you a reliable starting point when adding and removing Armory or Spinnaker features to your cluster.

To start, create your own copy of the spinnaker-kustomize-patches repository by clicking the Use this template button:


Once created, clone this repository to your local machine.

If you installed Operator in basic mode, you must set the namespace field in your kustomization.yml file to the spinnaker-operator namespace. The permissions in basic mode are scoped to a single namespace so it doesn’t see anything in other namespaces.

Once configured, run the following command to install:

# If you have `kustomize` installed:
kustomize build | kubectl apply -f -

# If you only have kubectl installed: kubectl apply -k .

Watch the install progress and check out the pods being created:

kubectl -n spinnaker get spinsvc spinnaker -w

How configuration works

Armory’s configuration is found in a Custom Resource Definition (CRD) that you can store in version control. After you install the Armory Operator, you can use kubectl to manage the lifecycle of your deployment.

kind: SpinnakerService
  name: spinnaker
      # Change the `.x` segment to the latest patch release found on our website:
      version: 2.23.x

See the full format for more configuration options.

Customize your Spinnaker installation

Add GCP credentials as a cluster secret

The kustomize template repository that you cloned enables you to easily create Secret objects within your Kubernetes cluster so you can securely access credentials. Place the ${SERVICE_ACCOUNT_FILE} file in the ./secrets/files directory and run the ./secrets/ script.

Adding persistance to Spinnaker

Create a file in your kustomize directory called ./patch-gcs.yml and add it to the patchesStrategicMerge section of your kustomization.yml file.

The contents of that file should look something like this:

kind: SpinnakerService
  name: spinnaker
        persistentStoreType: gcs
          bucket: <YOUR_GCS_BUCKET_NAME>
          rootFolder: front50  
          jsonPath: encryptedFile:k8s!n:spin-secrets!k:<SERVICE_ACCOUNT_FILE>

Remember to replace <YOUR_GCS_BUCKET_NAME> with your bucket name. You should also update the <SERVICE_ACCOUNT_FILE> at the end of the jsonPath segment with the name of the service account file you added in the Add GCP credentials as a cluster secret section.

Install Kustomize (optional)

You can do a kubectl -k to deploy Kustomize templates, but what may be more helpful is to install Kustomize standalone so that you can build Kustomize and look at the YAML first.

curl -s "\
kubernetes-sigs/kustomize/master/hack/"  | bash
sudo mv kustomize /usr/local/bin/

Deploy Armory using Kustomize

kubectl create ns <spinnaker-namespace>
kustomize build | kubectl apply -f -

Configure ingress

The spinnaker-kustomize-patches repository contains several examples for exposing ingress to your cluster. Consult the examples in the expose directory and choose the most appropriate example for your environment. Make any modifications to the examples for your environment, then make sure the file is listed in the patchesStrategicMerge section of your kustomization.yml file.

See spec.expose for more information.

Configure authentication

The spinnaker-kustomize-patches repository contains several examples for adding authentication to your cluster. Consult the examples in the security directory and choose the most appropriate example for your environment. For example, to enable basic auth, modify the security/patch-basic-auth.yml by changing the username to one of your choosing. Then, add the file path to your kustomization.yml file in the patchesStrategicMerge section. Finally, modify the secrets-example.env file to choose a password unique to you, and run the ./ script to create Kubernetes credentials in your cluster.

Make sure you enable the right Auth Scopes on the GKE node pools, or you may see authentication issues trying to write to Google Cloud Storage for logging.

Configure Dinghy

The spinnaker-kustomize-patches repository contains a patch for enabling Dinghy in your Armory cluster. Be sure to modify the armory/patch-dinghy.yml file with configuration specific to your environment, then make sure the file is listed in the patchesStrategicMerge section of your kustomization.yml file.

Now add an entry to the end of kustomization.yml to include patch-dinghy.yml.

Other patch files

The spinnaker-kustomize-patches repository contains many more example patches to further customize your Armory cluster. Explore the repositoryto see if there are features you’d like to try out.