Service Account Configuration for GCP Cloud Functions and Infrastructure Manager with Terraform

The reference material centers on defining and operating service accounts for Google Cloud Platform workloads using Terraform, with particular emphasis on Cloud Functions, role assignment patterns, Infrastructure Manager integration, and authentication pathways for Terraform execution. The material describes prerequisites for the hashicorp/google Terraform provider, the IAM permissions required for Terraform to create resources and manage policies, the resource definitions for service accounts and project-level IAM bindings, the use of for_each iteration over role lists, and the authentication methods for Terraform running locally or on Google Cloud. The material also covers Infrastructure Manager service account configuration, including the Service Account User and Infra Manager Agent roles, and the gcloud commands used to bind those roles.

The discussion spans service account creation for Cloud Functions, role assignment at project scope, authentication via Application Default Credentials, service account impersonation, and key-based authentication. Each element is presented with concrete resource examples and permission requirements drawn from the provided sources.

Service Account Definition for Cloud Functions with Terraform

The article from softwarephilosopher.com addresses a problem encountered during regular work: how to define a service account for Cloud Functions using Terraform. The solution is framed within a system based on Google Cloud Platform where some logic is built using Cloud Functions and Firebase, and Terraform is used for managing infrastructure.

The prerequisite stated is that the hashicorp/google Terraform provider has to be used. Also, the service account that Terraform uses needs to have appropriate permissions.

The permission set includes permissions to create resources that depends on what exactly is in the Terraform code. Specific permissions listed are:

resourcemanager.projects.getIamPolicy
resourcemanager.projects.setIamPolicy

for setting project-level policies

secretmanager.secrets.getIamPolicy
secretmanager.secrets.setIamPolicy

to use googlesecretmanagersecretiam_member

The material also notes potentially other permissions that end with *. *.setIamPolicy for resource-level policies.

The impact of these permissions is that without resourcemanager.projects.getIamPolicy and resourcemanager.projects.setIamPolicy, Terraform cannot read or write IAM policies at the project level. This blocks the ability to bind service accounts to roles for Cloud Functions deployment. Without secretmanager.secrets.getIamPolicy and secretmanager.secrets.setIamPolicy, Terraform cannot manage IAM on Secret Manager secrets, which prevents using googlesecretmanagersecretiam_member to grant access to the service account used by Cloud Functions.

The context of this requirement is a GCP system where Cloud Functions and Firebase components coexist. Service accounts for Cloud Functions often need access to Secret Manager for configuration secrets, and project-level IAM is needed for deployment permissions. Terraform acting as an infrastructure codification layer must therefore possess both project policy and secret policy permissions.

Terraform Resource Pattern for Service Account Creation and Role Assignment

The material describes a general pattern for creating a GCP service account and assigning it roles using Terraform. The guide explains defining the service account, specifying roles, and using the googleprojectiam_member resource to grant the roles.

The example code includes explanations and important considerations for managing service accounts and their permissions effectively.

To create a GCP service account with roles using Terraform, the steps generally follow:

Define the service account:

resource "google_service_account" "default" { account_id = "your-service-account-id" display_name = "Your Service Account Name" }

Replace "your-service-account-id" with a unique identifier for your service account. Replace "Your Service Account Name" with a descriptive name.

Define the roles:

You can either list roles directly or use variables for better organization:

variable "roles" { type = list(string) default = [ "roles/storage.objectViewer", "roles/pubsub.publisher", ] }

Assign roles using googleprojectiam_member:

resource "google_project_iam_member" "service_account_roles" { for_each = toset(var.roles) role = each.value member = "serviceAccount:${google_service_account.default.email}" }

This iterates through the roles list and grants each role to the service account.

Explanation:

googleserviceaccount: This resource creates the service account itself.

googleprojectiam_member: This resource binds roles to members at the project level.

for_each: This Terraform construct allows you to create multiple instances of a resource based on a collection.

The iteration through roles uses for_each to iterate through the list of roles and assign each one to the service account.

The code fragment shown in the reference:

"serviceAccount:${google_service_account.default.email}"

and

for_each = toset(var.roles)

Key considerations listed:

