A Terraform Module to List Google Cloud Service Agents

Google Cloud Platform presents two distinct types of service accounts: user-managed service accounts and Google-managed service accounts. The former is typically employed by user applications as an interface with Google Cloud, whereas the latter is utilized internally by Google Cloud. Within the realm of Google-managed service accounts, a specialized subset exists: Google Cloud Service Agents. These service agents are used by Google Cloud services to operate internal processes necessary to fulfill user-requested operations.

A service agent adhers to the following template:

service-PROJECT_NUMBER@SERVICE_NAME.iam.gserviceaccount.com

These service agents are easily identifiable within the IAM section of the Google Cloud Console.

/img/20200402-0012.png

During the management of IAM binding policies via Terraform, these service agents can often become obtrusive. For illustration, consider the following code snippet from one of our Terraform files (where xxxxx substitutes the actual project number).

data "google_project" "project" {}

resource "google_project_iam_binding" "cloudbuild_service_agent" {
  project = data.google_project.project.project_id
  role    = "roles/cloudbuild.serviceAgent"

  members = [
    "serviceAccount:[email protected]",
  ]
}

resource "google_project_iam_binding" "container_service_agent" {
  project = data.google_project.project.project_id
  role    = "roles/container.serviceAgent"

  members = [
    "serviceAccount:[email protected]",
  ]
}

The complication intensifies when referencing service agents from different projects, as these project numbers can often resemble what we term “magic numbers”.

To address this issue, I’ve developed a simple Terraform module dubbed google-cloud-service-agents. This module accepts a project ID as input and provides a list of service agents as output. By leveraging this module, the aforementioned code snippet can be effectively refactored as follow:

data "google_project" "project" {}

module "agents" {
  source = "/path/to/module"

  project_number = data.google_project.project.number
}

resource "google_project_iam_binding" "cloudbuild_service_agent" {
  project = data.google_project.project.project_id
  role    = "roles/cloudbuild.serviceAgent"

  members = [
    "serviceAccount:${module.agents.cloud_build}",
  ]
}

resource "google_project_iam_binding" "container_service_agent" {
  project = data.google_project.project.project_id
  role    = "roles/container.serviceAgent"

  members = [
    "serviceAccount:${module.agents.container_engine}",
  ]
}

For more information, kindly refer to the Github repository.