terraform-google-modules / terraform-google-project-factory

Creates an opinionated Google Cloud project by using Shared VPC, IAM, and Google Cloud APIs
https://registry.terraform.io/modules/terraform-google-modules/project-factory/google
Apache License 2.0
826 stars 535 forks source link

"activate_api_identities"throwing error that email can't be null #751

Open katiyuki opened 1 year ago

katiyuki commented 1 year ago

TL;DR

I am using "activate_api_identities" with api "cloudfunctions.googleapis.com" so I can create the "appspot" google managed service account, and assign roles to it. terraform plan fails with:

on .terraform/modules/project-factory/modules/project_services/main.tf line 84, in resource "google_project_iam_member" "project_service_identity_roles":" member = "serviceAccount:${each.value.email} each.value.email is null The expression result is null. Cannot include a null value in a string template

Expected behavior

terraform plan to succeed, with use of activate_api_identities", mapping API to roles

Observed behavior

on .terraform/modules/project-factory/modules/project_services/main.tf line 84, in resource "google_project_iam_member" "project_service_identity_roles":" member = "serviceAccount:${each.value.email} each.value.email is null The expression result is null. Cannot include a null value in a string template

Terraform Configuration

variable "activate_api_identities" {
  type = list(object({
    api   = string
    roles = list(string)
  }))
  description = "The list of service identities (Google Managed service account for the API) to force-create for the project (e.g. in order to grant additional roles)."
  default     = []
}

-------
module "project-factory" {
  count   = var.create_project ? 1 : 0
  source  = "terraform-google-modules/project-factory/google"
  version = "13.0.0"
  ...
  activate_api_identities = var.activate_api_identities
}
----------
activate_api_identities = [
  {
    api = "cloudfunctions.googleapis.com"
    roles = [
      "roles/editor",
      "roles/artifactregistry.repoAdmin",
      "roles/cloudbuild.builds.builder",
      "roles/cloudfunctions.invoker",
      "roles/run.serviceAgent",
      "roles/secretmanager.secretAccessor",
      "roles/storage.admin",
      "roles/workflows.invoker"
    ]
  },
  {
    api = "compute.googleapis.com"
    roles = [
      "roles/editor"
    ]
  }
]

Terraform Version

terraform {
  required_version = "~> 1.0"

  backend "gcs" {}
}

Additional information

No response

katiyuki commented 1 year ago

when I removed the "compute.googleapis.com" part in "activate_api_identities" list, terraform plan ran successfully.

why?

github-actions[bot] commented 1 year ago

This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days

bharathkkb commented 1 year ago

@katiyuki this maybe because the compute API does not return the service identity. Usually a way to check if a service supports returns an identity is by running the gcloud command gcloud beta services identity create --service=cloudfunctions.googleapis.com --format json. In this case within the module, I think we should filter out any each.value.email that is null.

imrannayer commented 5 months ago

It is needed for very few APIs like healthcare etc. There is no way to find which API is supported. It should not be used unless user is aware of the API which needs it.

imrannayer commented 5 months ago

I have added in the variable description that it only APIs which are supported by command gcloud beta services identity create