Automated infrastructure on Google Cloud Platform requires an identity that is not tied to a human user. Terraform operations against production GCP workloads must be performed through a dedicated Google Cloud service account with carefully scoped IAM role bindings. The terraform-google-service-accounts module provides a declarative Terraform infrastructure-as-code solution for creating and managing GCP service accounts with associated IAM role bindings. The module automates the provisioning of service accounts, assignment of IAM roles at multiple scopes, optional key generation, and includes specialized submodules for simplified single-account creation and secure key distribution.
Running Terraform against Google Cloud in production means you need a service account. Personal Google accounts work fine for experimentation, but automated deployments need a dedicated identity with specific permissions. A GCP service account is a special type of Google account that belongs to your project rather than to an individual user. It has an email address like [email protected], a key pair for authentication, and IAM role bindings that determine its permissions. Service accounts are the standard way to authenticate automated workloads including Terraform, CI/CD pipelines, and applications running on GCP.
The terraform-google-service-accounts module is maintained as part of the Cloud Foundation Toolkit and follows Google Cloud best practices for infrastructure management. The repository implements a modular architecture with three distinct entry points, each serving different service account management workflows. The root module uses Terraform's for_each meta-argument to manage multiple service accounts and their IAM bindings. The module addresses the operational overhead of managing GCP service accounts by providing a declarative interface for provisioning.
Module Architecture and Entry Points
The terraform-google-service-accounts module allows easy creation of one or more service accounts, and granting them basic roles. The resources, services, activations, and deletions that this module will create or trigger are:
- one or more service accounts
- optional project-level IAM role bindings for each service account
- one optional billing IAM role binding per service account, at the organization or billing account level
- two optional organization-level IAM bindings per service account, to enable the service accounts to create and manage Shared VPC networks
- one optional service account key per service account
This module is meant for use with Terraform 0.13+ and tested using Terraform 1.0+. If you find incompatibilities using Terraform >=0.13, please open an issue. If you haven't upgraded and need a Terraform 0.12.x-compatible version of this module, the last released version intended for Terraform 0.12.x is v3.0.1.
Basic usage of this module is as follows:
hcl
module "service_accounts" {
source = "terraform-google-modules/service-accounts/google"
version = "~> 4.0"
project_id = "<PROJECT ID>"
prefix = "test-sa"
names = ["first", "second"]
project_roles = [
"project-foo=>roles/viewer",
"project-spam=>roles/storage.objectViewer",
]
}
Functional examples are included in the examples directory.
The module provides a table of inputs where Name, Description, Type, Default, Required are documented.
```
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| billingaccountid | If assigning billing role, specificy a billing account (default is to assign at the organizational level) |
```
The module automates provisioning of service accounts, assignment of IAM roles at multiple scopes project, organization, billing, optional key generation, and includes specialized submodules for simplified single-account creation and secure key distribution. For detailed information on specific module components, see Module Structure. For version compatibility requirements, see Version Requirements.
Service Account Creation with gcloud CLI
Creating a service account through the CLI establishes the identity that Terraform will later reference in provider configuration and IAM bindings.
Set your project before creation:
bash
export PROJECT_ID="my-project-123"
gcloud config set project $PROJECT_ID
Create the service account with display name and description:
bash
gcloud iam service-accounts create terraform \
--display-name="Terraform Service Account" \
--description="Used by Terraform to manage GCP infrastructure"
Verify it was created:
bash
gcloud iam service-accounts list
The service account email is formed as terraform@PROJECT_ID.iam.gserviceaccount.com. That email address is the identifier used in IAM policy bindings, provider impersonation, and role assignments.
Impact of creation: The service account exists as a project-owned principal. Without subsequent role bindings, it has no permissions. The creation step is decoupled from authorization, which allows least-privilege design where roles are assigned explicitly after creation.
Contextual layer: The module wraps this CLI operation into declarative resources. The root module uses Terraform's for_each meta-argument to manage multiple service accounts and their IAM bindings, allowing a single module call to produce first and second service accounts with prefix test-sa.
IAM Role Assignment Patterns
Grant the service account the permissions it needs through IAM policy bindings.
For a general-purpose Terraform service account, you might use the Editor role during initial setup and tighten it later:
bash
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:terraform@${PROJECT_ID}.iam.gserviceaccount.com" \
--role="roles/editor"
Broad access for initial setup is not recommended for production. The module supports project-level IAM role bindings for each service account via project_roles. It also supports one optional billing IAM role binding per service account at the organization or billing account level, and two optional organization-level IAM bindings per service account to enable the service accounts to create and manage Shared VPC networks.
Example role assignment for Cloud SQL administration:
bash
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:terraform@${PROJECT_ID}.iam.gserviceaccount.com" \
--role="roles/cloudsql.admin"
The module allows assignment of IAM roles at multiple scopes project, organization, billing. The declarative interface lets you specify project-foo=>roles/viewer and project-spam=>roles/storage.objectViewer in the same module invocation.
Authentication Methods for Terraform Provider
There are several ways to authenticate Terraform with the service account.
Method 1 - Service Account Key File
Generate a JSON key and point Terraform at it:
bash
gcloud iam service-accounts keys create terraform-key.json \
--iam-account="terraform@${PROJECT_ID}.iam.gserviceaccount.com"
The file contains private key material - handle it securely:
bash
chmod 600 terraform-key.json
Provider configuration with explicit credentials:
hcl
provider "google" {
project = var.project_id
region = "us-central1"
credentials = file("terraform-key.json")
}
Or better, use the GOOGLE_CREDENTIALS environment variable:
bash
export GOOGLE_CREDENTIALS=$(cat terraform-key.json)
export GOOGLE_APPLICATION_CREDENTIALS="/path/to/terraform-key.json"
Provider configuration without credentials in code:
hcl
provider "google" {
project = var.project_id
region = "us-central1"
}
The provider reads from GOOGLECREDENTIALS or GOOGLEAPPLICATION_CREDENTIALS automatically.
Important security note: Service account keys are long-lived credentials. Key rotation and revocation become operational burdens if keys are distributed widely. The module includes optional service account key per service account creation, but secure key distribution submodules are provided for safer patterns.
Method 2 - Service Account Impersonation
Authenticate using service account impersonation. You can use service account impersonation to set up a local ADC file. Terraform uses those credentials automatically.
Make sure you must have the Service Account Token Creator roles/iam.serviceAccountTokenCreator IAM role on the service account you are impersonating. For more information, see Required roles.
Use service account impersonation to create a local ADC file by running:
bash
gcloud auth application-default login --impersonate-service-account SERVICE_ACCT_EMAIL
If you want to allow users to use a shared primary authentication source and a variable service account per environment, set the impersonateserviceaccount field in your Terraform configuration file:
hcl
provider "google" {
impersonate_service_account = "SERVICE_ACCT_EMAIL"
}
When running Terraform on a Google Cloud cloud-based development environment such as Cloud Shell, the tool uses the credentials you provided when you signed in for authentication.
When using Terraform with Google Cloud services such as Compute Engine, App Engine, and Cloud Run functions, you can attach a user-managed service account to resources. Generally, attaching a service account is supported when that service's resources can run or include application code.
Provider Configuration and ADC
After you sign in, your credentials are stored in the local credential file used by ADC. Application Default Credentials provide a default chain for authentication.
Service account impersonation eliminates the need to distribute long-lived JSON keys. The impersonated account must be granted roles/iam.serviceAccountTokenCreator on the target service account.
Impact: Teams can share a primary authentication source and select per-environment service accounts via configuration, reducing key exposure.
HCP Terraform and Environment Variables
When using the Terraform CLI locally, you can use several methods to authenticate with Google Cloud. However, when you use HCP Terraform or Terraform Enterprise with the remote backend, you must configure the credentials as an environment variable in the target workspaces.
Procedure:
- Navigate to the Terraform Enterprise UI and select the appropriate organization.
- Select the workspace where you need to add the credentials.
- Select Variables from the workspace menu.
- In the Environment Variables section, click Add variable.
- Set the Key to GOOGLE_CREDENTIALS.
- Open your service account key file, copy the entire JSON content, and paste it into the Value field.
- Check the Sensitive box to protect the credential from being displayed in the UI or logs.
- Click Save variable.
- Queue a new plan in the workspace to verify that Terraform is using the new credentials to authenticate with Google Cloud.
For more details on configuring the Google Provider, please see the Google Provider Reference: Credentials documentation.
The sensitive variable approach keeps key material out of version control and restricts visibility in the UI.
Infrastructure Manager Service Agent Configuration
For deployments using Infra Manager, the service agent email is formed as service-INFRAMANAGER[email protected].
Grant the Service Account Token Creator roles/iam.serviceAccountTokenCreator role to the Cloud Build service agent in the project where you're creating deployments. To allow Infra Manager to execute Terraform using Cloud Build, the Cloud Build service agent in the project containing the service account needs additional permissions as part of the cross-project set up:
bash
gcloud projects add-iam-policy-binding SERVICE_ACCOUNT_PROJECT_ID \
--member="serviceAccount:service-INFRA_MANAGER_PROJECT_NUMBER@gcp-sa-cloudbuild.iam.gserviceaccount.com" \
--role="roles/iam.serviceAccountTokenCreator"
This forms the email ID of the service agent. The cross-project binding allows Infra Manager to impersonate the service account for Terraform execution.
What's next includes learning about IAM, learning more about Terraform with Google Cloud, deploying infrastructure using Infra Manager, updating a deployment, and viewing the state of a deployment.
Module Inputs and Output Behavior
The module supports:
- project_id for scoping service account creation
- prefix for naming convention
- names for multiple service accounts
- project_roles for project-level IAM bindings
- billingaccountid for billing role assignment
- organization-level bindings for Shared VPC management
- optional service account key generation
The root module uses Terraform's for_each meta-argument to manage multiple service accounts and their IAM bindings. This enables bulk creation with consistent naming and role application.
The module is maintained as part of the Cloud Foundation Toolkit and follows Google Cloud best practices for infrastructure management.
Conclusion
Google service account management in Terraform spans identity creation, IAM scoping, and provider authentication. The terraform-google-service-accounts module centralizes service account provisioning with declarative IAM bindings at project, organization, and billing scopes while supporting optional key generation and secure distribution patterns. CLI creation via gcloud iam service-accounts create establishes the principal, and gcloud projects add-iam-policy-binding applies roles such as roles/editor for initial setup or roles/cloudsql.admin for targeted access. Authentication evolves from long-lived JSON keys loaded via credentials = file or GOOGLECREDENTIALS environment variables toward short-lived impersonation using roles/iam.serviceAccountTokenCreator and provider impersonateserviceaccount settings. HCP Terraform and Terraform Enterprise require GOOGLECREDENTIALS as a sensitive workspace variable rather than committed files. Infra Manager deployments introduce service-INFRAMANAGERPROJECT[email protected] agents and cross-project Service Account Token Creator grants to Cloud Build service agents. The module's foreach driven architecture, Cloud Foundation Toolkit maintenance, and support for Terraform 0.13+ and 1.0+ make it the operational backbone for least-privilege, auditable service account lifecycles in GCP.
Sources
- terraform-google-service-accounts
- How to configure GCP provider with service account
- Authenticate Terraform with Google Cloud
- Add a Google Cloud Service Account as a Terraform Enterprise Workspace Environment Variable
- Configure service account for Infrastructure Manager
- terraform-google-service-accounts