Permissions: Ensure your Terraform code has the necessary permissions to create service accounts and assign roles.

Resource Hierarchy: Adjust the resource type based on the desired level of role assignment project, organization, etc..

Service Account Deletion: Be aware of potential propagation delays when deleting and recreating service accounts with the same name.

Alternative Approaches: Explore using loops with count or modules for managing roles across multiple service accounts.

By combining the googleserviceaccount and googleprojectiammember resources with Terraform's built-in functionalities like foreach, you can efficiently manage service accounts and their roles in your GCP projects. This approach enables infrastructure as code, ensuring that service accounts have the correct permissions for applications and workflows. Following security best practices, such as the principle of least privilege, and consulting the Terraform Google provider documentation for the latest features and updates is recommended. Automating this process can minimize errors, improve consistency, and streamline cloud infrastructure management.

The impact of using foreach with toset(var.roles) is that each role becomes an independent googleprojectiammember instance. This allows Terraform to add or remove individual role bindings without recreating the entire set, which reduces drift and improves plan readability.

The context of this pattern is that service accounts for Cloud Functions require multiple fine-grained roles, for example storage.objectViewer and pubsub.publisher. Hardcoding each googleprojectiammember would be repetitive. The foreach pattern centralizes role management in a variable.

Authentication for Terraform Execution on Google Cloud

The material from docs.cloud.google.com/docs/terraform/authentication describes authentication methods for Terraform.

After you sign in, your credentials are stored in the local credential file used by ADC.

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 the following command:

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:

provider "google" { impersonate_service_account = "SERVICE_ACCT_EMAIL" }

Authenticate when running Terraform on Google Cloud:

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.

You can create a credential configuration file and set the GOOGLEAPPLICATIONCREDENTIALS environment variable to point to it. This approach is more secure than creating a service account key. For instructions on setting up Workload Identity Federation for ADC, see Workload Identity Federation with other clouds.

Authenticate using service account keys:

When running Terraform in a local development environment, on premises, or a different cloud provider, you can create a service account, grant it the IAM roles that your application requires, and create a key for the service account.

To create a service account key and make it available to ADC:

Create a service account with the roles your application needs, and a key for that service account, by following the instructions in Creating a service account key.

Authenticate to Cloud Storage backends:

Terraform lets you configure Cloud Storage as a backend to store Terraform state files. To authenticate to a Cloud Storage backend, use any of the methods described on this page. For information on configuration variables related to authentication for Cloud Storage backends, see the Terraform backends page for Cloud Storage.

The impact of service account impersonation is that developers do not need to download long-lived service account keys. The local ADC file contains short-lived access tokens obtained via impersonation, reducing key exposure risk.

The context is that Terraform code may be run locally by developers who should not have direct IAM permissions to create service accounts. Impersonation allows a central service account to hold permissions while developers authenticate via their own Google identity.

Infrastructure Manager Service Account Configuration

The material from docs.cloud.google.com/infrastructure-manager/docs/configure-service-account explains how to configure a service account so that you can deploy resources with Infrastructure Manager.

Infra Manager executes Terraform using the identity of this service account.

You do not need a service account to view information about Infra Manager deployments.

This page explains how to configure a service account so that you can deploy resources with Infrastructure Manager.

Before you begin:

Enable the Infra Manager service.
Create a service account or identify an existing service account to use with Infra Manager.

Grant access to the service account:

To use Infrastructure Manager to create, update, or delete a deployment, an individual user needs access to the service account.

Grant the user the Service Account User roles/iam.serviceAccountUser IAM role for the service account.

Grant permissions for Infra Manager:

To work with Infra Manager, the service account needs the Infra Manager Agent roles/config.agent role.

This grants permissions for Infra Manager to create, update, and delete resources:

gcloud projects add-iam-policy-binding INFRA_MANAGER_PROJECT_ID \ --member="serviceAccount:SERVICE_ACCOUNT_EMAIL" \ --role="roles/config.agent"

Replace:

INFRAMANAGERPROJECTID: The project ID of the project where you're creating deployments.
SERVICE
ACCOUNT_EMAIL: The email of the service account.

