Skip to content

Elevating IaC Workflows with Spacelift Stacks and Dependencies ๐Ÿ› ๏ธ

Register for the July 23 demo โ†’

Google Cloud Platform (GCP)ยป

Configuring Workload Identityยป

In order to enable Spacelift runs to access GCP resources, you need to set up Spacelift as a valid identity provider for your account. To do this you need to perform a number of steps within GCP:

  • Create a workload identity pool and set up the Spacelift OIDC provider as an identity provider for it;
  • Create a service account that will be used by Spacelift;
  • Connect the service account to the workload identity pool;

Let's go through these steps one by one. First, you will want to go to the GCP console and select the IAM service, then click on the "Workload Identity Federation" link in the left-hand menu:

If this is your first time creating a Workload Identity Pools, you will click on the Get Started button.

GCP Workload Identity Federation Get Started

If you have created a Workload Identity Pool before, your screen should look like:

GCP Workload Identity Federation

From there, you will want to click on the Create pool button, which will take you to the pool creation form. First, give your new identity pool a name and optionally set a description. The next step is more interesting - you will need to set up an identity provider. The name is pretty much arbitrary but the rest of the fields are important to get right. The Issuer URL needs to be set to the URL of your Spacelift account (including the scheme). You will want to manually specify allowed audiences. There's just one you need - the hostname of your Spacelift account. Here is what a properly filled out form would look like:

Adding workload identity provider to GCP

Hint

You will need to add iss to Issuer (URL) and you will need to add aud to Audience. You will need to replace demo.app.spacelift.io and demo@spacelift.io with the hostname of your Spacelift account.

In the last step, you will need to configure a mapping between provider Spacelift token claims (assertions) and Google attributes. google.subject is a required mapping and should generally map to assertion.sub. Custom claims can be mapped to custom attributes, which need to start with the attribute. prefix. In the below example, we are also mapping Spacelift's spaceId claim to GCP's custom space attribute:

GCP provider attribute mapping

To restrict which identities can authenticate using your workload identity pool you can specify extra conditions using Google's Common Expression Language.

Warning

If your Stack ID is too long, it may exceed the threshold set by Google for the google.subject mapping. In that case, you can use a different Custom claim to create the mapping.

Last but not least, we will want to grant the workload identity pool the ability to impersonate the service account we will be using. Assuming we already have a service account, let's allow any token claiming to originate from the prod space in our Spacelift account to impersonate it:

GCP granting access to service account

Make sure you use the full space id and not the space name.

Downloading the Configuration Fileยป

After clicking save on the previous screen, you will be brought to download the configuration file. Here, you will need to change the OIDC ID token path to /mnt/workspace/spacelift.oidc and change the format to json.

GCP config file

The file that is downloaded will include the format type in the credentials source. You can remove this so you credentials section just contains:

1
2
3
 "credential_source": {
    "file": "/mnt/workspace/spacelift.oidc"
  }

Configuring the Terraform Providerยป

Once the Spacelift-GCP OIDC integration is set up, the Google Cloud Terraform provider can be configured without the need for any static credentials. You will however want to provide a configuration file telling the provider how to authenticate. The configuration file can be created manually or generated by the gcloud utility and would look like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
{
  "type": "external_account",
  "audience": "//iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${WORKER_POOL_ID}/providers/${IDENTITY_PROVIDER_ID}",
  "subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
  "token_url": "https://sts.googleapis.com/v1/token",
  "credential_source": {
    "file": "/mnt/workspace/spacelift.oidc"
  },
  "service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/${SERVICE_ACCOUNT_EMAIL}:generateAccessToken",
  "service_account_impersonation": {
    "token_lifetime_seconds": 3600
  }
}

Your Spacelift run needs to have access to this file, so you can check it in (there's nothing secret here), mount it on a stack or mount it in a context that is then attached to the stack.

Note that you will also need to tell the provider how to find this configuration file. You can do this by creating a GOOGLE_APPLICATION_CREDENTIALS environment variable, and setting it to the path to your credentials file.

Here is an example of us using a Spacelift context to mount the file and configure the provider to be attached to an arbitrary number of stacks:

GCP Spacelift settings

For more information about configuring the Terraform provider, please see the Google Cloud Terraform provider docs.

Tip

You get a PERMISSION_DENIED for the iam.serviceAccounts.getAccessToken permission if you have specified some kind of permission about what principals are allowed to use your service account in the "Connected Service Accounts" section, and that condition isn't fulfilled (e.g. You specify that only stacks from a certain space are allowed to use your service account, and you try to trigger a run on a stack in a different space).