Full Report
IntroductionTerraform 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 scenarioConsider 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 architectureAt 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 setupCreate one TFC project per business unitCreate workspaces under TFC projects, one for each environmentConfigure TFC workspace with the right pool id for deployment pipelines to runGoogle Cloud setupIn Google Cloud Workload identity pools and service accounts are set up for TFC workspaces use:1. Setup Workload identity poolsa. Create one Workload identity pool for each environment. b. Create Terraform Cloud as Workload identity pool provider. 2. Setup service accounts for managing resourcesa. Create a service account for Terraform (TF SA) workspace impersonationb. Grant TF SAs the minimum roles needed to run IaC in application projects, following the principle of least privilege3. 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 troubleshootingUse 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 controlTo access TFC workspaces, ensure appropriate RBAC controls and approval processes are in place with naming conventions of -, 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 configurationHere 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 managementA 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. The following IaC code illustrates the creation of one Identity Pool with a single TFC Provider in that pool. code_block )])]> 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 )])]> Deny unauthorized access to TFC WorkspacesUnauthorized 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 managementCreate 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 )])]> 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: Get started todayRefer to the following detailed documentation on concepts and best practices for using Workload Identity Federation. Workload identity federation | IAM Documentation | Google CloudConfigure workload identity federation with deployment pipelines | IAM Documentation | Google CloudBest practices for using workload identity federation | IAM Documentation | Google CloudBest practices for using service accounts in pipelines | IAM Documentation | Google Cloud 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
Analysis Summary
# Best Practices: Terraform Cloud & Google Cloud Workload Identity Federation
## Overview
These practices address the security risks associated with managing long-lived static service account keys in CI/CD pipelines. By using Workload Identity Federation (WIF), organizations can establish a keyless authentication mechanism between Terraform Cloud (TFC) and Google Cloud, ensuring that IaC deployments are scoped strictly by business unit and environment.
## Key Recommendations
### Immediate Actions
1. **Eliminate Static Keys:** Phase out the use of JSON service account keys for TFC workspaces; replace them with Workload Identity Federation.
2. **Map TFC Projects to Business Units:** Create one TFC Project for each department (e.g., Banking, Insurance) to isolate administrative boundaries.
3. **Implement Naming Conventions:** Adopt a `<business-unit>-<environment>` naming convention for TFC workspaces to ensure clear mapping to cloud resources.
### Short-term Improvements (1-3 months)
1. **Environment Isolation:** Create dedicated Workload Identity Pools for each environment (e.g., one for `prod`, one for `dev`).
2. **Attribute Mapping:** Configure TFC OIDC assertions to map Google Cloud attributes, allowing for granular access control based on TFC metadata.
3. **Strict Attribute Conditions:** Apply CEL (Common Expression Language) conditions in the WIF provider to restrict access only to your specific TFC Organization and specific Workspace IDs.
### Long-term Strategy (3+ months)
1. **One SA per Workspace:** Transition to a 1:1 mapping where each TFC workspace has its own unique Google Cloud Service Account (TF SA).
2. **Isolated SA Projects:** Move TF SAs into dedicated, locked-down Google Cloud projects separate from application projects.
3. **Automated Least Privilege:** Conduct regular IAM reviews to ensure TF SAs only hold the minimum roles required for the specific resources managed by their workspace.
## Implementation Guidance
### For Small Organizations
- Use a single Workload Identity Pool but use strictly defined attribute conditions to separate development and production workspaces.
- Centralize all TF SAs in one "Security-Shared-Services" project.
### For Medium Organizations
- Implement the "one pool per environment" strategy.
- Enforce TFC Project-level RBAC to ensure team members only access their respective business unit's workspaces.
### For Large Enterprises
- Deploy a "Hub-and-Spoke" IAM model where Workload Identity Pools are managed by a central security team.
- Use TFC workspace IDs as the primary constraint in IAM policy bindings to prevent "sideways" movement between business units.
- Enable organizational-level audit logging for all STS (Security Token Service) exchanges.
## Configuration Examples
### WIF Provider Attribute Condition
To ensure only the "Banking" production workspace in your TFC organization can authenticate:
hcl
# Conceptual CEL Condition
assertion.repository == "my-org/my-repo" &&
attribute.terraform_organization_id == "org-xxxxxxxx" &&
attribute.terraform_workspace_id == "ws-xxxxxxxx"
### IAM Impersonation Binding
Granting a specific TFC workspace the right to impersonate its dedicated service account:
bash
gcloud iam service-accounts add-iam-policy-binding [SA_NAME]@[PROJECT].iam.gserviceaccount.com \
--role="roles/iam.workloadIdentityUser" \
--member="principalSet://iam.googleapis.com/projects/[PROJECT_NUMBER]/locations/global/workloadIdentityPools/[POOL_ID]/attribute.terraform_workspace_id/[WORKSPACE_ID]"
## Compliance Alignment
- **NIST SP 800-204:** Aligns with recommendations for microservice and CI/CD security by using short-lived tokens.
- **CIS Google Cloud Benchmark:** Supports identity and access management controls by reducing the footprint of service account keys.
- **Least Privilege:** Directly addresses IAM standards by scoping TFC access to specific environments.
## Common Pitfalls to Avoid
- **Shared Pools for Dev/Prod:** Avoid using the same WIF pool for different environments; a misconfiguration in the provider condition could grant dev pipelines access to production.
- **Over-Scoping Service Accounts:** Do not use a single "Global Terraform SA." If compromised, the entire infrastructure hierarchy is at risk.
- **Ignoring Data Logs:** Failure to enable Data Access Logs for IAM and STS makes it impossible to perform forensics if an identity pool is misused.
## Resources
- [Google Cloud Documentation: Workload Identity Federation](https://cloud.google.com/iam/docs/workload-identity-federation)
- [Terraform Cloud: OIDC Configuration Guide](https://developer.hashicorp.com/terraform/cloud-docs/workspaces/dynamic-provider-credentials/gcp-configuration)
- [Best Practices for Service Accounts in Pipelines](https://cloud.google.com/iam/docs/best-practices-for-using-service-accounts-in-deployment-pipelines)