For details about how to grant permissions to service accounts, see Manage access to service accounts.

Grant read permission for the storage bucket:

You can use a storage bucket to store the Terraform configurations that are deployed by Infra Manager.

If you use a storage

The impact of granting roles/iam.serviceAccountUser to a user is that the user can impersonate the service account used by Infra Manager, which is required for deployment actions. Without this, users cannot trigger Terraform runs.

The context is that Infrastructure Manager acts as a managed Terraform execution plane. The service account it uses must have Infra Manager Agent role to allow the service to create, update, and delete resources in the target project. The gcloud command binds that role at the project level.

Permission and Resource Mapping Summary

The reference facts provide a set of permissions and resources that interact.

Table: Permissions Required for Terraform Service Account Operations

| Permission | Resource Context | Purpose |
| resourcemanager.projects.getIamPolicy | Project | Read project IAM policy |
| resourcemanager.projects.setIamPolicy | Project | Write project IAM policy |
| secretmanager.secrets.getIamPolicy | Secret Manager secret | Read secret IAM policy |
| secretmanager.secrets.setIamPolicy | Secret Manager secret | Write secret IAM policy |
| roles/iam.serviceAccountTokenCreator | Service Account | Required for service account impersonation |
| roles/iam.serviceAccountUser | Service Account | Grant user ability to use service account |
| roles/config.agent | Project | Infra Manager Agent for Infra Manager deployments |

Table: Terraform Resources and Roles

| Terraform Resource | Function | Related Role |
| googleserviceaccount | Creates service account | N/A |
| googleprojectiammember | Binds roles to service account at project level | Variable roles such as roles/storage.objectViewer, roles/pubsub.publisher |
| google
secretmanagersecretiammember | Binds roles to secret | Requires secretmanager.secrets.setIamPolicy |

The impact of mapping permissions to resources is that operators can audit the minimum privilege set required for a Terraform service account that provisions Cloud Functions, Secret Manager access, and Infrastructure Manager deployments.

The context is that the same service account may be used both as the identity for Terraform execution and as the runtime identity for Cloud Functions. Separating these concerns requires distinct service accounts and distinct IAM bindings.

Operational Considerations

Permissions: Ensure your Terraform code has the necessary permissions to create service accounts and assign roles.

Resource Hierarchy: Adjust the resource type based on the desired level of role assignment project, organization, etc..

Service Account Deletion: Be aware of potential propagation delays when deleting and recreating service accounts with the same name.

Alternative Approaches: Explore using loops with count or modules for managing roles across multiple service accounts.

The impact of propagation delays is that Terraform may attempt to recreate a service account with the same name immediately after deletion and encounter name collision errors. This can cause apply failures.

The context of resource hierarchy is that googleprojectiam_member assigns at project level, but similar resources exist for folder, organization, and resource levels. Choosing the correct level matches the principle of least privilege.

Conclusion

The reference material establishes a coherent workflow for defining service accounts for GCP Cloud Functions using Terraform, with explicit prerequisites for the hashicorp/google provider, required IAM permissions for project and Secret Manager policy management, and a reusable pattern for service account creation and role assignment using googleserviceaccount and googleprojectiammember with foreach iteration over a roles variable.

Authentication for Terraform execution is covered through Application Default Credentials, service account impersonation with roles/iam.serviceAccountTokenCreator, provider impersonateserviceaccount configuration, and key-based authentication for local or on-premises runs. Infrastructure Manager integration requires a dedicated service account with roles/config.agent granted via gcloud projects add-iam-policy-binding, and user access via roles/iam.serviceAccountUser.

The combined facts illustrate how Terraform can codify service account lifecycle and IAM bindings for Cloud Functions workloads, how to authenticate Terraform runs safely without long-lived keys, and how to configure Infrastructure Manager to execute Terraform using a controlled service account identity. The key operational considerations remain ensuring Terraform's service account has the correct project and secret policy permissions, using for_each for scalable role assignment, accounting for service account deletion propagation delays, and selecting the appropriate resource hierarchy for role bindings.

Sources

  1. Source 1
  2. Source 2
  3. Source 3
  4. Source 4

Related Posts