Imaging when I needed to grant access to a Google storage bucket for a list of Google service accounts, I put the list in YAML like this:
# data/gcs.yaml google-service-accounts: - [email protected] - [email protected] - [email protected] - [email protected] ...
Assuming horizon
is the default GCP project and mass-effect
is a partner project and most GSAs are of course from the default project. So can this list be DRYed up a bit like this?
# data/gcs.yaml google-service-accounts: - gaia - nova - cyan - edi@mass-effect ... default: project: horizon
The terraform
code to read this YAML and grant IAM members could look like:
locals { manifest = yamldecode(file("./data/gcs.yaml")) } resource "google_storage_bucket" "default" { ... } resource "google_storage_bucket_iam_binding" "default_readers" { bucket = google_storage_bucket.default.name role = "roles/storage.objectViewer" members = formatlist( "serviceAccount:%s", [for member in local.manifest['google-service-accounts'] : format("%s@%s.iam.gserviceaccount.com", split("@", member)[0], try(split("@", member)[1], local.manifest.default.project))] ) }
A quick explanation on how this works:
# for item `gaia` split("@", "gaia") -> ["gaia"] split("@", "gaia")[0] -> "gaia" split("@", "gaia")[1] -> error # doesn't exist try(split("@", "gaia")[1], "horizon") -> "horizon" format("%s@%s.iam.gserviceaccount.com", ...) -> "[email protected]" # for item edi@mass-effect split("@", "edi@mass-effect") -> ["edi", "mass-effect"] split("@", "edi@mass-effect")[0] -> "edi" split("@", "edi@mass-effect")[1] -> "mass-effect" try(split("@", "edi@mass-effect")[1], "horizon") -> "mass-effect" format("%s@%s.iam.gserviceaccount.com", ...) -> "[email protected]"
PS. yes I like the Horizon and Mass Effect games. 🙂