# How to Safely Link Terraform Cloud and Google Cloud Platform via Workload Identity Federation

Terraform Cloud is a great service for managing Terraform configurations and applying them to provision infrastructure across different cloud providers, including Google Cloud Platform (GCP). However, securely authenticating Terraform Cloud to GCP can be a challenge. Workload Identity Federation is a new feature in GCP that allows you to safely authenticate access to GCP resources without using long-lived credentials like service account keys. This post will walk through how to set up Workload Identity Federation between Terraform Cloud and GCP.

**If you prefer French, check PoC video here**

<iframe width="auto" height="auto" src="https://www.youtube.com/embed/ebV8VeNdscU?si=uPu4sJYCobh9qjQE"></iframe>

**Prerequisites:**

* A GCP project
    
* A Terraform Cloud account and workspace
    

**Step 1:** Enable Required GCP APIs First, you need to enable the required APIs in your GCP project:

```yaml
gcloud services enable iamcredentials.googleapis.com
gcloud services enable cloudresourcemanager.googleapis.com
```

**Step 2:** Create a Google Cloud Workload Identity Pool: It's a collection of workloads that share the same identity and access policy. Create one with:

```yaml
gcloud iam workload-identity-pools create tfc-wif-pool \
  --project=<PROJECT_ID> \
  --location=global
```

**Step 3:** Create a Google Cloud Workload Identity Pool Provider: This links your external identity provider (in this case Terraform Cloud) to the workload identity pool:

```yaml
gcloud iam workload-identity-pools providers create-oidc tfc-wif-provider \
  --project=<PROJECT_ID> \
  --location=global \
  --workload-identity-pool=tfc-wif-pool \
  --issuer-uri=https://app.terraform.io \
  --attribute-mapping="google.subject=assertion.terraform_workspace_id"
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1716717334229/2814699d-d72b-4035-8eb6-41e63fa6998e.png align="center")

**Step 4:** Create a Google Service Account for Terraform: This represents the identity that Terraform will use:

```yaml
gcloud iam service-accounts create tfc-wif-sa \
  --project=<PROJECT_ID>
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1716717417185/deea212c-27a2-429b-b941-68d4c67d7688.png align="center")

**Step 5:** Allow the Service Account to user the Workload Identity:

```yaml
gcloud projects add-iam-policy-binding <PROJECT_ID> \
    --member serviceAccount:tfc-wif-sa@<PROJECT_ID>.iam.gserviceaccount.com \
    --role roles/iam.workloadIdentityUser
```

**Step 6:** Add Permissions to the Service Account and any required permissions to the service account, such as the ability to create and manage compute Engine resources:

```yaml
gcloud projects add-iam-policy-binding <PROJECT_ID> \
  --member="serviceAccount:tfc-wif-sa@<PROJECT_ID>.iam.gserviceaccount.com" \
  --role="roles/compute.admin"
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1716717578432/ad6f03b1-8e73-4afa-8e96-4e47f552cd1f.png align="center")

**Step 7:** Configure Terraform Cloud In your Terraform Cloud workspace:

1. Go to "Variables" and create a new environment : change `PROJECT_NUMBER` and `PROJECT_ID`
    
    ```yaml
    TFC_GCP_PROJECT_NUMBER = <PROJECT_NUMBER> 
    TFC_GCP_PROVIDER_AUTH = true	
    TFC_GCP_RUN_SERVICE_ACCOUNT_EMAIL = tfc-wif-sa@<PROJECT_ID>.iam.gserviceaccount.com
    TFC_GCP_WORKLOAD_POOL_ID = tfc-wif-pool
    TFC_GCP_WORKLOAD_PROVIDER_ID = tfc-wif-provider
    ```
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1716717634162/9fa76915-8724-4dee-8b8c-4f985148acf4.png align="center")
    
2. **Update**[Workload Identity Federation](https://console.cloud.google.com/iam-admin/workload-identity-pools) to add service **tfc-wif-sa@&lt;PROJECT\_ID&gt;.**[**iam.gserviceaccount.com**](http://iam.gserviceaccount.com)
    
    Click on **tfc-wif-pool** Display Name
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1716717874949/1d2f806a-3aa6-4fe7-81d2-8d1d89233570.png align="center")
    
3. And Click **Grant Access**
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1716717922397/654b1581-a898-458f-97ea-8cef9fb671ce.png align="center")
    
4. Add your SA email
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1715543130130/666dfd14-0cac-4041-bc42-3bf7c81e80a0.png align="center")
    
    Add your **Terraform cloud Workspace ID** like this:
    
    Copy your \*\*ws-\*\*xSSKSSSSSS
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1716718030273/e803b862-8ab8-45b6-b292-6d10d33f68e0.png align="center")
    
5. Update subject with the workspace ID `subject` and Click on "**SAVE**" in the popup page, click on **DISMISS**
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1716718080974/7c884182-bdee-4fdd-b265-5b745d96bb4c.png align="center")
    
6. Your provider **CONNECTED SERVICE ACCOUNTS** should look like this
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1716718133600/148cb6d0-5a64-4ac2-83d6-dadb53101290.png align="center")
    
7. create a terraform file `main.tf`, add the `google` provider block and resource to create `Compute Engine Instance`:
    

```yaml
terraform {
  cloud {
    organization = "change_me" # change this

    workspaces {
      name = "tfc-gcp-wif"
    }
  }
}

provider "google" {
  project = var.gcp_project_id
  region  = var.gcp_region
  zone    = var.gcp_zone
}

variable "gcp_project_id" {}

variable "gcp_region" {
  default = "us-east4"
}

variable "gcp_zone" {
  default = "us-east4-c"
}

resource "google_compute_instance" "test-instance" {
  name         = "test-instance"
  machine_type = "n1-standard-1"
  zone         = var.gcp_zone

  boot_disk {
    initialize_params {
      image = "centos-cloud/centos-7"
      size = 20
    }
  }

  network_interface {
    subnetwork = "default"
  }
}
```

Run **terraform init**, **terraform plan** and **terraform apply --auto-approve**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1716718315091/b970e37a-8592-493a-9e89-e52713275187.png align="center")

Congratulations, you did it !

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1716718223474/44c37980-2ac9-4c91-9700-420eabaf0879.png align="center")

That's it! Terraform Cloud can now securely provision resources in your GCP project using Workload Identity Federation without needing to manage long-lived service account keys. The service account permissions can be scoped as needed, and the external identity is validated by GCP for each run.

**Don't forget to destroy ressources !**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1716718274208/b24389bc-490a-4403-8c65-27666f59ccda.png align="center")
