From d47a6fd7cae3319c11670c8b4450eb895cff1eb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wiktor=20Niesiob=C4=99dzki?= Date: Tue, 3 Sep 2024 16:41:41 +0000 Subject: [PATCH 1/2] Add IAM dependencies to outputs --- modules/artifact-registry/outputs.tf | 14 +++++++++- modules/bigquery-dataset/outputs.tf | 9 ++++--- modules/gcs/outputs.tf | 8 ++++-- modules/kms/outputs.tf | 39 +++++++++++++++++++++++----- modules/project/cmek.tf | 5 ++-- modules/pubsub/outputs.tf | 12 ++++++--- modules/secret-manager/outputs.tf | 16 ++++++++++++ 7 files changed, 84 insertions(+), 19 deletions(-) diff --git a/modules/artifact-registry/outputs.tf b/modules/artifact-registry/outputs.tf index 0a804888d3..ad3cb7dcf6 100644 --- a/modules/artifact-registry/outputs.tf +++ b/modules/artifact-registry/outputs.tf @@ -17,16 +17,25 @@ output "id" { description = "Fully qualified repository id." value = google_artifact_registry_repository.registry.id + depends_on = [ + google_artifact_registry_repository_iam_binding.bindings + ] } output "name" { description = "Repository name." value = google_artifact_registry_repository.registry.name + depends_on = [ + google_artifact_registry_repository_iam_binding.bindings + ] } output "repository" { description = "Repository object." value = google_artifact_registry_repository.registry + depends_on = [ + google_artifact_registry_repository_iam_binding.bindings + ] } output "url" { @@ -36,5 +45,8 @@ output "url" { var.project_id, var.name ]) - depends_on = [google_artifact_registry_repository.registry] + depends_on = [ + google_artifact_registry_repository.registry, + google_artifact_registry_repository_iam_binding.bindings + ] } diff --git a/modules/bigquery-dataset/outputs.tf b/modules/bigquery-dataset/outputs.tf index 3beb5f82c5..21b3fe41c5 100644 --- a/modules/bigquery-dataset/outputs.tf +++ b/modules/bigquery-dataset/outputs.tf @@ -29,7 +29,8 @@ output "dataset_id" { google_bigquery_dataset_access.domain, google_bigquery_dataset_access.group_by_email, google_bigquery_dataset_access.special_group, - google_bigquery_dataset_access.user_by_email + google_bigquery_dataset_access.user_by_email, + google_bigquery_dataset_iam_binding.bindings, ] } @@ -43,7 +44,8 @@ output "id" { google_bigquery_dataset_access.domain, google_bigquery_dataset_access.group_by_email, google_bigquery_dataset_access.special_group, - google_bigquery_dataset_access.user_by_email + google_bigquery_dataset_access.user_by_email, + google_bigquery_dataset_iam_binding.bindings, ] } @@ -67,7 +69,8 @@ output "self_link" { google_bigquery_dataset_access.domain, google_bigquery_dataset_access.group_by_email, google_bigquery_dataset_access.special_group, - google_bigquery_dataset_access.user_by_email + google_bigquery_dataset_access.user_by_email, + google_bigquery_dataset_iam_binding.bindings, ] } diff --git a/modules/gcs/outputs.tf b/modules/gcs/outputs.tf index e49bc72199..ed2f6c2128 100644 --- a/modules/gcs/outputs.tf +++ b/modules/gcs/outputs.tf @@ -30,7 +30,9 @@ output "id" { value = "${local.prefix}${lower(var.name)}" depends_on = [ google_storage_bucket.bucket, - google_storage_bucket_iam_binding.bindings + google_storage_bucket_iam_binding.bindings, + google_storage_bucket_iam_binding.authoritative, + google_storage_bucket_iam_member.bindings ] } @@ -39,7 +41,9 @@ output "name" { value = "${local.prefix}${lower(var.name)}" depends_on = [ google_storage_bucket.bucket, - google_storage_bucket_iam_binding.bindings + google_storage_bucket_iam_binding.bindings, + google_storage_bucket_iam_binding.authoritative, + google_storage_bucket_iam_member.bindings ] } diff --git a/modules/kms/outputs.tf b/modules/kms/outputs.tf index acfb69b3e6..9346ce6b86 100644 --- a/modules/kms/outputs.tf +++ b/modules/kms/outputs.tf @@ -19,7 +19,11 @@ output "id" { value = local.keyring.id depends_on = [ google_kms_key_ring_iam_binding.authoritative, - google_kms_key_ring_iam_binding.bindings + google_kms_key_ring_iam_binding.bindings, + google_kms_key_ring_iam_member.bindings, + google_kms_crypto_key_iam_binding.authoritative, + google_kms_crypto_key_iam_binding.bindings, + google_kms_crypto_key_iam_member.members ] } @@ -28,7 +32,11 @@ output "import_job" { value = google_kms_key_ring_import_job.default depends_on = [ google_kms_key_ring_iam_binding.authoritative, - google_kms_key_ring_iam_binding.bindings + google_kms_key_ring_iam_binding.bindings, + google_kms_key_ring_iam_member.bindings, + google_kms_crypto_key_iam_binding.authoritative, + google_kms_crypto_key_iam_binding.bindings, + google_kms_crypto_key_iam_member.members ] } @@ -40,7 +48,8 @@ output "key_ids" { } depends_on = [ google_kms_crypto_key_iam_binding.authoritative, - google_kms_crypto_key_iam_binding.bindings + google_kms_crypto_key_iam_binding.bindings, + google_kms_crypto_key_iam_member.members ] } @@ -49,7 +58,11 @@ output "keyring" { value = local.keyring depends_on = [ google_kms_key_ring_iam_binding.authoritative, - google_kms_key_ring_iam_binding.bindings + google_kms_key_ring_iam_binding.bindings, + google_kms_crypto_key_iam_member.members, + google_kms_crypto_key_iam_binding.authoritative, + google_kms_crypto_key_iam_binding.bindings, + google_kms_crypto_key_iam_member.members, ] } @@ -57,8 +70,12 @@ output "keys" { description = "Key resources." value = google_kms_crypto_key.default depends_on = [ + google_kms_key_ring_iam_binding.authoritative, + google_kms_key_ring_iam_binding.bindings, + google_kms_key_ring_iam_member.bindings, google_kms_crypto_key_iam_binding.authoritative, - google_kms_crypto_key_iam_binding.bindings + google_kms_crypto_key_iam_binding.bindings, + google_kms_crypto_key_iam_member.members ] } @@ -67,7 +84,11 @@ output "location" { value = local.keyring.location depends_on = [ google_kms_key_ring_iam_binding.authoritative, - google_kms_key_ring_iam_binding.bindings + google_kms_key_ring_iam_binding.bindings, + google_kms_key_ring_iam_member.bindings, + google_kms_crypto_key_iam_binding.authoritative, + google_kms_crypto_key_iam_binding.bindings, + google_kms_crypto_key_iam_member.members ] } @@ -76,6 +97,10 @@ output "name" { value = local.keyring.name depends_on = [ google_kms_key_ring_iam_binding.authoritative, - google_kms_key_ring_iam_binding.bindings + google_kms_key_ring_iam_binding.bindings, + google_kms_key_ring_iam_member.bindings, + google_kms_crypto_key_iam_binding.authoritative, + google_kms_crypto_key_iam_binding.bindings, + google_kms_crypto_key_iam_member.members ] } diff --git a/modules/project/cmek.tf b/modules/project/cmek.tf index 9cf83a6b54..fd37191262 100644 --- a/modules/project/cmek.tf +++ b/modules/project/cmek.tf @@ -54,8 +54,9 @@ locals { # use the deps listed above, if the service does not appear # there, use all the service agents belonging to the service for dep in try(local._cmek_agents_by_service[service], [for x in local._service_agents_by_api[service] : x.name]) : { - for key in keys : - "${key}.${local._aliased_service_agents[dep].name}" => { + # use index in map key, to allow specyfing keys, that will be created in the same apply + for index, key in keys : + "key-${index}.${local._aliased_service_agents[dep].name}" => { key = key agent = local._aliased_service_agents[dep].iam_email } diff --git a/modules/pubsub/outputs.tf b/modules/pubsub/outputs.tf index 8218e2b335..35ad069db4 100644 --- a/modules/pubsub/outputs.tf +++ b/modules/pubsub/outputs.tf @@ -20,7 +20,8 @@ output "id" { depends_on = [ google_pubsub_topic.default, google_pubsub_topic_iam_binding.authoritative, - google_pubsub_topic_iam_binding.bindings + google_pubsub_topic_iam_binding.bindings, + google_pubsub_topic_iam_member.bindings ] } @@ -41,7 +42,8 @@ output "subscription_id" { } depends_on = [ google_pubsub_subscription_iam_binding.authoritative, - google_pubsub_subscription_iam_binding.bindings + google_pubsub_subscription_iam_binding.bindings, + google_pubsub_subscription_iam_member.members ] } @@ -50,7 +52,8 @@ output "subscriptions" { value = google_pubsub_subscription.default depends_on = [ google_pubsub_subscription_iam_binding.authoritative, - google_pubsub_subscription_iam_binding.bindings + google_pubsub_subscription_iam_binding.bindings, + google_pubsub_subscription_iam_member.members ] } @@ -59,6 +62,7 @@ output "topic" { value = google_pubsub_topic.default depends_on = [ google_pubsub_topic_iam_binding.authoritative, - google_pubsub_topic_iam_binding.bindings + google_pubsub_topic_iam_binding.bindings, + google_pubsub_topic_iam_member.bindings ] } diff --git a/modules/secret-manager/outputs.tf b/modules/secret-manager/outputs.tf index 7450ad742a..89215567b9 100644 --- a/modules/secret-manager/outputs.tf +++ b/modules/secret-manager/outputs.tf @@ -19,11 +19,18 @@ output "ids" { value = { for k, v in google_secret_manager_secret.default : v.secret_id => v.id } + depends_on = [ + google_secret_manager_secret_iam_binding.default + ] } output "secrets" { description = "Secret resources." value = google_secret_manager_secret.default + depends_on = [ + google_secret_manager_secret_iam_binding.default + ] + } output "version_ids" { @@ -31,6 +38,9 @@ output "version_ids" { value = { for k, v in google_secret_manager_secret_version.default : k => v.id } + depends_on = [ + google_secret_manager_secret_iam_binding.default + ] } output "version_versions" { @@ -38,10 +48,16 @@ output "version_versions" { value = { for k, v in google_secret_manager_secret_version.default : k => v.version } + depends_on = [ + google_secret_manager_secret_iam_binding.default + ] } output "versions" { description = "Secret versions." value = google_secret_manager_secret_version.default sensitive = true + depends_on = [ + google_secret_manager_secret_iam_binding.default + ] } From 398f73eaea1b5adffc78226da6d1d594cf459c87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wiktor=20Niesiob=C4=99dzki?= Date: Tue, 3 Sep 2024 16:43:07 +0000 Subject: [PATCH 2/2] Fix E2E tests --- modules/alloydb/README.md | 60 ++++++++++-- modules/artifact-registry/README.md | 6 +- modules/bigquery-dataset/README.md | 16 +-- modules/cloud-function-v1/README.md | 97 +++++++++++++++---- modules/cloud-function-v2/README.md | 38 +++++++- modules/cloud-run-v2/README.md | 37 ++++++- modules/cloudsql-instance/README.md | 65 ++++++++++--- modules/compute-vm/README.md | 55 +++++++++-- modules/dataproc/README.md | 66 ++++++++++--- modules/gcs/README.md | 10 +- modules/kms/README.md | 15 ++- modules/net-vpc/README.md | 20 ++-- modules/project/README.md | 51 ++++++++-- modules/pubsub/README.md | 10 +- modules/secret-manager/README.md | 90 ++++++++++++++--- tests/examples/variables.tf | 12 --- .../setup_module/e2e_tests.tfvars.tftpl | 6 -- tests/examples_e2e/setup_module/main.tf | 25 +---- .../functions-default-sa-iam-grants.tf | 6 -- tests/fixtures/kms-global-regional-keys.tf | 43 ++++---- tests/modules/alloydb/examples/cmek.yaml | 9 +- .../examples/bucket-creation.yaml | 2 +- .../examples/bucket-creation.yaml | 2 +- .../cloud_function_v2/examples/iam.yaml | 1 - tests/modules/compute_vm/examples/cmek.yaml | 15 +-- .../net_vpc/examples/psa-prefix-services.yaml | 46 +-------- tests/modules/project/examples/data.yaml | 34 +++++-- .../project/service_encryption_keys.yaml | 6 +- .../project_factory/examples/example.yaml | 2 +- .../secret_manager/examples/secret-cmek.yaml | 12 +-- 30 files changed, 592 insertions(+), 265 deletions(-) diff --git a/modules/alloydb/README.md b/modules/alloydb/README.md index 6b4292bda1..147fd0a46c 100644 --- a/modules/alloydb/README.md +++ b/modules/alloydb/README.md @@ -147,23 +147,71 @@ module "alloydb" { ### CMEK encryption ```hcl +module "project" { + source = "./fabric/modules/project" + name = "alloycmek" + billing_account = var.billing_account_id + prefix = var.prefix + parent = var.folder_id + services = [ + "alloydb.googleapis.com", + "cloudkms.googleapis.com", + "servicenetworking.googleapis.com" + ] +} + +module "kms" { + source = "./fabric/modules/kms" + project_id = module.project.project_id + keyring = { + location = var.region + name = "keyring" + } + keys = { + "key-regional" = { + } + } + iam = { + "roles/cloudkms.cryptoKeyEncrypterDecrypter" = [ + module.project.service_agents.alloydb.iam_email + ] + } +} + +module "vpc" { + source = "./fabric/modules/net-vpc" + project_id = module.project.project_id + name = "my-network" + subnets = [ + { + ip_cidr_range = "10.0.0.0/24" + name = "production" + region = var.region + }, + ] + psa_configs = [{ + ranges = { myrange = "10.0.1.0/24" } + }] +} + + module "alloydb" { source = "./fabric/modules/alloydb" - project_id = var.project_id + project_id = module.project.project_id cluster_name = "primary" location = var.region name = "primary" network_config = { psa_config = { - network = var.vpc.id + network = module.vpc.id } } encryption_config = { - primary_kms_key_name = var.kms_key.id + primary_kms_key_name = module.kms.keys.key-regional.id } } -# tftest modules=1 resources=3 fixtures=fixtures/alloydb-kms-iam-grant.tf inventory=cmek.yaml e2e +# tftest inventory=cmek.yaml e2e ``` ## Tag bindings @@ -257,8 +305,4 @@ module "alloydb" { | [service_attachment](outputs.tf#L90) | AlloyDB Primary instance service attachment. | | | [service_attachments](outputs.tf#L95) | AlloyDB instances service attachment. | | | [user_passwords](outputs.tf#L102) | Map of containing the password of all users created through terraform. | ✓ | - -## Fixtures - -- [alloydb-kms-iam-grant.tf](../../tests/fixtures/alloydb-kms-iam-grant.tf) diff --git a/modules/artifact-registry/README.md b/modules/artifact-registry/README.md index c61bf1e65b..f3623e3e3c 100644 --- a/modules/artifact-registry/README.md +++ b/modules/artifact-registry/README.md @@ -231,7 +231,7 @@ module "registry-docker" { | name | description | sensitive | |---|---|:---:| | [id](outputs.tf#L17) | Fully qualified repository id. | | -| [name](outputs.tf#L22) | Repository name. | | -| [repository](outputs.tf#L27) | Repository object. | | -| [url](outputs.tf#L32) | Repository URL. | | +| [name](outputs.tf#L25) | Repository name. | | +| [repository](outputs.tf#L33) | Repository object. | | +| [url](outputs.tf#L41) | Repository URL. | | diff --git a/modules/bigquery-dataset/README.md b/modules/bigquery-dataset/README.md index c0f15289ae..0ef0773ca4 100644 --- a/modules/bigquery-dataset/README.md +++ b/modules/bigquery-dataset/README.md @@ -347,12 +347,12 @@ module "bigquery-dataset" { |---|---|:---:| | [dataset](outputs.tf#L17) | Dataset resource. | | | [dataset_id](outputs.tf#L22) | Dataset id. | | -| [id](outputs.tf#L36) | Fully qualified dataset id. | | -| [materialized_view_ids](outputs.tf#L50) | Map of fully qualified materialized view ids keyed by view ids. | | -| [materialized_views](outputs.tf#L55) | Materialized view resources. | | -| [self_link](outputs.tf#L60) | Dataset self link. | | -| [table_ids](outputs.tf#L74) | Map of fully qualified table ids keyed by table ids. | | -| [tables](outputs.tf#L79) | Table resources. | | -| [view_ids](outputs.tf#L84) | Map of fully qualified view ids keyed by view ids. | | -| [views](outputs.tf#L89) | View resources. | | +| [id](outputs.tf#L37) | Fully qualified dataset id. | | +| [materialized_view_ids](outputs.tf#L52) | Map of fully qualified materialized view ids keyed by view ids. | | +| [materialized_views](outputs.tf#L57) | Materialized view resources. | | +| [self_link](outputs.tf#L62) | Dataset self link. | | +| [table_ids](outputs.tf#L77) | Map of fully qualified table ids keyed by table ids. | | +| [tables](outputs.tf#L82) | Table resources. | | +| [view_ids](outputs.tf#L87) | Map of fully qualified view ids keyed by view ids. | | +| [views](outputs.tf#L92) | View resources. | | diff --git a/modules/cloud-function-v1/README.md b/modules/cloud-function-v1/README.md index d5431854a6..b63982e38b 100644 --- a/modules/cloud-function-v1/README.md +++ b/modules/cloud-function-v1/README.md @@ -40,8 +40,11 @@ module "cf-http" { bundle_config = { path = "assets/sample-function/" } + depends_on = [ + google_project_iam_member.bucket_default_compute_account_grant, + ] } -# tftest modules=1 resources=5 fixtures=fixtures/functions-default-sa-iam-grants.tf e2e +# tftest modules=1 resources=5 fixtures=fixtures/functions-default-sa-iam-grants.tf e2e ``` ### PubSub and non-HTTP triggers @@ -62,6 +65,10 @@ module "cf-http" { event = "google.pubsub.topic.publish" resource = module.pubsub.topic.name } + depends_on = [ + google_project_iam_member.bucket_default_compute_account_grant, + ] + } # tftest modules=2 resources=7 fixtures=fixtures/pubsub.tf,fixtures/functions-default-sa-iam-grants.tf e2e ``` @@ -83,8 +90,11 @@ module "cf-http" { iam = { "roles/cloudfunctions.invoker" = ["allUsers"] } + depends_on = [ + google_project_iam_member.bucket_default_compute_account_grant, + ] } -# tftest modules=1 resources=6 fixtures=fixtures/functions-default-sa-iam-grants.tf inventory=iam.yaml e2e +# tftest fixtures=fixtures/functions-default-sa-iam-grants.tf inventory=iam.yaml e2e ``` ### GCS bucket creation @@ -106,8 +116,11 @@ module "cf-http" { bundle_config = { path = "assets/sample-function/" } + depends_on = [ + google_project_iam_member.bucket_default_compute_account_grant, + ] } -# tftest modules=1 resources=6 fixtures=fixtures/functions-default-sa-iam-grants.tf inventory=bucket-creation.yaml e2e +# tftest fixtures=fixtures/functions-default-sa-iam-grants.tf inventory=bucket-creation.yaml e2e ``` ### Service account management @@ -125,6 +138,9 @@ module "cf-http" { path = "assets/sample-function/" } service_account_create = true + depends_on = [ + google_project_iam_member.bucket_default_compute_account_grant, + ] } # tftest modules=1 resources=6 fixtures=fixtures/functions-default-sa-iam-grants.tf e2e ``` @@ -142,6 +158,9 @@ module "cf-http" { path = "assets/sample-function/" } service_account = var.service_account.email + depends_on = [ + google_project_iam_member.bucket_default_compute_account_grant, + ] } # tftest modules=1 resources=5 fixtures=fixtures/functions-default-sa-iam-grants.tf e2e ``` @@ -170,6 +189,9 @@ module "cf-http" { excludes = ["__pycache__"] } } + depends_on = [ + google_project_iam_member.bucket_default_compute_account_grant, + ] } # tftest modules=1 resources=5 fixtures=fixtures/functions-default-sa-iam-grants.tf e2e ``` @@ -189,6 +211,9 @@ module "cf-http" { bundle_config = { path = "assets/sample-function/" } + depends_on = [ + google_project_iam_member.bucket_default_compute_account_grant, + ] } # tftest modules=1 resources=6 fixtures=fixtures/cloudbuild-custom-pool.tf,fixtures/functions-default-sa-iam-grants.tf e2e ``` @@ -218,8 +243,11 @@ module "cf-http-two" { bundle_config = { path = "assets/sample-function/" } + depends_on = [ + google_project_iam_member.bucket_default_compute_account_grant, + ] } -# tftest modules=2 resources=7 fixtures=fixtures/functions-default-sa-iam-grants.tf inventory=multiple_functions.yaml e2e +# tftest fixtures=fixtures/functions-default-sa-iam-grants.tf inventory=multiple_functions.yaml e2e ``` ### Mounting secrets from Secret Manager @@ -256,8 +284,11 @@ module "cf-http" { ] } } + depends_on = [ + google_project_iam_member.bucket_default_compute_account_grant, + ] } -# tftest modules=2 resources=8 fixtures=fixtures/secret-credentials.tf,fixtures/functions-default-sa-iam-grants.tf inventory=secrets.yaml e2e +# tftest fixtures=fixtures/secret-credentials.tf,fixtures/functions-default-sa-iam-grants.tf inventory=secrets.yaml e2e ``` ### Using CMEK to encrypt function resources @@ -265,52 +296,80 @@ module "cf-http" { This encrypt bucket _gcf-sources-*_ with the provided kms key. The repository has to be encrypted with the same kms key. ```hcl +module "project" { + source = "./fabric/modules/project" + name = "cf-v1" + billing_account = var.billing_account_id + prefix = var.prefix + parent = var.folder_id + services = [ + "artifactregistry.googleapis.com", + "cloudbuild.googleapis.com", + "cloudfunctions.googleapis.com", + "cloudkms.googleapis.com", + "compute.googleapis.com", + "storage.googleapis.com", + ] + iam = { + # grant compute default service account that is used by Cloud Founction + # permission to read from the buckets so it can function sources + "roles/storage.objectViewer" = [ + "serviceAccount:${module.project.default_service_accounts.compute}" + ] + } +} + module "kms" { source = "./fabric/modules/kms" - project_id = var.project_id + project_id = module.project.project_id keyring = { location = var.regions.secondary - name = "function-cmek" + name = "keyring" } keys = { - "key" = {} + "key-regional" = { + } } iam = { "roles/cloudkms.cryptoKeyEncrypterDecrypter" = [ - "serviceAccount:service-${var.project_number}@gcf-admin-robot.iam.gserviceaccount.com", - "serviceAccount:service-${var.project_number}@gcp-sa-artifactregistry.iam.gserviceaccount.com", - "serviceAccount:service-${var.project_number}@gs-project-accounts.iam.gserviceaccount.com", + module.project.service_agents["artifactregistry"].iam_email, + module.project.service_agents["cloudfunctions"].iam_email, + module.project.service_agents["storage"].iam_email, ] } } module "artifact-registry" { source = "./fabric/modules/artifact-registry" - project_id = var.project_id + project_id = module.project.project_id location = var.regions.secondary name = "registry" format = { docker = { standard = {} } } - encryption_key = module.kms.key_ids["key"] - depends_on = [ - module.kms - ] + encryption_key = module.kms.key_ids["key-regional"] + iam = { + "roles/artifactregistry.createOnPushWriter" = [ + # grant compute default service account that is used by Cloud Build + # permission to push compiled container into Artifact Registry + "serviceAccount:${module.project.default_service_accounts.compute}", + ] + } } module "cf-http" { source = "./fabric/modules/cloud-function-v1" - project_id = var.project_id + project_id = module.project.project_id region = var.regions.secondary name = "test-cf-http" bucket_name = var.bucket bundle_config = { path = "assets/sample-function/" } - kms_key = module.kms.key_ids["key"] + kms_key = module.kms.key_ids["key-regional"] repository_settings = { repository = module.artifact-registry.id } } -# tftest modules=3 resources=9 fixtures=fixtures/functions-default-sa-iam-grants.tf e2e +# tftest modules=4 resources=25 ``` ## Variables diff --git a/modules/cloud-function-v2/README.md b/modules/cloud-function-v2/README.md index d4b58c243c..0fc90148ca 100644 --- a/modules/cloud-function-v2/README.md +++ b/modules/cloud-function-v2/README.md @@ -39,6 +39,9 @@ module "cf-http" { bundle_config = { path = "assets/sample-function/" } + depends_on = [ + google_project_iam_member.bucket_default_compute_account_grant, + ] } # tftest modules=1 resources=5 fixtures=fixtures/functions-default-sa-iam-grants.tf e2e ``` @@ -73,6 +76,9 @@ module "cf-http" { pubsub_topic = module.pubsub.topic.id service_account_email = module.trigger-service-account.email } + depends_on = [ + google_project_iam_member.bucket_default_compute_account_grant, + ] } # tftest modules=3 resources=9 fixtures=fixtures/pubsub.tf,fixtures/functions-default-sa-iam-grants.tf e2e ``` @@ -97,8 +103,11 @@ module "cf-http" { iam = { "roles/run.invoker" = ["allUsers"] } + depends_on = [ + google_project_iam_member.bucket_default_compute_account_grant, + ] } -# tftest modules=1 resources=6 fixtures=fixtures/functions-default-sa-iam-grants.tf inventory=iam.yaml e2e +# tftest fixtures=fixtures/functions-default-sa-iam-grants.tf inventory=iam.yaml e2e ``` ### GCS bucket creation @@ -120,8 +129,11 @@ module "cf-http" { bundle_config = { path = "assets/sample-function/" } + depends_on = [ + google_project_iam_member.bucket_default_compute_account_grant, + ] } -# tftest modules=1 resources=6 fixtures=fixtures/functions-default-sa-iam-grants.tf inventory=bucket-creation.yaml e2e +# tftest fixtures=fixtures/functions-default-sa-iam-grants.tf inventory=bucket-creation.yaml e2e ``` ### Service account management @@ -139,6 +151,9 @@ module "cf-http" { path = "assets/sample-function/" } service_account_create = true + depends_on = [ + google_project_iam_member.bucket_default_compute_account_grant, + ] } # tftest modules=1 resources=6 fixtures=fixtures/functions-default-sa-iam-grants.tf e2e ``` @@ -156,6 +171,9 @@ module "cf-http" { path = "assets/sample-function/" } service_account = var.service_account.email + depends_on = [ + google_project_iam_member.bucket_default_compute_account_grant, + ] } # tftest modules=1 resources=5 fixtures=fixtures/functions-default-sa-iam-grants.tf e2e ``` @@ -184,6 +202,9 @@ module "cf-http" { excludes = ["__pycache__"] } } + depends_on = [ + google_project_iam_member.bucket_default_compute_account_grant, + ] } # tftest modules=1 resources=5 fixtures=fixtures/functions-default-sa-iam-grants.tf e2e ``` @@ -203,6 +224,9 @@ module "cf-http" { bundle_config = { path = "assets/sample-function/" } + depends_on = [ + google_project_iam_member.bucket_default_compute_account_grant, + ] } # tftest modules=1 resources=6 fixtures=fixtures/functions-default-sa-iam-grants.tf,fixtures/cloudbuild-custom-pool.tf e2e ``` @@ -232,8 +256,11 @@ module "cf-http-two" { bundle_config = { path = "assets/sample-function/" } + depends_on = [ + google_project_iam_member.bucket_default_compute_account_grant, + ] } -# tftest modules=2 resources=7 fixtures=fixtures/functions-default-sa-iam-grants.tf inventory=multiple_functions.yaml e2e +# tftest fixtures=fixtures/functions-default-sa-iam-grants.tf inventory=multiple_functions.yaml e2e ``` ### Mounting secrets from Secret Manager @@ -270,9 +297,12 @@ module "cf-http" { ] } } + depends_on = [ + google_project_iam_member.bucket_default_compute_account_grant, + ] } -# tftest modules=2 resources=8 fixtures=fixtures/secret-credentials.tf,fixtures/functions-default-sa-iam-grants.tf inventory=secrets.yaml e2e +# tftest fixtures=fixtures/secret-credentials.tf,fixtures/functions-default-sa-iam-grants.tf inventory=secrets.yaml e2e ``` ## Variables diff --git a/modules/cloud-run-v2/README.md b/modules/cloud-run-v2/README.md index 533bbb800b..3087171db1 100644 --- a/modules/cloud-run-v2/README.md +++ b/modules/cloud-run-v2/README.md @@ -189,19 +189,49 @@ module "cloud_run" { Deploy a Cloud Run service with environment variables encrypted using a Customer-Managed Encryption Key (CMEK). Ensure you specify the encryption_key with the full resource identifier of your Cloud KMS CryptoKey and that Cloud Run Service agent (`service-@serverless-robot-prod.iam.gserviceaccount.com`) has permission to use the key, for example `roles/cloudkms.cryptoKeyEncrypterDecrypter` IAM role. This setup adds an extra layer of security by utilizing your own encryption keys. ```hcl +module "project" { + source = "./fabric/modules/project" + name = "cloudrun" + billing_account = var.billing_account_id + prefix = var.prefix + parent = var.folder_id + services = [ + "cloudkms.googleapis.com", + "run.googleapis.com", + ] +} + +module "kms" { + source = "./fabric/modules/kms" + project_id = module.project.project_id + keyring = { + location = var.region + name = "keyring" + } + keys = { + "key-regional" = { + } + } + iam = { + "roles/cloudkms.cryptoKeyEncrypterDecrypter" = [ + module.project.service_agents.run.iam_email + ] + } +} + module "cloud_run" { source = "./fabric/modules/cloud-run-v2" - project_id = var.project_id + project_id = module.project.project_id region = var.region name = "hello" - encryption_key = var.kms_key.id + encryption_key = module.kms.keys.key-regional.id containers = { hello = { image = "us-docker.pkg.dev/cloudrun/container/hello" } } } -# tftest modules=1 resources=2 fixtures=fixtures/cloud-run-kms-iam-grant.tf e2e +# tftest modules=3 resources=11 e2e ``` ## Eventarc triggers @@ -471,7 +501,6 @@ module "cloud_run" { ## Fixtures -- [cloud-run-kms-iam-grant.tf](../../tests/fixtures/cloud-run-kms-iam-grant.tf) - [iam-service-account.tf](../../tests/fixtures/iam-service-account.tf) - [pubsub.tf](../../tests/fixtures/pubsub.tf) - [secret-credentials.tf](../../tests/fixtures/secret-credentials.tf) diff --git a/modules/cloudsql-instance/README.md b/modules/cloudsql-instance/README.md index 79d9a5ad02..bc46432b10 100644 --- a/modules/cloudsql-instance/README.md +++ b/modules/cloudsql-instance/README.md @@ -19,7 +19,6 @@ Note that this module assumes that some options are the same for both the primar - [SSL Config](#ssl-config) - [Variables](#variables) - [Outputs](#outputs) -- [Fixtures](#fixtures) ## Examples @@ -154,14 +153,63 @@ module "db" { ### CMEK encryption ```hcl +module "project" { + source = "./fabric/modules/project" + name = "cloudsql" + billing_account = var.billing_account_id + prefix = var.prefix + parent = var.folder_id + services = [ + "cloudkms.googleapis.com", + "servicenetworking.googleapis.com", + "sqladmin.googleapis.com", + ] +} + +module "kms" { + source = "./fabric/modules/kms" + project_id = module.project.project_id + keyring = { + location = var.region + name = "keyring" + } + keys = { + "key-regional" = { + } + } + iam = { + "roles/cloudkms.cryptoKeyEncrypterDecrypter" = [ + module.project.service_agents["cloud-sql"].iam_email + ] + } +} + +module "vpc" { + source = "./fabric/modules/net-vpc" + project_id = module.project.project_id + name = "my-network" + subnets = [ + { + ip_cidr_range = "10.0.0.0/24" + name = "production" + region = var.region + }, + ] + psa_configs = [{ + ranges = { myrange = "10.0.1.0/24" } + deletion_policy = "ABANDON" + }] +} + + module "db" { source = "./fabric/modules/cloudsql-instance" - project_id = var.project_id - encryption_key_name = var.kms_key.id + project_id = module.project.project_id + encryption_key_name = module.kms.keys.key-regional.id network_config = { connectivity = { psa_config = { - private_network = var.vpc.self_link + private_network = module.vpc.self_link } } } @@ -171,12 +219,9 @@ module "db" { tier = "db-g1-small" gcp_deletion_protection = false terraform_deletion_protection = false - depends_on = [ - google_kms_crypto_key_iam_binding.encrypt_decrypt - ] } -# tftest modules=1 resources=2 fixtures=fixtures/cloudsql-kms-iam-grant.tf e2e +# tftest modules=4 resources=21 e2e ``` ### Instance with PSC enabled @@ -368,8 +413,4 @@ module "db" { | [self_link](outputs.tf#L114) | Self link of the primary instance. | | | [self_links](outputs.tf#L119) | Self links of all instances. | | | [user_passwords](outputs.tf#L127) | Map of containing the password of all users created through terraform. | ✓ | - -## Fixtures - -- [cloudsql-kms-iam-grant.tf](../../tests/fixtures/cloudsql-kms-iam-grant.tf) diff --git a/modules/compute-vm/README.md b/modules/compute-vm/README.md index 36a241f175..4d6cb66225 100644 --- a/modules/compute-vm/README.md +++ b/modules/compute-vm/README.md @@ -535,14 +535,57 @@ module "template-confidential-example" { This example shows how to control disk encryption via the the `encryption` variable, in this case the self link to a KMS CryptoKey that will be used to encrypt boot and attached disk. Managing the key with the `../kms` module is of course possible, but is not shown here. ```hcl +module "project" { + source = "./fabric/modules/project" + name = "gce" + billing_account = var.billing_account_id + prefix = var.prefix + parent = var.folder_id + services = [ + "cloudkms.googleapis.com", + "compute.googleapis.com", + ] +} + +module "kms" { + source = "./fabric/modules/kms" + project_id = module.project.project_id + keyring = { + location = var.region + name = "keyring" + } + keys = { + "key-regional" = { + } + } + iam = { + "roles/cloudkms.cryptoKeyEncrypterDecrypter" = [ + module.project.service_agents.compute.iam_email + ] + } +} + +module "vpc" { + source = "./fabric/modules/net-vpc" + project_id = module.project.project_id + name = "my-network" + subnets = [ + { + ip_cidr_range = "10.0.0.0/24" + name = "production" + region = var.region + }, + ] +} + module "kms-vm-example" { source = "./fabric/modules/compute-vm" - project_id = var.project_id - zone = "europe-west1-b" + project_id = module.project.project_id + zone = "${var.region}-b" name = "kms-test" network_interfaces = [{ - network = var.vpc.self_link - subnetwork = var.subnet.self_link + network = module.vpc.self_link + subnetwork = module.vpc.subnet_self_links["${var.region}/production"] }] attached_disks = [{ name = "attached-disk" @@ -553,10 +596,10 @@ module "kms-vm-example" { } encryption = { encrypt_boot = true - kms_key_self_link = var.kms_key.id + kms_key_self_link = module.kms.keys.key-regional.id } } -# tftest modules=1 resources=3 inventory=cmek.yaml +# tftest inventory=cmek.yaml e2e ``` ### Instance template diff --git a/modules/dataproc/README.md b/modules/dataproc/README.md index 2ae54a2346..ff54fc6da3 100644 --- a/modules/dataproc/README.md +++ b/modules/dataproc/README.md @@ -91,19 +91,66 @@ module "processing-dp-cluster" { To set cluster configuration use the Customer Managed Encryption key, set `dataproc_config.encryption_config.` variable. The Compute Engine service agent and the Cloud Storage service agent need to have `CryptoKey Encrypter/Decrypter` role on they configured KMS key ([Documentation](https://cloud.google.com/dataproc/docs/concepts/configuring-clusters/customer-managed-encryption)). ```hcl +module "project" { + source = "./fabric/modules/project" + name = "dataproc" + billing_account = var.billing_account_id + prefix = var.prefix + parent = var.folder_id + services = [ + "cloudkms.googleapis.com", + "dataproc.googleapis.com", + "servicenetworking.googleapis.com", + ] +} + +module "kms" { + source = "./fabric/modules/kms" + project_id = module.project.project_id + keyring = { + location = var.region + name = "keyring" + } + keys = { + "key-regional" = { + } + } + iam = { + "roles/cloudkms.cryptoKeyEncrypterDecrypter" = [ + module.project.service_agents.dataproc.iam_email + ] + } +} + +module "vpc" { + source = "./fabric/modules/net-vpc" + project_id = module.project.project_id + name = "my-network" + subnets = [ + { + ip_cidr_range = "10.0.0.0/24" + name = "production" + region = var.region + }, + ] + psa_configs = [{ + ranges = { myrange = "10.0.1.0/24" } + }] +} + module "dataproc-service-account" { source = "./fabric/modules/iam-service-account" - project_id = var.project_id + project_id = module.project.project_id name = "dataproc-worker" iam_project_roles = { - (var.project_id) = ["roles/dataproc.worker", "roles/cloudkms.cryptoKeyEncrypterDecrypter"] + (module.project.project_id) = ["roles/dataproc.worker", "roles/cloudkms.cryptoKeyEncrypterDecrypter"] } } module "firewall" { source = "./fabric/modules/net-vpc-firewall" - project_id = var.project_id - network = var.vpc.name + project_id = module.project.project_id + network = module.vpc.name ingress_rules = { allow-ingress-dataproc = { description = "Allow all traffic between Dataproc nodes." @@ -115,7 +162,7 @@ module "firewall" { module "processing-dp-cluster" { source = "./fabric/modules/dataproc" - project_id = var.project_id + project_id = module.project.project_id name = "my-cluster" region = var.region dataproc_config = { @@ -124,20 +171,17 @@ module "processing-dp-cluster" { internal_ip_only = true service_account = module.dataproc-service-account.email service_account_scopes = ["cloud-platform"] - subnetwork = var.subnet.self_link + subnetwork = module.vpc.subnet_self_links["${var.region}/production"] tags = ["dataproc"] zone = "${var.region}-b" } } encryption_config = { - kms_key_name = var.kms_key.id + kms_key_name = module.kms.keys.key-regional.id } } - depends_on = [ - module.dataproc-service-account, # ensure all grants are done before creating the cluster - ] } -# tftest modules=3 resources=8 e2e +# tftest modules=6 resources=28 e2e ``` ### Cluster configuration on GKE diff --git a/modules/gcs/README.md b/modules/gcs/README.md index ae9ebc487e..12a71ebf7b 100644 --- a/modules/gcs/README.md +++ b/modules/gcs/README.md @@ -346,9 +346,9 @@ module "bucket" { |---|---|:---:| | [bucket](outputs.tf#L17) | Bucket resource. | | | [id](outputs.tf#L28) | Fully qualified bucket id. | | -| [name](outputs.tf#L37) | Bucket name. | | -| [notification](outputs.tf#L46) | GCS Notification self link. | | -| [objects](outputs.tf#L51) | Objects in GCS bucket. | | -| [topic](outputs.tf#L63) | Topic ID used by GCS. | | -| [url](outputs.tf#L68) | Bucket URL. | | +| [name](outputs.tf#L39) | Bucket name. | | +| [notification](outputs.tf#L50) | GCS Notification self link. | | +| [objects](outputs.tf#L55) | Objects in GCS bucket. | | +| [topic](outputs.tf#L67) | Topic ID used by GCS. | | +| [url](outputs.tf#L72) | Bucket URL. | | diff --git a/modules/kms/README.md b/modules/kms/README.md index 5772fcacb9..5073314ff0 100644 --- a/modules/kms/README.md +++ b/modules/kms/README.md @@ -71,7 +71,7 @@ module "kms" { keyring_create = false keys = { key-a = {}, key-b = {}, key-c = {} } } -# tftest skip (uses data sources) e2e +# tftest skip (uses data sources) ``` ### Crypto key purpose @@ -149,7 +149,6 @@ module "kms" { } # tftest modules=2 resources=6 ``` - ## Variables @@ -170,10 +169,10 @@ module "kms" { | name | description | sensitive | |---|---|:---:| | [id](outputs.tf#L17) | Fully qualified keyring id. | | -| [import_job](outputs.tf#L26) | Keyring import job resources. | | -| [key_ids](outputs.tf#L35) | Fully qualified key ids. | | -| [keyring](outputs.tf#L47) | Keyring resource. | | -| [keys](outputs.tf#L56) | Key resources. | | -| [location](outputs.tf#L65) | Keyring location. | | -| [name](outputs.tf#L74) | Keyring name. | | +| [import_job](outputs.tf#L30) | Keyring import job resources. | | +| [key_ids](outputs.tf#L43) | Fully qualified key ids. | | +| [keyring](outputs.tf#L56) | Keyring resource. | | +| [keys](outputs.tf#L69) | Key resources. | | +| [location](outputs.tf#L82) | Keyring location. | | +| [name](outputs.tf#L95) | Keyring name. | | diff --git a/modules/net-vpc/README.md b/modules/net-vpc/README.md index 2214d9f7f1..98865d9de8 100644 --- a/modules/net-vpc/README.md +++ b/modules/net-vpc/README.md @@ -252,7 +252,7 @@ module "vpc" { ranges = { myrange = "10.0.1.0/24" } }] } -# tftest modules=1 resources=7 inventory=psa.yaml e2e +# tftest inventory=psa.yaml e2e ``` The module prefixes the PSA service to address range names, to disable this behaviour just set the `range_prefix` attribute in the PSA configuration: @@ -274,7 +274,7 @@ module "vpc" { range_prefix = "" }] } -# tftest modules=1 resources=7 inventory=psa-prefix.yaml e2e +# tftest inventory=psa-prefix.yaml e2e ``` Each PSA service can set a different prefix. Ranges will be allocated to the service they are defined in, as in the following example: @@ -293,24 +293,18 @@ module "vpc" { ] psa_configs = [ { - ranges = { myrange = "10.0.1.0/24" } - range_prefix = "" + ranges = { myrange = "10.0.1.0/24" } + range_prefix = "" + deletion_policy = "ABANDON" }, { ranges = { netapp = "10.0.2.0/24" } service_producer = "netapp.servicenetworking.goog" range_prefix = "" - }, - { - ranges = { - example = "10.0.3.0/24", - example2 = "10.0.4.0/24" - } - service_producer = "example.servicenetworking.goog" } ] } -# tftest modules=1 resources=14 inventory=psa-prefix-services.yaml e2e +# tftest inventory=psa-prefix-services.yaml e2e ``` ### Private Service Networking with peering routes and peered Cloud DNS domains @@ -494,7 +488,7 @@ module "vpc" { ```yaml name: simple -region: primary +region: primary ip_cidr_range: 10.0.1.0/24 # tftest-file id=subnet-simple path=config/subnets/subnet-simple.yaml schema=subnet.schema.json diff --git a/modules/project/README.md b/modules/project/README.md index 260480627c..04aa70bf2d 100644 --- a/modules/project/README.md +++ b/modules/project/README.md @@ -737,11 +737,31 @@ module "project" { "storage.googleapis.com" ] service_encryption_key_ids = { - "compute.googleapis.com" = [var.kms_key.id] - "storage.googleapis.com" = [var.kms_key.id] + "compute.googleapis.com" = [module.kms.keys.key-regional.id] + "storage.googleapis.com" = [module.kms.keys.key-regional.id] } } -# tftest modules=1 resources=7 e2e + +module "kms" { + source = "./fabric/modules/kms" + project_id = var.project_id # KMS is in different project to prevent dependency cycle + keyring = { + location = var.region + name = "keyring" + } + keys = { + "key-regional" = { + } + } + iam = { + "roles/cloudkms.cryptoKeyEncrypterDecrypter" = [ + module.project.service_agents.compute.iam_email, + module.project.service_agents.storage.iam_email, + ] + } +} + +# tftest modules=2 resources=10 e2e ``` ## Tags @@ -1274,8 +1294,27 @@ module "project" { "storage.googleapis.com", ] service_encryption_key_ids = { - "compute.googleapis.com" = [var.kms_key.id] - "storage.googleapis.com" = [var.kms_key.id] + "compute.googleapis.com" = [module.kms.keys.key-global.id] + "storage.googleapis.com" = [module.kms.keys.key-global.id] + } +} + +module "kms" { + source = "./fabric/modules/kms" + project_id = var.project_id # Keys come from different project to prevent dependency cycle + keyring = { + location = "global" + name = "keyring" + } + keys = { + "key-global" = { + } + } + iam = { + "roles/cloudkms.cryptoKeyEncrypterDecrypter" = [ + module.project.service_agents.compute.iam_email, + module.project.service_agents.storage.iam_email + ] } } @@ -1318,7 +1357,7 @@ module "bucket" { parent = var.project_id id = "${var.prefix}-bucket" } -# tftest modules=7 resources=61 inventory=data.yaml e2e +# tftest inventory=data.yaml e2e ``` diff --git a/modules/pubsub/README.md b/modules/pubsub/README.md index e9a8e9e177..ca51e1676f 100644 --- a/modules/pubsub/README.md +++ b/modules/pubsub/README.md @@ -181,11 +181,11 @@ module "pubsub" { | name | description | sensitive | |---|---|:---:| | [id](outputs.tf#L17) | Fully qualified topic id. | | -| [schema](outputs.tf#L27) | Schema resource. | | -| [schema_id](outputs.tf#L32) | Schema resource id. | | -| [subscription_id](outputs.tf#L37) | Subscription ids. | | -| [subscriptions](outputs.tf#L48) | Subscription resources. | | -| [topic](outputs.tf#L57) | Topic resource. | | +| [schema](outputs.tf#L28) | Schema resource. | | +| [schema_id](outputs.tf#L33) | Schema resource id. | | +| [subscription_id](outputs.tf#L38) | Subscription ids. | | +| [subscriptions](outputs.tf#L50) | Subscription resources. | | +| [topic](outputs.tf#L60) | Topic resource. | | ## Fixtures diff --git a/modules/secret-manager/README.md b/modules/secret-manager/README.md index 32e6b305a2..b547f476ab 100644 --- a/modules/secret-manager/README.md +++ b/modules/secret-manager/README.md @@ -84,26 +84,94 @@ module "secret-manager" { CMEK will be used if an encryption key is set in the `keys` field of `secrets` object for the secret region. For secrets with auto-replication, a global key must be specified. ```hcl +module "project" { + source = "./fabric/modules/project" + name = "sec-mgr" + billing_account = var.billing_account_id + prefix = var.prefix + parent = var.folder_id + services = [ + "cloudkms.googleapis.com", + "secretmanager.googleapis.com", + ] +} + +module "kms-global" { + source = "./fabric/modules/kms" + project_id = module.project.project_id + keyring = { + location = "global" + name = "keyring-global" + } + keys = { + "key-global" = { + } + } + iam = { + "roles/cloudkms.cryptoKeyEncrypterDecrypter" = [ + module.project.service_agents.secretmanager.iam_email + ] + } +} + + +module "kms-primary-region" { + source = "./fabric/modules/kms" + project_id = module.project.project_id + keyring = { + location = var.regions.primary + name = "keyring-regional" + } + keys = { + "key-regional" = { + } + } + iam = { + "roles/cloudkms.cryptoKeyEncrypterDecrypter" = [ + module.project.service_agents.secretmanager.iam_email + ] + } +} + +module "kms-secondary-region" { + source = "./fabric/modules/kms" + project_id = module.project.project_id + keyring = { + location = var.regions.secondary + name = "keyring-regional" + } + keys = { + "key-regional" = { + } + } + iam = { + "roles/cloudkms.cryptoKeyEncrypterDecrypter" = [ + module.project.service_agents.secretmanager.iam_email + ] + } +} + + module "secret-manager" { source = "./fabric/modules/secret-manager" - project_id = var.project_id + project_id = module.project.project_id secrets = { test-auto = { keys = { - global = module.kms_global.keys.key-gl.id + global = module.kms-global.keys.key-global.id } } test-auto-nokeys = {} test-manual = { locations = [var.regions.primary, var.regions.secondary] keys = { - "${var.regions.primary}" = module.kms_regional_primary.keys.key-a.id - "${var.regions.secondary}" = module.kms_regional_secondary.keys.key-b.id + "${var.regions.primary}" = module.kms-primary-region.keys.key-regional.id + "${var.regions.secondary}" = module.kms-secondary-region.keys.key-regional.id } } } } -# tftest modules=4 resources=11 fixtures=fixtures/kms-global-regional-keys.tf inventory=secret-cmek.yaml e2e +# tftest inventory=secret-cmek.yaml e2e ``` ## Variables @@ -122,14 +190,10 @@ module "secret-manager" { | name | description | sensitive | |---|---|:---:| | [ids](outputs.tf#L17) | Fully qualified secret ids. | | -| [secrets](outputs.tf#L24) | Secret resources. | | -| [version_ids](outputs.tf#L29) | Version ids keyed by secret name : version name. | | -| [version_versions](outputs.tf#L36) | Version versions keyed by secret name : version name. | | -| [versions](outputs.tf#L43) | Secret versions. | ✓ | - -## Fixtures - -- [kms-global-regional-keys.tf](../../tests/fixtures/kms-global-regional-keys.tf) +| [secrets](outputs.tf#L27) | Secret resources. | | +| [version_ids](outputs.tf#L36) | Version ids keyed by secret name : version name. | | +| [version_versions](outputs.tf#L46) | Version versions keyed by secret name : version name. | | +| [versions](outputs.tf#L56) | Secret versions. | ✓ | ## Requirements diff --git a/tests/examples/variables.tf b/tests/examples/variables.tf index e4894dc810..80f76c2348 100644 --- a/tests/examples/variables.tf +++ b/tests/examples/variables.tf @@ -30,18 +30,6 @@ variable "group_email" { default = "organization-admins@example.org" } -variable "keyring" { - default = { - name = "keyring" - } -} - -variable "kms_key" { - default = { - id = "kms_key_self_link" - } -} - variable "organization_id" { default = "organizations/1122334455" } diff --git a/tests/examples_e2e/setup_module/e2e_tests.tfvars.tftpl b/tests/examples_e2e/setup_module/e2e_tests.tfvars.tftpl index 14e05ddf4b..99cb2934ee 100644 --- a/tests/examples_e2e/setup_module/e2e_tests.tfvars.tftpl +++ b/tests/examples_e2e/setup_module/e2e_tests.tfvars.tftpl @@ -14,12 +14,6 @@ bucket = "${bucket}" billing_account_id = "${billing_account_id}" -kms_key = { - id = "${kms_key_id}" -} -keyring = { - name = "${keyring.name}" -} group_email = "${group_email}" organization_id = "organizations/${organization_id}" folder_id = "folders/${folder_id}" diff --git a/tests/examples_e2e/setup_module/main.tf b/tests/examples_e2e/setup_module/main.tf index 85b7ad2764..6dcaaee088 100644 --- a/tests/examples_e2e/setup_module/main.tf +++ b/tests/examples_e2e/setup_module/main.tf @@ -218,19 +218,6 @@ resource "google_service_account" "service_account" { depends_on = [google_project_service.project_service] } -resource "google_kms_key_ring" "keyring" { - name = "keyring" - project = google_project.project.project_id - location = var.region - depends_on = [google_project_service.project_service] -} - -resource "google_kms_crypto_key" "key" { - name = "crypto-key-example" - key_ring = google_kms_key_ring.keyring.id - rotation_period = "100000s" -} - resource "google_project_service_identity" "jit_si" { for_each = toset(local.jit_services) provider = google-beta @@ -267,14 +254,10 @@ resource "local_file" "terraform_tfvars" { billing_account_id = var.billing_account folder_id = google_folder.folder.folder_id group_email = var.group_email - keyring = { - name = google_kms_key_ring.keyring.name - } - kms_key_id = google_kms_crypto_key.key.id - organization_id = var.organization_id - project_id = google_project.project.project_id - project_number = google_project.project.number - region = var.region + organization_id = var.organization_id + project_id = google_project.project.project_id + project_number = google_project.project.number + region = var.region regions = { primary = var.region secondary = var.region_secondary diff --git a/tests/fixtures/functions-default-sa-iam-grants.tf b/tests/fixtures/functions-default-sa-iam-grants.tf index 784a5ef264..b3a55e23c8 100644 --- a/tests/fixtures/functions-default-sa-iam-grants.tf +++ b/tests/fixtures/functions-default-sa-iam-grants.tf @@ -21,12 +21,6 @@ resource "google_project_iam_member" "bucket_default_compute_account_grant" { depends_on = [google_project_iam_member.artifact_writer] } -resource "google_project_iam_member" "debugging_grant" { - project = var.project_id - member = "serviceAccount:${var.project_number}-compute@developer.gserviceaccount.com" - role = "roles/logging.logWriter" -} - resource "google_project_iam_member" "artifact_writer" { project = var.project_id member = "serviceAccount:${var.project_number}-compute@developer.gserviceaccount.com" diff --git a/tests/fixtures/kms-global-regional-keys.tf b/tests/fixtures/kms-global-regional-keys.tf index c7b85f6083..a437e9c6e8 100644 --- a/tests/fixtures/kms-global-regional-keys.tf +++ b/tests/fixtures/kms-global-regional-keys.tf @@ -12,18 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -resource "google_project_service_identity" "secretmanager" { - provider = google-beta - project = var.project_id - service = "secretmanager.googleapis.com" -} - -resource "google_project_iam_binding" "bindings" { - project = var.project_id - role = "roles/cloudkms.cryptoKeyEncrypterDecrypter" - members = ["serviceAccount:${resource.google_project_service_identity.secretmanager.email}"] -} - module "kms_regional_primary" { source = "./fabric/modules/kms" project_id = var.project_id @@ -35,7 +23,14 @@ module "kms_regional_primary" { "key-a" = { } } - depends_on = [google_project_iam_binding.bindings] + iam = { + "roles/cloudkms.cryptoKeyEncrypterDecrypter" = [ + "serviceAccount:service-${var.project_number}@gcp-sa-secretmanager.iam.gserviceaccount.com", + "serviceAccount:service-${var.project_number}@gcp-sa-alloydb.iam.gserviceaccount.com", + "serviceAccount:service-${var.project_number}@serverless-robot-prod.iam.gserviceaccount.com", + "serviceAccount:service-${var.project_number}@gcp-sa-cloud-sql.iam.gserviceaccount.com", + ] + } } module "kms_regional_secondary" { @@ -49,7 +44,14 @@ module "kms_regional_secondary" { "key-b" = { } } - depends_on = [google_project_iam_binding.bindings] + iam = { + "roles/cloudkms.cryptoKeyEncrypterDecrypter" = [ + "serviceAccount:service-${var.project_number}@gcp-sa-secretmanager.iam.gserviceaccount.com", + "serviceAccount:service-${var.project_number}@gcp-sa-alloydb.iam.gserviceaccount.com", + "serviceAccount:service-${var.project_number}@serverless-robot-prod.iam.gserviceaccount.com", + "serviceAccount:service-${var.project_number}@gcp-sa-cloud-sql.iam.gserviceaccount.com", + ] + } } module "kms_global" { @@ -60,8 +62,15 @@ module "kms_global" { name = "keyring-gl" } keys = { - "key-gl" = { + "key-global" = { } } - depends_on = [google_project_iam_binding.bindings] -} \ No newline at end of file + iam = { + "roles/cloudkms.cryptoKeyEncrypterDecrypter" = [ + "serviceAccount:service-${var.project_number}@gcp-sa-secretmanager.iam.gserviceaccount.com", + "serviceAccount:service-${var.project_number}@gcp-sa-alloydb.iam.gserviceaccount.com", + "serviceAccount:service-${var.project_number}@serverless-robot-prod.iam.gserviceaccount.com", + "serviceAccount:service-${var.project_number}@gcp-sa-cloud-sql.iam.gserviceaccount.com", + ] + } +} diff --git a/tests/modules/alloydb/examples/cmek.yaml b/tests/modules/alloydb/examples/cmek.yaml index 799c2f1bdd..a893a6b704 100644 --- a/tests/modules/alloydb/examples/cmek.yaml +++ b/tests/modules/alloydb/examples/cmek.yaml @@ -19,14 +19,10 @@ values: cluster_type: PRIMARY continuous_backup_config: - enabled: true - encryption_config: - - kms_key_name: kms_key_self_link recovery_window_days: 14 database_version: POSTGRES_15 deletion_policy: DEFAULT display_name: primary - encryption_config: - - kms_key_name: kms_key_self_link etag: null initial_user: [] labels: null @@ -34,8 +30,7 @@ values: maintenance_update_policy: [] network_config: - allocated_ip_range: null - network: projects/xxx/global/networks/aaa - project: project-id + project: test-alloycmek restore_backup_source: [] restore_continuous_backup_source: [] secondary_config: [] @@ -64,7 +59,5 @@ values: counts: google_alloydb_cluster: 1 google_alloydb_instance: 1 - modules: 1 - resources: 3 outputs: {} diff --git a/tests/modules/cloud_function_v1/examples/bucket-creation.yaml b/tests/modules/cloud_function_v1/examples/bucket-creation.yaml index 9d08d9ae60..964682337e 100644 --- a/tests/modules/cloud_function_v1/examples/bucket-creation.yaml +++ b/tests/modules/cloud_function_v1/examples/bucket-creation.yaml @@ -33,4 +33,4 @@ counts: modules: 1 resources: 6 -outputs: {} +outputs: {} diff --git a/tests/modules/cloud_function_v2/examples/bucket-creation.yaml b/tests/modules/cloud_function_v2/examples/bucket-creation.yaml index 1e74e9575c..99cb104e33 100644 --- a/tests/modules/cloud_function_v2/examples/bucket-creation.yaml +++ b/tests/modules/cloud_function_v2/examples/bucket-creation.yaml @@ -38,4 +38,4 @@ counts: modules: 1 resources: 6 -outputs: {} +outputs: {} diff --git a/tests/modules/cloud_function_v2/examples/iam.yaml b/tests/modules/cloud_function_v2/examples/iam.yaml index 2720c26783..c96dbdb34d 100644 --- a/tests/modules/cloud_function_v2/examples/iam.yaml +++ b/tests/modules/cloud_function_v2/examples/iam.yaml @@ -26,7 +26,6 @@ values: bucket: bucket customer_encryption: [] detect_md5hash: different hash - name: bundle-95c1b0e5b92dae8333539b1e0ad5173b.zip source: /tmp/bundle-project-id-test-cf-http.zip counts: diff --git a/tests/modules/compute_vm/examples/cmek.yaml b/tests/modules/compute_vm/examples/cmek.yaml index cbd443c4fa..27b8238b54 100644 --- a/tests/modules/compute_vm/examples/cmek.yaml +++ b/tests/modules/compute_vm/examples/cmek.yaml @@ -15,18 +15,20 @@ values: module.kms-vm-example.google_compute_disk.disks["attached-disk"]: disk_encryption_key: - - kms_key_self_link: kms_key_self_link - kms_key_service_account: null + - kms_key_service_account: null raw_key: null rsa_encrypted_key: null labels: disk_name: attached-disk disk_type: pd-balanced name: kms-test-attached-disk - project: project-id + project: test-gce size: 10 + source_image_encryption_key: [] + source_snapshot_encryption_key: [] + storage_pool: null type: pd-balanced - zone: europe-west1-b + zone: europe-west8-b module.kms-vm-example.google_compute_instance.default[0]: attached_disk: - device_name: attached-disk @@ -41,16 +43,15 @@ values: resource_manager_tags: size: 10 type: pd-balanced - kms_key_self_link: kms_key_self_link mode: READ_WRITE name: kms-test - zone: europe-west1-b + zone: europe-west8-b module.kms-vm-example.google_service_account.service_account[0]: account_id: tf-vm-kms-test description: null disabled: false display_name: Terraform VM kms-test. - project: project-id + project: test-gce timeouts: null counts: diff --git a/tests/modules/net_vpc/examples/psa-prefix-services.yaml b/tests/modules/net_vpc/examples/psa-prefix-services.yaml index 6da9cdffc1..72c8524349 100644 --- a/tests/modules/net_vpc/examples/psa-prefix-services.yaml +++ b/tests/modules/net_vpc/examples/psa-prefix-services.yaml @@ -13,28 +13,6 @@ # limitations under the License. values: - module.vpc.google_compute_global_address.psa_ranges["example-servicenetworking-goog-example"]: - address: 10.0.3.0 - address_type: INTERNAL - description: null - ip_version: null - labels: null - name: example-servicenetworking-goog-example - prefix_length: 24 - project: project-id - purpose: VPC_PEERING - timeouts: null - module.vpc.google_compute_global_address.psa_ranges["example-servicenetworking-goog-example2"]: - address: 10.0.4.0 - address_type: INTERNAL - description: null - ip_version: null - labels: null - name: example-servicenetworking-goog-example2 - prefix_length: 24 - project: project-id - purpose: VPC_PEERING - timeouts: null module.vpc.google_compute_global_address.psa_ranges["myrange"]: address: 10.0.1.0 address_type: INTERNAL @@ -67,12 +45,6 @@ values: project: project-id routing_mode: GLOBAL timeouts: null - module.vpc.google_compute_network_peering_routes_config.psa_routes["example.servicenetworking.goog"]: - export_custom_routes: false - import_custom_routes: false - network: my-network - project: project-id - timeouts: null module.vpc.google_compute_network_peering_routes_config.psa_routes["netapp.servicenetworking.goog"]: export_custom_routes: false import_custom_routes: false @@ -124,14 +96,6 @@ values: role: null send_secondary_ip_range_if_empty: true timeouts: null - module.vpc.google_service_networking_connection.psa_connection["example.servicenetworking.goog"]: - deletion_policy: null - reserved_peering_ranges: - - example-servicenetworking-goog-example - - example-servicenetworking-goog-example2 - service: example.servicenetworking.goog - timeouts: null - update_on_creation_fail: null module.vpc.google_service_networking_connection.psa_connection["netapp.servicenetworking.goog"]: deletion_policy: null reserved_peering_ranges: @@ -140,7 +104,7 @@ values: timeouts: null update_on_creation_fail: null module.vpc.google_service_networking_connection.psa_connection["servicenetworking.googleapis.com"]: - deletion_policy: null + deletion_policy: ABANDON reserved_peering_ranges: - myrange service: servicenetworking.googleapis.com @@ -148,13 +112,13 @@ values: update_on_creation_fail: null counts: - google_compute_global_address: 4 + google_compute_global_address: 2 google_compute_network: 1 - google_compute_network_peering_routes_config: 3 + google_compute_network_peering_routes_config: 2 google_compute_route: 2 google_compute_subnetwork: 1 - google_service_networking_connection: 3 + google_service_networking_connection: 2 modules: 1 - resources: 14 + resources: 10 outputs: {} diff --git a/tests/modules/project/examples/data.yaml b/tests/modules/project/examples/data.yaml index f7cca9f073..c84008230a 100644 --- a/tests/modules/project/examples/data.yaml +++ b/tests/modules/project/examples/data.yaml @@ -25,7 +25,7 @@ values: module.create-project.google_project.project[0]: auto_create_network: false billing_account: 123456-123456-123456 - deletion_policy: 'DELETE' + deletion_policy: DELETE folder_id: '1122334455' labels: null name: test-project @@ -45,6 +45,7 @@ values: location: EU max_time_travel_hours: '168' project: project-id + resource_tags: null timeouts: null module.gcs.google_storage_bucket.bucket: autoclass: [] @@ -71,13 +72,28 @@ values: module.host-project.google_project.project[0]: auto_create_network: false billing_account: 123456-123456-123456 - deletion_policy: 'DELETE' + deletion_policy: DELETE folder_id: '1122334455' labels: null name: test-host org_id: null project_id: test-host timeouts: null + module.kms.google_kms_crypto_key.default["key-global"]: + labels: null + name: key-global + purpose: ENCRYPT_DECRYPT + rotation_period: null + skip_initial_version_creation: false + timeouts: null + module.kms.google_kms_key_ring.default[0]: + location: global + name: keyring + project: project-id + timeouts: null + module.kms.google_kms_key_ring_iam_binding.authoritative["roles/cloudkms.cryptoKeyEncrypterDecrypter"]: + condition: [] + role: roles/cloudkms.cryptoKeyEncrypterDecrypter module.project.data.google_bigquery_default_service_account.bq_sa[0]: project: test-project module.project.data.google_project.project[0]: @@ -93,13 +109,11 @@ values: host_project: test-host service_project: test-project timeouts: null - module.project.google_kms_crypto_key_iam_member.service_agent_cmek["kms_key_self_link.compute-system"]: + module.project.google_kms_crypto_key_iam_member.service_agent_cmek["key-0.compute-system"]: condition: [] - crypto_key_id: kms_key_self_link role: roles/cloudkms.cryptoKeyEncrypterDecrypter - module.project.google_kms_crypto_key_iam_member.service_agent_cmek["kms_key_self_link.gs-project-accounts"]: + module.project.google_kms_crypto_key_iam_member.service_agent_cmek["key-0.gs-project-accounts"]: condition: [] - crypto_key_id: kms_key_self_link role: roles/cloudkms.cryptoKeyEncrypterDecrypter module.project.google_logging_project_exclusion.logging-exclusion["no-gce-instances"]: description: no-gce-instances (Terraform-managed). @@ -457,7 +471,10 @@ counts: google_bigquery_default_service_account: 1 google_compute_shared_vpc_host_project: 1 google_compute_shared_vpc_service_project: 1 + google_kms_crypto_key: 1 google_kms_crypto_key_iam_member: 2 + google_kms_key_ring: 1 + google_kms_key_ring_iam_binding: 1 google_logging_project_bucket_config: 1 google_logging_project_exclusion: 1 google_logging_project_sink: 4 @@ -473,7 +490,8 @@ counts: google_storage_bucket: 1 google_storage_bucket_iam_member: 1 google_storage_project_service_account: 1 - modules: 7 - resources: 61 + modules: 8 + resources: 64 + outputs: {} diff --git a/tests/modules/project/service_encryption_keys.yaml b/tests/modules/project/service_encryption_keys.yaml index 5d3b274ab6..91228b35a2 100644 --- a/tests/modules/project/service_encryption_keys.yaml +++ b/tests/modules/project/service_encryption_keys.yaml @@ -16,15 +16,15 @@ values: data.google_storage_project_service_account.gcs_sa[0]: project: my-project user_project: null - google_kms_crypto_key_iam_member.service_agent_cmek["key1.compute-system"]: + google_kms_crypto_key_iam_member.service_agent_cmek["key-0.compute-system"]: condition: [] crypto_key_id: key1 role: roles/cloudkms.cryptoKeyEncrypterDecrypter - google_kms_crypto_key_iam_member.service_agent_cmek["key1.gs-project-accounts"]: + google_kms_crypto_key_iam_member.service_agent_cmek["key-0.gs-project-accounts"]: condition: [] crypto_key_id: key1 role: roles/cloudkms.cryptoKeyEncrypterDecrypter - google_kms_crypto_key_iam_member.service_agent_cmek["key2.gs-project-accounts"]: + google_kms_crypto_key_iam_member.service_agent_cmek["key-1.gs-project-accounts"]: condition: [] crypto_key_id: key2 role: roles/cloudkms.cryptoKeyEncrypterDecrypter diff --git a/tests/modules/project_factory/examples/example.yaml b/tests/modules/project_factory/examples/example.yaml index 416732aef1..a7154ae6f3 100644 --- a/tests/modules/project_factory/examples/example.yaml +++ b/tests/modules/project_factory/examples/example.yaml @@ -143,7 +143,7 @@ values: - ALL parent: projects/test-pf-dev-ta-app0-be timeouts: null - ? module.project-factory.module.projects["dev-ta-app0-be"].google_kms_crypto_key_iam_member.service_agent_cmek["projects/kms-central-prj/locations/europe-west3/keyRings/my-keyring/cryptoKeys/europe3-gce.gs-project-accounts"] + ? module.project-factory.module.projects["dev-ta-app0-be"].google_kms_crypto_key_iam_member.service_agent_cmek["key-0.gs-project-accounts"] : condition: [] crypto_key_id: projects/kms-central-prj/locations/europe-west3/keyRings/my-keyring/cryptoKeys/europe3-gce role: roles/cloudkms.cryptoKeyEncrypterDecrypter diff --git a/tests/modules/secret_manager/examples/secret-cmek.yaml b/tests/modules/secret_manager/examples/secret-cmek.yaml index c793b782f4..6cced31475 100644 --- a/tests/modules/secret_manager/examples/secret-cmek.yaml +++ b/tests/modules/secret_manager/examples/secret-cmek.yaml @@ -16,7 +16,7 @@ values: module.secret-manager.google_secret_manager_secret.default["test-auto"]: annotations: null labels: null - project: project-id + project: test-sec-mgr replication: - auto: - {} @@ -31,7 +31,7 @@ values: module.secret-manager.google_secret_manager_secret.default["test-auto-nokeys"]: annotations: null labels: null - project: project-id + project: test-sec-mgr replication: - auto: - customer_managed_encryption: [] @@ -46,7 +46,7 @@ values: module.secret-manager.google_secret_manager_secret.default["test-manual"]: annotations: null labels: null - project: project-id + project: test-sec-mgr replication: - auto: [] user_managed: @@ -64,10 +64,8 @@ values: counts: google_kms_crypto_key: 3 google_kms_key_ring: 3 - google_project_iam_binding: 1 - google_project_service_identity: 1 google_secret_manager_secret: 3 - modules: 4 - resources: 11 + modules: 5 + resources: 18 outputs: {}