Access Google Cloud from HCP Terraform with workload identity

Securely access Google Cloud from HCP Terraform using workload identity federation, eliminating the need to store service account keys.

Storing long-lived service account keys in HCP Terraform poses a significant security risk. If compromised, these account keys could give an attacker access to your Google Cloud environment. Not only is leaking the key a risk, but many organizations have a policy to block creation of such keys. Fortunately, in many cases, you can authenticate with more secure alternatives to service account keys. One such alternative is workload identity federation, which uses identity and access management (IAM) to grant external identities (such as HCP Terraform) the ability to impersonate service accounts.

HCP Terraform’s dynamic provider credentials allow Terraform runs to impersonate a service account through native OpenID Connect (OIDC) integration and obtain a short-lived OAuth 2.0 access token for each run. This short-lived access token lets you call any Google Cloud APIs that the service account has access to at runtime, making your HCP Terraform runs much more secure.

Using HashiCorp Terraform, you have the ability to create a Google Cloud workload identity pool and provider, which HCP Terraform uses to request a federated token. This token is then passed to the Google Terraform provider, which impersonates a service account to obtain temporary credentials to plan or apply Terraform.

diagram illustrates the authentication sequence for accessing Google Cloud using dynamic provider credentials and workload identity federation.

The above diagram illustrates the authentication sequence for accessing Google Cloud using dynamic provider credentials and workload identity federation.

Below is an example to configure workload identity federation in Google Cloud. This approach assumes you have a pre-existing method to authenticate with your Google Cloud project. If you don’t, you can create the temporary service account outlined below.

»Set up the workload identity pool and provider

To get started, create a temporary service account along with a JSON key. Safely store this key within your HCP Terraform workspace variables to grant temporary access to your Google Cloud project. This less-secure access method will only be used for initial setup. Remember to delete the temporary service account key once you’ve transitioned to workload identity federation using the steps below.

To set up the HCP Terraform pool and provider for workload identity federation, update the local google_project_id and organization_name values in the locals{} block:

locals {  google_project_id = "example-project"  organization_name = "example-org"} # create a workload identity pool for HCP Terraformresource "google_iam_workload_identity_pool" "hcp_tf" {  project                   = local.google_project_id  workload_identity_pool_id = "hcp-tf-pool"  display_name              = "HCP Terraform Pool"  description               = "Used to authenticate to Google Cloud"} # create a workload identity pool provider for HCP Terraformresource "google_iam_workload_identity_pool_provider" "hcp_tf" {  project                            = local.google_project_id  workload_identity_pool_id          = google_iam_workload_identity_pool.hcp_tf.workload_identity_pool_id  workload_identity_pool_provider_id = "hcp-tf-provider"  display_name                       = "HCP Terraform Provider"  description                        = "Used to authenticate to Google Cloud"  attribute_condition                = "assertion.terraform_organization_name==\"${local.organization_name}\""  attribute_mapping = {    "google.subject"                     = "assertion.sub"    "attribute.terraform_workspace_id"   = "assertion.terraform_workspace_id"    "attribute.terraform_full_workspace" = "assertion.terraform_full_workspace"  }  oidc {    issuer_uri = "https://app.terraform.io"  }}

Once the HCP Terraform pool and provider are created, create a service account that HCP Terraform will impersonate at runtime:

# example service account that HCP Terraform will impersonateresource "google_service_account" "example" {  account_id   = "example"  display_name = "Service Account for HCP Terraform"  project      = local.google_project_id} # IAM verifies the HCP Terraform Workspace ID before authorizing access to impersonate the 'example' service accountresource "google_service_account_iam_member" "example_workload_identity_user" {  service_account_id = google_service_account.example.name  role               = "roles/iam.workloadIdentityUser"  member             = "principalSet://iam.googleapis.com/${google_iam_workload_identity_pool.hcp_tf.name}/attribute.terraform_workspace_id/ws-ZZZZZZZZZZZZZZZ"} # grant 'example' service account permissions to create a bucketresource "google_project_iam_member" "example_storage_admin" {  member  = "serviceAccount:${google_service_account.example.email}"  role    = "roles/storage.admin"  project = local.google_project_id}

»Delegating access to another workspace

For improved security and scalability, consider using a separate HCP Terraform workspace to set up and configure your workload identity federation. From this workspace, using HCP Terraform variable sets, you can share the service account and identity federation configuration, allowing you to securely delegate access to Google Cloud from one workspace to another.

Below is an example configuration that creates a variable set and shares it with another HCP Terraform workspace.

# create a variable set to store the workload identity federation config for the 'example' service accountresource "tfe_variable_set" "example" {  name         = google_service_account.example.account_id  description  = "Workload identity federation configuration for ${google_service_account.example.name}"  organization = local.organization_name} # share the variable set with another HCP Terraform Workspaceresource "tfe_workspace_variable_set" "example" {  variable_set_id = tfe_variable_set.example.id  workspace_id    = "ws-XXXXXXXXXXXXXXX"}

Create the required environment variables below and associate them with the variable set. HCP Terraform uses these to obtain the short-lived OAuth 2.0 access token, which it uses to impersonate a service account at runtime that can call any Google Cloud APIs that the service account has access to:

resource "tfe_variable" "example_provider_auth" {  key             = "TFC_GCP_PROVIDER_AUTH"  value           = "true"  category        = "env"  variable_set_id = tfe_variable_set.example.id} resource "tfe_variable" "example_service_account_email" {  sensitive       = true  key             = "TFC_GCP_RUN_SERVICE_ACCOUNT_EMAIL"  value           = google_service_account.example.email  category        = "env"  variable_set_id = tfe_variable_set.example.id} resource "tfe_variable" "example_provider_name" {  sensitive       = true  key             = "TFC_GCP_WORKLOAD_PROVIDER_NAME"  value           = google_iam_workload_identity_pool_provider.hcp_tf.name  category        = "env"  variable_set_id = tfe_variable_set.example.id}

»Using workload identity federation

When using workload identity federation, you don't need to define anything within the provider itself. By sharing the variable set — which includes the service account and identity federation configuration — with another HCP Terraform workspace, you automatically gain access to Google Cloud within the shared workspace.

HCP Terraform does this by impersonating the service account at runtime, using the environment variables from the shared variable set. This approach allows you to securely scale access management within HCP Terraform by delegating access from one workspace to another while precisely restricting Google Cloud access to only what the service account needs.

Using the service account created earlier, which has been assigned only the cloud storage admin role, you can immediately create a bucket within the shared workspace without having to configure anything else:

resource "google_storage_bucket" "example" {  name     = "example"  location = "EU"  project  = “example-project”}

»Learn more about workload identity federation

If you want to learn more about keyless Google Cloud access from HCP Terraform, check out the dynamic provider credentials and workload identity federation documentation. You can find all the code used in this post on GitHub in the keyless-auth-gcp-hcp-terraform repository.

Sign up for the latest HashiCorp news

By submitting this form, you acknowledge and agree that HashiCorp will process your personal information in accordance with the Privacy Policy.