Wednesday, May 29, 2024
No menu items!
HomeCloud ComputingManage infrastructure with Workload Identity Federation and Terraform Cloud

Manage infrastructure with Workload Identity Federation and Terraform Cloud

Introduction

Terraform Cloud (TFC) can help manage infrastructure as code (IaC) development for large enterprises. As the number of Google Cloud projects grows, managing access controls for Terraform Cloud projects and workspaces can become complex. Don’t worry, we have a solution that is designed to be more secure than using Google Cloud service account keys, and also scales well for hundreds or even thousands of Google Cloud projects, TFC workspaces, and TFC projects using Workload Identity Federation.

An enterprise scenario

Consider a fictitious financial services firm example.com that offers banking, lending, insurance and brokerage service to customers.  Their Google Cloud resource hierarchy is shown below: Business Units > Environment Folders > Application Projects.

As IaC codebases grow to manage the infrastructure for the entire organization, it can be difficult to control access for a large number of deployment pipelines. The following solution guidance addresses three key challenges:

How do I ensure dev IaC code only creates or deletes resources only in the dev environment, not production?

How do I prevent Banking IaC code from accidentally creating or deleting Brokerage business unit resources?

How many TFC projects, workspaces, Google Cloud Workload identity pools and service accounts for Terraform are optimal for my enterprise use cases?

Solution architecture

At a high level, Terraform Cloud workspaces integrate with Workload Identity Federation to authenticate with Google Cloud, then impersonate Google Cloud service accounts to manage resources in application projects more securely. TFC workspaces are granted permission to impersonate the right service account.

The following diagram shows the components and how they interact.

This solution requires the following setup in Terraform Cloud and Google Cloud. 

Terraform Cloud setup

Create one TFC project per business unit

Create workspaces under TFC projects, one for each environment

Configure TFC workspace with the right pool id for deployment pipelines to run

Google Cloud setup

In Google Cloud Workload identity pools and service accounts are set up for TFC workspaces use:

1. Setup Workload identity pools

a. Create one Workload identity pool for each environment. 

b. Create Terraform Cloud as Workload identity pool provider. 

2. Setup service accounts for managing resources

a. Create a service account for Terraform (TF SA) workspace impersonation

b. Grant TF SAs the minimum roles needed to run IaC in application projects, following the principle of least privilege

3. Grant TF SA impersonation permission to only one TFC workspace. 

3. Enable data access logs for IAM and STS (Security Token Service) for auditability and troubleshooting

Use Workload identity pool to authenticate with Google Cloud and impersonate a service account to manage Google Cloud resources. For more information on keyless authentication, you can review our blogs on enabling keyless authentication from GitHub Actions and configuring Workload Identity Federation for GitHub actions and Terraform Cloud.

Putting all the pieces together 

Here is an example of banking-prod IaC code managing resources in  prj-banking-1-prod project.

A successful run of a plan result would look like this:

Projects and Workspaces in Terraform Cloud 

IaC code in TFC is organized into Projects and Workspaces for easier management. We create four projects In our case — banking, insurance, brokerage and lending — one for each business unit.

Terraform workspace access control

To access TFC workspaces, ensure appropriate RBAC controls and approval processes are in place with naming conventions of <business unit>-<environment>, where the environment determines the Workload identity pool it gets access to. For example, banking-prod gets access to the terraform-pool-prod in Google Cloud.

Terraform workspace configuration

Here is an example configuration that connects to the Production pool provider for banking-prod workspace. This step is executed after Google Cloud setup is completed.

Workload identity pool management

A Workload identity pool is an entity in Google Cloud that allows management of external identities. Each environment should have its own Workload identity pool. Set strict IAM policies for pool projects to ensure only authorized users have access.

Following pools are created for our example.com organization use case.

FollowingIaC code illustrates the creation of one Identity Pool with a single TFC Provider in that pool.

