From 1bf26e30ac617fb56ca335ec0fafb55e18412a3c Mon Sep 17 00:00:00 2001 From: Al Cutter Date: Fri, 13 Sep 2024 14:13:51 +0100 Subject: [PATCH] [GCP] Update `terra{grunt,form}` to reflect externally managed service accounts (#252) --- .../live/gcp/cloudbuild/prod/terragrunt.hcl | 2 ++ .../live/gcp/conformance/terragrunt.hcl | 6 ++-- deployment/modules/gcp/cloudbuild/main.tf | 28 ++++++++----------- .../modules/gcp/cloudbuild/variables.tf | 4 +++ deployment/modules/gcp/conformance/main.tf | 28 +++++++------------ deployment/modules/gcp/conformance/outputs.tf | 5 ---- .../modules/gcp/conformance/variables.tf | 9 ++++-- deployment/modules/gcp/gcs/main.tf | 22 ++++----------- deployment/modules/gcp/gcs/outputs.tf | 4 --- deployment/modules/gcp/gcs/variables.tf | 9 ++++-- 10 files changed, 50 insertions(+), 67 deletions(-) diff --git a/deployment/live/gcp/cloudbuild/prod/terragrunt.hcl b/deployment/live/gcp/cloudbuild/prod/terragrunt.hcl index bfa6b083..d6d535a5 100644 --- a/deployment/live/gcp/cloudbuild/prod/terragrunt.hcl +++ b/deployment/live/gcp/cloudbuild/prod/terragrunt.hcl @@ -6,6 +6,8 @@ include "root" { inputs = merge( include.root.locals, { + # Service accounts are managed externally. + service_account = "cloudbuild-${include.root.locals.env}-sa@trillian-tessera.iam.gserviceaccount.com" kms_key_version_id = get_env("TESSERA_KMS_KEY_VERSION", "projects/${include.root.locals.project_id}/locations/${include.root.locals.region}/keyRings/ci-conformance/cryptoKeys/log-signer/cryptoKeyVersions/1") log_origin = "ci-conformance" } diff --git a/deployment/live/gcp/conformance/terragrunt.hcl b/deployment/live/gcp/conformance/terragrunt.hcl index 1c77b85a..f7213233 100644 --- a/deployment/live/gcp/conformance/terragrunt.hcl +++ b/deployment/live/gcp/conformance/terragrunt.hcl @@ -10,8 +10,10 @@ locals { conformance_gcp_docker_image = "${local.location}-docker.pkg.dev/trillian-tessera/docker-${local.env}/conformance-gcp:latest" kms_key_version_id = get_env("TESSERA_KMS_KEY_VERSION", "projects/${local.project_id}/locations/${local.location}/keyRings/${local.base_name}/cryptoKeys/log-signer/cryptoKeyVersions/1") log_origin = local.base_name - conformance_users = ["serviceAccount:cloudbuild-prod-sa@trillian-tessera.iam.gserviceaccount.com"] - bucket_readers = ["serviceAccount:cloudbuild-prod-sa@trillian-tessera.iam.gserviceaccount.com"] + # Service accounts are managed externally: + conformance_users = ["serviceAccount:cloudbuild-prod-sa@trillian-tessera.iam.gserviceaccount.com"] + bucket_readers = ["serviceAccount:cloudbuild-prod-sa@trillian-tessera.iam.gserviceaccount.com"] + cloudrun_service_account = "cloudrun-${local.env}-sa@trillian-tessera.iam.gserviceaccount.com" } remote_state { diff --git a/deployment/modules/gcp/cloudbuild/main.tf b/deployment/modules/gcp/cloudbuild/main.tf index 15abd00a..7c84db2d 100644 --- a/deployment/modules/gcp/cloudbuild/main.tf +++ b/deployment/modules/gcp/cloudbuild/main.tf @@ -21,7 +21,7 @@ locals { resource "google_cloudbuild_trigger" "docker" { name = "build-docker-${var.env}" - service_account = google_service_account.cloudbuild_service_account.id + service_account = "projects/${var.project_id}/serviceAccounts/${var.service_account}" location = var.region github { @@ -36,7 +36,7 @@ resource "google_cloudbuild_trigger" "docker" { ## Build the GCP conformance server docker image. ## This will be used by the conformance terragrunt config step further down. step { - id = "docker_build_conformance_gcp" + id = "docker_build_conformance_gcp" name = "gcr.io/cloud-builders/docker" args = [ "build", @@ -81,9 +81,9 @@ resource "google_cloudbuild_trigger" "docker" { ## Grab some outputs from the terragrunt apply above (e.g. conformance server URL) and store ## them in files under /workspace. These are needed for later steps. step { - id = "terraform_outputs" - name = "alpine/terragrunt" - script = < /workspace/conformance_url EOT @@ -107,12 +107,12 @@ resource "google_cloudbuild_trigger" "docker" { ## Since the conformance infrastructure is not publicly accessible, we need to use bearer tokens ## for the hammer to access them. ## This step creates those, and stores them for later use. - step { - id = "access" - name = "gcr.io/cloud-builders/gcloud" - script = < /workspace/cb_access - curl -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/service-accounts/${google_service_account.cloudbuild_service_account.email}/identity?audience=$(cat /workspace/conformance_url)" > /workspace/cb_identity + curl -H "Metadata-Flavor: Google" "http://metadata/computeMetadata/v1/instance/service-accounts/${var.service_account}/identity?audience=$(cat /workspace/conformance_url)" > /workspace/cb_identity EOT wait_for = ["terraform_outputs"] } @@ -128,15 +128,9 @@ resource "google_cloudbuild_trigger" "docker" { } options { - logging = "CLOUD_LOGGING_ONLY" + logging = "CLOUD_LOGGING_ONLY" machine_type = "E2_HIGHCPU_8" } } } -# roles managed externally. -resource "google_service_account" "cloudbuild_service_account" { - account_id = "cloudbuild-${var.env}-sa" - display_name = "Service Account for CloudBuild (${var.env})" -} - diff --git a/deployment/modules/gcp/cloudbuild/variables.tf b/deployment/modules/gcp/cloudbuild/variables.tf index b6966586..0afca9b6 100644 --- a/deployment/modules/gcp/cloudbuild/variables.tf +++ b/deployment/modules/gcp/cloudbuild/variables.tf @@ -23,4 +23,8 @@ variable "kms_key_version_id" { type = string } +variable "service_account" { + description = "Service account email to use for cloudbuild" +} + diff --git a/deployment/modules/gcp/conformance/main.tf b/deployment/modules/gcp/conformance/main.tf index 02a58026..e4156844 100644 --- a/deployment/modules/gcp/conformance/main.tf +++ b/deployment/modules/gcp/conformance/main.tf @@ -15,11 +15,12 @@ terraform { module "gcs" { source = "..//gcs" - base_name = var.base_name - env = var.env - location = var.location - project_id = var.project_id - bucket_readers = var.bucket_readers + base_name = var.base_name + env = var.env + location = var.location + project_id = var.project_id + bucket_readers = var.bucket_readers + log_writer_members = ["serviceAccount:${var.cloudrun_service_account}"] } ## @@ -75,15 +76,6 @@ resource "google_kms_crypto_key_version" "log_signer" { */ -### -### Set up Cloud Run service -### -### Roles managed externally. -resource "google_service_account" "cloudrun_service_account" { - account_id = "cloudrun-${var.env}-sa" - display_name = "Service Account for Cloud Run (${var.base_name})" -} - locals { spanner_db_full = "projects/${var.project_id}/instances/${module.gcs.log_spanner_instance.name}/databases/${module.gcs.log_spanner_db.name}" } @@ -94,9 +86,9 @@ resource "google_cloud_run_v2_service" "default" { launch_stage = "GA" template { - service_account = google_service_account.cloudrun_service_account.email + service_account = var.cloudrun_service_account max_instance_request_concurrency = 700 - timeout = "10s" + timeout = "10s" scaling { max_instance_count = 3 @@ -116,13 +108,13 @@ resource "google_cloud_run_v2_service" "default" { "--origin=${var.log_origin}", ] ports { - name = "h2c" + name = "h2c" container_port = 8080 } resources { limits = { - cpu = "2" + cpu = "2" memory = "1024Mi" } } diff --git a/deployment/modules/gcp/conformance/outputs.tf b/deployment/modules/gcp/conformance/outputs.tf index 413a3d62..b63869c8 100644 --- a/deployment/modules/gcp/conformance/outputs.tf +++ b/deployment/modules/gcp/conformance/outputs.tf @@ -1,8 +1,3 @@ -output "run_service_account" { - description = "The CloudRun service account" - value = google_service_account.cloudrun_service_account -} - output "conformance_url" { description = "The URL of the running conformance server" value = google_cloud_run_v2_service.default.uri diff --git a/deployment/modules/gcp/conformance/variables.tf b/deployment/modules/gcp/conformance/variables.tf index 84d81bac..1cf233a1 100644 --- a/deployment/modules/gcp/conformance/variables.tf +++ b/deployment/modules/gcp/conformance/variables.tf @@ -33,12 +33,17 @@ variable "kms_key_version_id" { type = string } +variable "cloudrun_service_account" { + description = "The service account email to use for the CloudRun instance" + type = string +} + variable "conformance_users" { description = "The list of users allowed to invoke calls to the conformance instance." - type = list + type = list(any) } variable "bucket_readers" { description = "The list of users allowed to read the conformance bucket contents" - type = list + type = list(any) } diff --git a/deployment/modules/gcp/gcs/main.tf b/deployment/modules/gcp/gcs/main.tf index b47c3cfe..188ce1ce 100644 --- a/deployment/modules/gcp/gcs/main.tf +++ b/deployment/modules/gcp/gcs/main.tf @@ -18,14 +18,6 @@ resource "google_project_service" "storage_googleapis_com" { ## Resources -# Service accounts - -resource "google_service_account" "log_writer" { - account_id = "${var.base_name}-writer" - display_name = "Transparency log writer service account" -} - - # Buckets resource "google_storage_bucket" "log_bucket" { @@ -39,17 +31,15 @@ resource "google_storage_bucket_iam_binding" "log_bucket_reader" { bucket = google_storage_bucket.log_bucket.name role = "roles/storage.objectViewer" members = concat( - [ google_service_account.log_writer.member ], + var.log_writer_members, var.bucket_readers ) } resource "google_storage_bucket_iam_binding" "log_bucket_writer" { - bucket = google_storage_bucket.log_bucket.name - role = "roles/storage.legacyBucketWriter" - members = [ - google_service_account.log_writer.member - ] + bucket = google_storage_bucket.log_bucket.name + role = "roles/storage.legacyBucketWriter" + members = var.log_writer_members } # Spanner @@ -76,7 +66,5 @@ resource "google_spanner_database_iam_binding" "database" { database = google_spanner_database.log_db.name role = "roles/spanner.databaseUser" - members = [ - google_service_account.log_writer.member - ] + members = var.log_writer_members } diff --git a/deployment/modules/gcp/gcs/outputs.tf b/deployment/modules/gcp/gcs/outputs.tf index 797a5584..4750120e 100644 --- a/deployment/modules/gcp/gcs/outputs.tf +++ b/deployment/modules/gcp/gcs/outputs.tf @@ -13,7 +13,3 @@ output "log_spanner_instance" { value = google_spanner_instance.log_spanner } -output "service_account_name" { - description = "Name of the service account with write permission for storage" - value = google_service_account.log_writer.member -} diff --git a/deployment/modules/gcp/gcs/variables.tf b/deployment/modules/gcp/gcs/variables.tf index 3d852722..9ddfca31 100644 --- a/deployment/modules/gcp/gcs/variables.tf +++ b/deployment/modules/gcp/gcs/variables.tf @@ -20,6 +20,11 @@ variable "env" { variable "bucket_readers" { description = "List of identities allowed to read the log bucket" - type = list - default = [ "allUsers" ] + type = list(any) + default = ["allUsers"] +} + +variable "log_writer_members" { + description = "List of identities in member format allowed to write to the log" + type = list(any) }