Running Infrastructure-As-Code With The Least Privilege Possible

Terraform is an open source infrastructure as code tool that is used widely for managing google cloud resources as it lets you define resources as human-readable configuration files that you can version, reuse and share which provides flexibility of managing IAC, portability and easy collaboration among developers. When starting to use terraform to manage resources with roles like owner, editor assigned developers can focus more towards maintaining the syntax and structure of Terraform configuration files. As with greater permissions assigned one has less chances of getting an IAM Permissions issue.

In this blog post we will outline the various methods to impersonate google cloud service accounts using terraform. Using service account impersonation the administrators need not generate service account keys whereas the permissions are maintained via IAM with Service Account Token Creator role. So administrators are not required to implement any service account key management process, key rotation, creation and deletion. This improves resource security as user accounts can be granted permissions to specific service accounts using the principle of least privilege. It improves access management and access security as user credentials are not used to grant Google Cloud Service Authorization.

Terraform code should be run with the principle of least privilege to address best security practices while using IAM. Instead of restricting the user access privileges as per terraform code one can use service accounts to run Terraform code. A service account is a special type of Google Account used by different resources like virtual machines to access APIs and services. Applications can authenticate using non-human user service accounts to be authorized access to data in Google APIs.

Service Account authentication can be done by generating the service account keys but using this approach one has to maintain the keys with rotation at regular intervals and also add api key restrictions to avoid the impact of compromised keys which is a security downside with this approach as any user with keys can authenticate with the service account.

Another approach to achieve this is using the service account impersonation. With this the user does not need access to service account keys instead needs IAM Permissions to authorize the use of the service account. This reduces the permissions required for the user account. If a user no longer requires access to the service account then simply we can remove his identity from the service account resource in Google Cloud IAM.

Permissions Needed for Service Account Impersonation

Below are the permissions needed for the user account to impersonate a service account :

  • Service Account User (roles/iam.serviceAccountUser): The role allows principals to access resources that service account has access to. This role however does refuse principals to create short-lived credentials for service accounts or use –impersonate-service-account flag for Google Cloud CLI.
  • Service Account Token Creator (roles/iam.serviceAccountTokenCreator): The role allows principals to impersonate service accounts creating credentials ( OAuth 2.0 access tokens, OpenID Connect (OIDC) ID tokens, Sign JSON Web Tokens (JWTs) and binary blobs )

Ways to Impersonate Service Account for running Terraform Code

The first method to impersonate the service account is to set the GOOGLE_IMPERSONATE_SERVICE_ACCOUNT environment variable to the service account’s email.

For example : export GOOGLE_IMPERSONATE[email protected]

This would impersonate the service account and any Terraform code ran post this would be using the service account’s credentials. Limitation with the approach being setting the environment variable with every terminal restarts and also using a single account for complete Terraform code.¨C7C¨C8C

The second method is to add a provider alias with access_token to impersonate the service account. This would require the below steps to be added to the Terraform code.

  • Either create the service account via Terraform configuration file or set variable with service account email in terraform.tfvars to be used.
  • Provider block used to retrieve an access token for the service account.
provider "google" {
    alias = "imperonation"
    scopes = [
  • Add a data block to get the access token for the service account.
data "google_service_account_access_token" "default" {
    provider = google.impersonation
    target_service_account = [email protected]
    scopes = [ "userinfo-email", "cloud-platform" ]
    lifetime = "1200s"
  • Include a provider block to use the access token of the given service account.
provider "google" {
    project = "YOUR_PROJECT_ID"
    access_token = data.google_service_account_access_token.default.access_token
    request_timeout = "60s"

Now any resources created running the Terraform code will use the service account impersonated using the above approach. With this approach we can use different service accounts to run different Terraform modules with the principle of least privilege.

The third option is to use service account impersonation using the provider block attribute impersonate_service_account. Using this approach similar to the previous approach we can have a provider alias which can impersonate a service account for a given provider. We can use below steps to implement this :

Add the below provider block to impersonate the service account.

provider "google" {
    project = "YOUR_PROJECT_ID"
    impersonate_service_account = [email protected]
  • Above step would set impersonation to the default provider block if impersonation is needed only to run a few tasks we can use alias attribute and define provider with alias for resource where impersonation is required. Billing Budget Terraform resource created below will use the impersonated service account as shown.
provider "google" {
    alias = "impersonate"
    project = "YOUR_PROJECT_ID"
    impersonate_service_account = [email protected]

By: Vipul Sharma (Cloud Engineer, Infrastructure, Google)
Originally published at: Google Cloud Blog

Source: Cyberpogo

Our humans need coffee too! Your support is highly appreciated, thank you!

Previous Article

Solving The Serverless Cloud Cost Conundrum

Next Article

Private Service Connect: Now Hybrid And Global

Related Posts