code_block[StructValue([(u’code’, u’resource “google_iam_workload_identity_pool” “tfc_identity_pool” {rn workload_identity_pool_id t= “terraform-pool-prod””rn display_name tt= “terraform-pool-prod”rn description tt= “Production Pool”rn disabled tt= falsern} rnrnresource “google_iam_workload_identity_pool_provider” “pool-provider” {rn workload_identity_pool_id t= google_iam_workload_identity_pool.tfc_identity_pool.workload_identity_pool_idrn workload_identity_pool_provider_id t= “terraform-cloud-oidc-prod”rn display_name tt= “terraform-cloud-oidc-prod”rn description tt= “Terraform Cloud OIDC Provider”rn disabled ttt= falsernrn attribute_mapping = {rn “attribute.tfc_organization_id” t= “assertion.terraform_organization_id”rn “attribute.tfc_project_id” tt= “assertion.terraform_project_id”rn “attribute.tfc_project_name” t= “assertion.terraform_project_name”rn “google.subject” tt= “assertion.terraform_workspace_id”rn “attribute.tfc_workspace_name” t= “assertion.terraform_workspace_name”rn “attribute.tfc_workspace_env” t= “assertion.terraform_workspace_name.split(‘-‘)[assertion.terraform_workspace_name.split(‘-‘).size() -1]”rn }rnrn oidc {rn issuer_uri = “https://app.terraform.io”rn }rnrn attribute_condition = “attribute.tfc_organization_id == ‘org-abcd123456’ && attribute.tfc_workspace_env.startsWith ( ‘prod’)'”rn}’), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3e43c83f4690>)])]

The Pool provider is created with TFC OIDC assertions mapped to Google Cloud attributes. Refer to https://app.terraform.io/.well-known/openid-configuration for the claims supported by TFC ID Token. 

The diagram below shows Provider configuration created by IaC code.

Workload identity pool security 

Use attribute conditions to restrict the use of example.com Workload identity pools to the example.com TFC organization and for one specific environment by configuring the Terraform identity pool provider resource.

code_block[StructValue([(u’code’, u’# Code to restrict the pool for your TFC organization and one environmentrnattribute_condition = “attribute.tfc_organization_id == ‘org-abcd123456’ && attribute.tfc_workspace_env.startsWith ( ‘prod’)'”‘), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3e43c831e650>)])]

Deny unauthorized access to TFC Workspaces

Unauthorized access to a workload identity pool by a workspace is denied.  
Dev TFC Workspace configuration with production pool.

Error received when TF plan is run in TFC.

Unauthorized access to a service account by a workspace is denied. 
Dev TFC Workspace configuration with a production service account.

Error received when TF plan is run:

Service Account management

Create Google Cloud service accounts for use by Terraform Cloud workspaces to manage Google Cloud resources in application projects. For our enterprise use case we create a separate service account for each TFC workspace. 

Create these service accounts in separate Google Cloud projects with proper IAM applied to those projects.

An example that grants impersonation permission only to TFC workspace banking-dev.

code_block[StructValue([(u’code’, u’resource “google_service_account” “sa_tf_banking_dev” {rnaccount_id = “sa-tf-banking-dev”rndisplay_name = “Banking Dev Service Account”rn}rnresource “google_service_account_iam_binding” “sa_tf_banking_dev_iam” {rnservice_account_id = google_service_account.sa_tf_banking_dev.namernrole = “roles/iam.workloadIdentityUser”rnmembers = [rn”principal://iam.googleapis.com/projects/01234567890/locations/global/workloadIdentityPools/terraform-pool-dev/subject/ws-xxxxxxxxxxxxx”,rn]rn}’), (u’language’, u”), (u’caption’, <wagtail.wagtailcore.rich_text.RichText object at 0x3e43c83c5e10>)])]

Grant minimum roles to service accounts based on app project requirements. For example, grant sa-tf-banking-prod service account  roles/storage.admin, roles/compute.admin to manage Compute and Cloud Storage services in  prj-banking-1-prod project.

IAM in prj-banking-1-prod for Service account sa-tf-banking-prod will look like this: 

Auditability 

Enable data access logs for IAM and STS in pool projects to track who is accessing resources in those projects, what resources they are accessing, and identify any unauthorized access. 

Example IAM and STS log entries:

Related Article

Enabling keyless authentication from GitHub Actions

Authenticate from GitHub Actions to create and manage Google Cloud resources using Workload Identity Federation.

Read Article

Cloud BlogRead More

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments