From fe485414e67b5a0ffb11ce1c65871834e05cfa77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wiktor=20Niesiob=C4=99dzki?= Date: Fri, 3 Nov 2023 18:04:19 +0100 Subject: [PATCH] Add end-to-end tests for project module (#1823) * Add end-to-end tests for project module * Add inventory to data tests * Add files to end-to-end test cases * Review fixes - use named groups --------- Co-authored-by: Ludovico Magnocavallo --- modules/compute-vm/README.md | 2 +- modules/project/README.md | 411 ++++++++++++++---- modules/project/logging.tf | 3 +- modules/project/service-agents.yaml | 8 +- tests/examples/test_plan.py | 30 +- tests/examples/variables.tf | 6 +- tests/examples_e2e/README.md | 9 +- .../setup_module/e2e_tests.tfvars.tftpl | 10 +- tests/examples_e2e/setup_module/main.tf | 23 +- tests/examples_e2e/setup_module/variables.tf | 3 + tests/examples_e2e/test_plan.py | 10 +- tests/examples_e2e/variables.tf | 92 ---- tests/fixtures.py | 11 +- tests/modules/project/examples/basic.yaml | 10 +- tests/modules/project/examples/data.yaml | 338 ++++++++++++++ .../project/examples/iam-authoritative.yaml | 12 +- .../examples/iam-bindings-additive.yaml | 14 +- .../project/examples/iam-bindings.yaml | 14 +- tests/modules/project/examples/iam-group.yaml | 16 +- .../project/examples/logging-data-access.yaml | 10 +- tests/modules/project/examples/logging.yaml | 20 +- .../project/examples/org-policies.yaml | 34 +- .../examples/shared-vpc-auto-grants.yaml | 16 +- .../modules/project/examples/shared-vpc.yaml | 18 +- 24 files changed, 827 insertions(+), 293 deletions(-) delete mode 100644 tests/examples_e2e/variables.tf create mode 100644 tests/modules/project/examples/data.yaml diff --git a/modules/compute-vm/README.md b/modules/compute-vm/README.md index 052d71b76b..450ccad730 100644 --- a/modules/compute-vm/README.md +++ b/modules/compute-vm/README.md @@ -516,7 +516,7 @@ module "kms-vm-example" { } encryption = { encrypt_boot = true - kms_key_self_link = var.kms_key.self_link + kms_key_self_link = var.kms_key.id } } # tftest modules=1 resources=3 inventory=cmek.yaml diff --git a/modules/project/README.md b/modules/project/README.md index 43dfbc7044..9d94d9f2d1 100644 --- a/modules/project/README.md +++ b/modules/project/README.md @@ -11,15 +11,16 @@ This module implements the creation and management of one GCP project including - [Authoritative IAM](#authoritative-iam) - [Additive IAM](#additive-iam) - [Service Identities and Authoritative IAM](#service-identities-and-authoritative-iam) - - [Service Identities Requiring Manual Iam Grants](#service-identities-requiring-manual-iam-grants) + - [Service Identities Requiring Manual IAM Grants](#service-identities-requiring-manual-iam-grants) - [Shared VPC](#shared-vpc) - [Organization Policies](#organization-policies) - [Organization Policy Factory](#organization-policy-factory) - [Log Sinks](#log-sinks) - [Data Access Logs](#data-access-logs) -- [Cloud Kms Encryption Keys](#cloud-kms-encryption-keys) +- [Cloud KMS Encryption Keys](#cloud-kms-encryption-keys) - [Tags](#tags) - [Outputs](#outputs) + - [Managing project related configuration without creating it](#managing-project-related-configuration-without-creating-it) - [Files](#files) - [Variables](#variables) - [Outputs](#outputs) @@ -30,16 +31,16 @@ This module implements the creation and management of one GCP project including ```hcl module "project" { source = "./fabric/modules/project" - billing_account = "123456-123456-123456" - name = "myproject" - parent = "folders/1234567890" - prefix = "foo" + billing_account = var.billing_account_id + name = "project" + parent = var.folder_id + prefix = var.prefix services = [ "container.googleapis.com", "stackdriver.googleapis.com" ] } -# tftest modules=1 resources=3 inventory=basic.yaml +# tftest modules=1 resources=3 inventory=basic.yaml e2e ``` ## IAM @@ -65,10 +66,10 @@ locals { module "project" { source = "./fabric/modules/project" - billing_account = "123456-123456-123456" - name = "project-example" - parent = "folders/1234567890" - prefix = "foo" + billing_account = var.billing_account_id + name = "project" + parent = var.folder_id + prefix = var.prefix services = [ "container.googleapis.com", "stackdriver.googleapis.com" @@ -87,12 +88,12 @@ The `group_iam` variable uses group email addresses as keys and is a convenient ```hcl module "project" { source = "./fabric/modules/project" - billing_account = "123456-123456-123456" - name = "project-example" - parent = "folders/1234567890" - prefix = "foo" + billing_account = var.billing_account_id + name = "project" + parent = var.folder_id + prefix = var.prefix group_iam = { - "gcp-security-admins@example.com" = [ + (var.group_email) = [ "roles/cloudasset.owner", "roles/cloudsupport.techSupportEditor", "roles/iam.securityReviewer", @@ -100,7 +101,7 @@ module "project" { ] } } -# tftest modules=1 resources=5 inventory=iam-group.yaml +# tftest modules=1 resources=5 inventory=iam-group.yaml e2e ``` The `iam_bindings` variable behaves like a more verbose version of `iam`, and allows setting binding-level IAM conditions. @@ -108,10 +109,10 @@ The `iam_bindings` variable behaves like a more verbose version of `iam`, and al ```hcl module "project" { source = "./fabric/modules/project" - billing_account = "123456-123456-123456" - name = "project-example" - parent = "folders/1234567890" - prefix = "foo" + billing_account = var.billing_account_id + name = "project" + parent = var.folder_id + prefix = var.prefix services = [ "container.googleapis.com", "stackdriver.googleapis.com" @@ -119,7 +120,7 @@ module "project" { iam_bindings = { iam_admin_conditional = { members = [ - "group:test-admins@example.org" + "group:${var.group_email}" ] role = "roles/resourcemanager.projectIamAdmin" condition = { @@ -135,7 +136,7 @@ module "project" { } } } -# tftest modules=1 resources=4 inventory=iam-bindings.yaml +# tftest modules=1 resources=4 inventory=iam-bindings.yaml e2e ``` ### Additive IAM @@ -146,19 +147,22 @@ The `iam_bindings_additive` variable allows setting individual role/principal bi ```hcl module "project" { - source = "./fabric/modules/project" - name = "project-1" + source = "./fabric/modules/project" + billing_account = var.billing_account_id + name = "project" + parent = var.folder_id + prefix = var.prefix services = [ "compute.googleapis.com" ] iam_bindings_additive = { group-owner = { - member = "group:p1-owners@example.org" + member = "group:${var.group_email}" role = "roles/owner" } } } -# tftest modules=1 resources=3 inventory=iam-bindings-additive.yaml +# tftest modules=1 resources=3 inventory=iam-bindings-additive.yaml e2e ``` ### Service Identities and Authoritative IAM @@ -167,23 +171,21 @@ As mentioned above, there are cases where authoritative management of specific I ```hcl module "project" { - source = "./fabric/modules/project" - name = "project-example" - group_iam = { - "foo@example.com" = [ - "roles/editor" - ] - } + source = "./fabric/modules/project" + billing_account = var.billing_account_id + name = "project" + parent = var.folder_id + prefix = var.prefix iam = { "roles/editor" = [ "serviceAccount:${module.project.service_accounts.cloud_services}" ] } } -# tftest modules=1 resources=2 +# tftest modules=1 resources=2 e2e ``` -### Service Identities Requiring Manual Iam Grants +### Service Identities Requiring Manual IAM Grants The module will create service identities at project creation instead of creating of them at the time of first use. This allows granting these service identities roles in other projects, something which is usually necessary in a Shared VPC context. @@ -191,15 +193,21 @@ You can grant roles to service identities using the following construct: ```hcl module "project" { - source = "./fabric/modules/project" - name = "project-example" + source = "./fabric/modules/project" + billing_account = var.billing_account_id + name = "project" + parent = var.folder_id + prefix = var.prefix + services = [ + "apigee.googleapis.com", + ] iam = { "roles/apigee.serviceAgent" = [ "serviceAccount:${module.project.service_accounts.robots.apigee}" ] } } -# tftest modules=1 resources=2 +# tftest modules=1 resources=4 e2e ``` This table lists all affected services and roles that you need to grant to service identities @@ -225,16 +233,26 @@ You can enable Shared VPC Host at the project level and manage project service a ```hcl module "host-project" { - source = "./fabric/modules/project" - name = "my-host-project" + source = "./fabric/modules/project" + billing_account = var.billing_account_id + name = "host" + parent = var.folder_id + prefix = var.prefix shared_vpc_host_config = { enabled = true } } module "service-project" { - source = "./fabric/modules/project" - name = "my-service-project" + source = "./fabric/modules/project" + billing_account = var.billing_account_id + name = "service" + parent = var.folder_id + prefix = var.prefix + services = [ + "container.googleapis.com", + "run.googleapis.com" + ] shared_vpc_service_config = { host_project = module.host-project.project_id service_identity_iam = { @@ -250,23 +268,29 @@ module "service-project" { } } } -# tftest modules=2 resources=8 inventory=shared-vpc.yaml +# tftest modules=2 resources=10 inventory=shared-vpc.yaml e2e ``` The module allows also granting necessary permissions in host project to service identities by specifying which services will be used in service project in `grant_iam_for_services`. ```hcl module "host-project" { - source = "./fabric/modules/project" - name = "my-host-project" + source = "./fabric/modules/project" + billing_account = var.billing_account_id + name = "host" + parent = var.folder_id + prefix = var.prefix shared_vpc_host_config = { enabled = true } } module "service-project" { - source = "./fabric/modules/project" - name = "my-service-project" + source = "./fabric/modules/project" + billing_account = var.billing_account_id + name = "service" + parent = var.folder_id + prefix = var.prefix services = [ "container.googleapis.com", ] @@ -275,7 +299,7 @@ module "service-project" { service_iam_grants = module.service-project.services } } -# tftest modules=2 resources=9 inventory=shared-vpc-auto-grants.yaml +# tftest modules=2 resources=9 inventory=shared-vpc-auto-grants.yaml e2e ``` ## Organization Policies @@ -285,10 +309,10 @@ To manage organization policies, the `orgpolicy.googleapis.com` service should b ```hcl module "project" { source = "./fabric/modules/project" - billing_account = "123456-123456-123456" - name = "project-example" - parent = "folders/1234567890" - prefix = "foo" + billing_account = var.billing_account_id + name = "project" + parent = var.folder_id + prefix = var.prefix org_policies = { "compute.disableGuestAttributesAccess" = { rules = [{ enforce = true }] @@ -334,7 +358,7 @@ module "project" { } } } -# tftest modules=1 resources=8 inventory=org-policies.yaml +# tftest modules=1 resources=8 inventory=org-policies.yaml e2e ``` ### Organization Policy Factory @@ -348,13 +372,13 @@ The example below deploys a few organization policies split between two YAML fil ```hcl module "project" { source = "./fabric/modules/project" - billing_account = "123456-123456-123456" - name = "project-example" - parent = "folders/1234567890" - prefix = "foo" + billing_account = var.billing_account_id + name = "project" + parent = var.folder_id + prefix = var.prefix org_policies_data_path = "configs/org-policies/" } -# tftest modules=1 resources=8 files=boolean,list inventory=org-policies.yaml +# tftest modules=1 resources=8 files=boolean,list inventory=org-policies.yaml e2e ``` ```yaml @@ -415,6 +439,7 @@ module "gcs" { source = "./fabric/modules/gcs" project_id = var.project_id name = "gcs_sink" + prefix = var.prefix force_destroy = true } @@ -422,6 +447,7 @@ module "dataset" { source = "./fabric/modules/bigquery-dataset" project_id = var.project_id id = "bq_sink" + options = { delete_contents_on_destroy = true } } module "pubsub" { @@ -433,15 +459,19 @@ module "pubsub" { module "bucket" { source = "./fabric/modules/logging-bucket" parent_type = "project" - parent = "my-project" + parent = var.project_id id = "bucket" } module "project-host" { source = "./fabric/modules/project" - name = "my-project" - billing_account = "123456-123456-123456" - parent = "folders/1234567890" + name = "project" + billing_account = var.billing_account_id + parent = var.folder_id + prefix = var.prefix + services = [ + "logging.googleapis.com" + ] logging_sinks = { warnings = { destination = module.gcs.id @@ -471,7 +501,7 @@ module "project-host" { no-gce-instances = "resource.type=gce_instance" } } -# tftest modules=5 resources=14 inventory=logging.yaml +# tftest modules=5 resources=15 inventory=logging.yaml e2e ``` ## Data Access Logs @@ -483,13 +513,14 @@ This example shows how to set a non-authoritative access log configuration: ```hcl module "project" { source = "./fabric/modules/project" - name = "my-project" - billing_account = "123456-123456-123456" - parent = "folders/1234567890" + name = "project" + billing_account = var.billing_account_id + parent = var.folder_id + prefix = var.prefix logging_data_access = { allServices = { # logs for principals listed here will be excluded - ADMIN_READ = ["group:organization-admins@example.org"] + ADMIN_READ = ["group:${var.group_email}"] } "storage.googleapis.com" = { DATA_READ = [] @@ -497,33 +528,34 @@ module "project" { } } } -# tftest modules=1 resources=3 inventory=logging-data-access.yaml +# tftest modules=1 resources=3 inventory=logging-data-access.yaml e2e ``` -## Cloud Kms Encryption Keys +## Cloud KMS Encryption Keys The module offers a simple, centralized way to assign `roles/cloudkms.cryptoKeyEncrypterDecrypter` to service identities. ```hcl module "project" { - source = "./fabric/modules/project" - name = "my-project" - prefix = "foo" + source = "./fabric/modules/project" + billing_account = var.billing_account_id + name = "project" + prefix = var.prefix + parent = var.folder_id services = [ "compute.googleapis.com", "storage.googleapis.com" ] service_encryption_key_ids = { compute = [ - "projects/kms-central-prj/locations/europe-west3/keyRings/my-keyring/cryptoKeys/europe3-gce", - "projects/kms-central-prj/locations/europe-west4/keyRings/my-keyring/cryptoKeys/europe4-gce" + var.kms_key.id ] storage = [ - "projects/kms-central-prj/locations/europe/keyRings/my-keyring/cryptoKeys/europe-gcs" + var.kms_key.id ] } } -# tftest modules=1 resources=7 +# tftest modules=1 resources=6 e2e ``` ## Tags @@ -548,7 +580,8 @@ module "org" { module "project" { source = "./fabric/modules/project" - name = "test-project" + name = "project" + parent = var.folder_id tag_bindings = { env-prod = module.org.tag_values["environment/prod"].id foo = "tagValues/12345678" @@ -565,8 +598,11 @@ One non-obvious output is `service_accounts`, which offers a simple way to disco ```hcl module "project" { - source = "./fabric/modules/project" - name = "project-example" + source = "./fabric/modules/project" + billing_account = var.billing_account_id + name = "project" + prefix = var.prefix + parent = var.folder_id services = [ "compute.googleapis.com" ] @@ -575,9 +611,222 @@ module "project" { output "compute_robot" { value = module.project.service_accounts.robots.compute } -# tftest modules=1 resources=2 inventory:outputs.yaml +# tftest modules=1 resources=2 inventory:outputs.yaml e2e ``` +### Managing project related configuration without creating it + +The module offers managing all related resources without ever touching the project itself by using `project_create = false` + +```hcl +module "create-project" { + source = "./fabric/modules/project" + billing_account = var.billing_account_id + name = "project" + parent = var.folder_id + prefix = var.prefix +} + +module "project" { + source = "./fabric/modules/project" + depends_on = [module.create-project] + billing_account = var.billing_account_id + name = "project" + parent = var.folder_id + prefix = var.prefix + project_create = false + + group_iam = { + (var.group_email) = [ + "roles/cloudasset.owner", + "roles/cloudsupport.techSupportEditor", + "roles/iam.securityReviewer", + "roles/logging.admin", + ] + } + iam_bindings = { + iam_admin_conditional = { + members = [ + "group:${var.group_email}" + ] + role = "roles/resourcemanager.projectIamAdmin" + condition = { + title = "delegated_network_user_one" + expression = <<-END + api.getAttribute( + 'iam.googleapis.com/modifiedGrantsByRole', [] + ).hasOnly([ + 'roles/compute.networkAdmin' + ]) + END + } + } + } + iam_bindings_additive = { + group-owner = { + member = "group:${var.group_email}" + role = "roles/owner" + } + } + iam = { + "roles/editor" = [ + "serviceAccount:${module.project.service_accounts.cloud_services}" + ] + "roles/apigee.serviceAgent" = [ + "serviceAccount:${module.project.service_accounts.robots.apigee}" + ] + } + logging_data_access = { + allServices = { + # logs for principals listed here will be excluded + ADMIN_READ = ["group:${var.group_email}"] + } + "storage.googleapis.com" = { + DATA_READ = [] + DATA_WRITE = [] + } + } + logging_sinks = { + warnings = { + destination = module.gcs.id + filter = "severity=WARNING" + type = "storage" + } + info = { + destination = module.dataset.id + filter = "severity=INFO" + type = "bigquery" + } + notice = { + destination = module.pubsub.id + filter = "severity=NOTICE" + type = "pubsub" + } + debug = { + destination = module.bucket.id + filter = "severity=DEBUG" + exclusions = { + no-compute = "logName:compute" + } + type = "logging" + } + } + logging_exclusions = { + no-gce-instances = "resource.type=gce_instance" + } + org_policies = { + "compute.disableGuestAttributesAccess" = { + rules = [{ enforce = true }] + } + "compute.skipDefaultNetworkCreation" = { + rules = [{ enforce = true }] + } + "iam.disableServiceAccountKeyCreation" = { + rules = [{ enforce = true }] + } + "iam.disableServiceAccountKeyUpload" = { + rules = [ + { + condition = { + expression = "resource.matchTagId('tagKeys/1234', 'tagValues/1234')" + title = "condition" + description = "test condition" + location = "somewhere" + } + enforce = true + }, + { + enforce = false + } + ] + } + "iam.allowedPolicyMemberDomains" = { + rules = [{ + allow = { + values = ["C0xxxxxxx", "C0yyyyyyy"] + } + }] + } + "compute.trustedImageProjects" = { + rules = [{ + allow = { + values = ["projects/my-project"] + } + }] + } + "compute.vmExternalIpAccess" = { + rules = [{ deny = { all = true } }] + } + } + shared_vpc_service_config = { + host_project = module.host-project.project_id + service_iam_grants = module.project.services + service_identity_iam = { + "roles/cloudasset.owner" = [ + "cloudservices", "container-engine" + ] + } + } + services = [ + "apigee.googleapis.com", + "bigquery.googleapis.com", + "container.googleapis.com", + "logging.googleapis.com", + "run.googleapis.com", + "storage.googleapis.com", + ] + service_encryption_key_ids = { + compute = [ + var.kms_key.id + ] + storage = [ + var.kms_key.id + ] + } +} + +module "host-project" { + source = "./fabric/modules/project" + billing_account = var.billing_account_id + name = "host" + parent = var.folder_id + prefix = var.prefix + shared_vpc_host_config = { + enabled = true + } +} + +module "gcs" { + source = "./fabric/modules/gcs" + project_id = var.project_id + name = "gcs_sink" + prefix = var.prefix + force_destroy = true +} + +module "dataset" { + source = "./fabric/modules/bigquery-dataset" + project_id = var.project_id + id = "bq_sink" + options = { delete_contents_on_destroy = true } +} + +module "pubsub" { + source = "./fabric/modules/pubsub" + project_id = var.project_id + name = "pubsub_sink" +} + +module "bucket" { + source = "./fabric/modules/logging-bucket" + parent_type = "project" + parent = var.project_id + id = "bucket" +} +# tftest modules=7 resources=53 inventory=data.yaml e2e +``` + + ## Files diff --git a/modules/project/logging.tf b/modules/project/logging.tf index 0181f04f56..6694c176a2 100644 --- a/modules/project/logging.tf +++ b/modules/project/logging.tf @@ -69,7 +69,8 @@ resource "google_logging_project_sink" "sink" { depends_on = [ google_project_iam_binding.authoritative, google_project_iam_binding.bindings, - google_project_iam_member.bindings + google_project_iam_member.bindings, + google_project_service.project_services ] } diff --git a/modules/project/service-agents.yaml b/modules/project/service-agents.yaml index c8eff2df97..eb38dc4cc9 100644 --- a/modules/project/service-agents.yaml +++ b/modules/project/service-agents.yaml @@ -18,7 +18,7 @@ service_agent: "service-%s@gcp-sa-adsdatahub.iam.gserviceaccount.com" - name: "aiplatform" service_agent: "service-%s@gcp-sa-aiplatform.iam.gserviceaccount.com" - jit: true + jit: true # roles/aiplatform.customCodeServiceAgent - name: "aiplatform-cc" service_agent: "service-%s@gcp-sa-aiplatform-cc.iam.gserviceaccount.com" - name: "alloydb" @@ -37,7 +37,7 @@ service_agent: "service-%s@gcp-sa-apigateway-mgmt.iam.gserviceaccount.com" - name: "apigee" service_agent: "service-%s@gcp-sa-apigee.iam.gserviceaccount.com" - jit: true #roles/apigee.serviceAgent + jit: true # roles/apigee.serviceAgent - name: "apigeeregistry" service_agent: "service-%s@gcp-sa-apigeeregistry.iam.gserviceaccount.com" - name: "appdevelopmentexperience" @@ -221,7 +221,7 @@ service_agent: "service-%s@gcp-sa-healthcare.iam.gserviceaccount.com" - name: "iap" service_agent: "service-%s@gcp-sa-iap.iam.gserviceaccount.com" - jit: true + jit: true # none - name: "identitytoolkit" service_agent: "service-%s@gcp-sa-identitytoolkit.iam.gserviceaccount.com" - name: "ids" @@ -314,7 +314,7 @@ service_agent: "service-%s@gcp-sa-spectrumsas.iam.gserviceaccount.com" - name: "secretmanager" service_agent: "service-%s@gcp-sa-secretmanager.iam.gserviceaccount.com" - jit: true + jit: true # none - name: "securedlandingzone" service_agent: "service-%s@gcp-sa-slz.iam.gserviceaccount.com" - name: "securitycenter-notification" diff --git a/tests/examples/test_plan.py b/tests/examples/test_plan.py index 3ff2992ed5..22525698ed 100644 --- a/tests/examples/test_plan.py +++ b/tests/examples/test_plan.py @@ -18,9 +18,18 @@ from pathlib import Path BASE_PATH = Path(__file__).parent -COUNT_TEST_RE = re.compile(r'# tftest +modules=(\d+) +resources=(\d+)' + - r'(?: +files=([\w@,_-]+))?' + - r'(?: +inventory=([\w\-.]+))?') +COUNT_TEST_RE = re.compile(r'# tftest +modules=(?P\d+) +resources=(?P\d+)' + + r'(?: +files=(?P[\w@,_-]+))?' + + r'(?: +inventory=(?P[\w\-.]+))?') + + +def prepare_files(example, test_path, line): + if line is not None: + requested_files = line.split(',') + for f in requested_files: + destination = test_path / example.files[f].path + destination.parent.mkdir(parents=True, exist_ok=True) + destination.write_text(example.files[f].content) def test_example(plan_validator, tmp_path, example): @@ -33,21 +42,16 @@ def test_example(plan_validator, tmp_path, example): if assets_path.exists(): (tmp_path / 'assets').symlink_to(assets_path) - expected_modules = int(match.group(1)) - expected_resources = int(match.group(2)) + expected_modules = int(match.group("modules")) + expected_resources = int(match.group("resources")) - if match.group(3) is not None: - requested_files = match.group(3).split(',') - for f in requested_files: - destination = tmp_path / example.files[f].path - destination.parent.mkdir(parents=True, exist_ok=True) - destination.write_text(example.files[f].content) + prepare_files(example, tmp_path, match.group("files")) inventory = [] - if match.group(4) is not None: + if match.group("inventory") is not None: python_test_path = str(example.module).replace('-', '_') inventory = BASE_PATH.parent / python_test_path / 'examples' - inventory = inventory / match.group(4) + inventory = inventory / match.group("inventory") # TODO: force plan_validator to never copy files (we're already # running from a temp dir) diff --git a/tests/examples/variables.tf b/tests/examples/variables.tf index 9a65aa7a52..ebdbb155cb 100644 --- a/tests/examples/variables.tf +++ b/tests/examples/variables.tf @@ -22,9 +22,13 @@ variable "billing_account_id" { default = "123456-123456-123456" } +variable "group_email" { + default = "organization-admins@example.org" +} + variable "kms_key" { default = { - self_link = "kms_key_self_link" + id = "kms_key_self_link" } } diff --git a/tests/examples_e2e/README.md b/tests/examples_e2e/README.md index 027ef21c8a..bab4337288 100644 --- a/tests/examples_e2e/README.md +++ b/tests/examples_e2e/README.md @@ -9,7 +9,7 @@ Prepare following information: * prepare service account that has necessary permissions (able to assign billing account to project, resource creation etc) # How does it work -Each test case is provided by additional environment defined in [variables.tf](./variables.tf). This simplifies writing the examples as this follows the same structure as for non-end-to-end tests, and allows multiple, independent and concurrent runs of tests. +Each test case is provided by additional environment defined in [variables.tf](../examples/variables.tf). This simplifies writing the examples as this follows the same structure as for non-end-to-end tests, and allows multiple, independent and concurrent runs of tests. The test environment can be provisioned automatically during the test run (which now takes ~2 minutes) and destroyed and the end, when of the tests (Option 1 below), which is targeting automated runs in CI/CD pipeline, or can be provisioned manually to reduce test time, which might be typical use case for tests run locally. @@ -18,6 +18,7 @@ The test environment can be provisioned automatically during the test run (which ## Create `e2e.tfvars` file ```hcl billing_account = "123456-123456-123456" # billing account id to associate projects +group_email = "group@example.org" # existing group within organization organization_id = "1234567890" # your organization id parent = "folders/1234567890" # folder under which test resources will be created prefix = "your-unique-prefix" # unique prefix for projects @@ -27,15 +28,17 @@ region = "europe-west4" # region to use ``` And set environment variable pointing to the file: ```bash +export TF_VAR_prefix="your-unique-prefix" # unique prefix for projects, no longer than 7 characters export TFTEST_E2E_SETUP_TFVARS_PATH= ``` Or set above variables in environment: ```bash export TF_VAR_billing_account="123456-123456-123456" # billing account id to associate projects +export TF_VAR_group_email="group@example.org" # existing group within organization export TF_VAR_organization_id="1234567890" # your organization id export TF_VAR_parent="folders/1234567890" # folder under which test resources will be created -export TF_VAR_prefix="your-unique-prefix" # unique prefix for projects +export TF_VAR_prefix="your-unique-prefix" # unique prefix for projects, no longer than 7 characters export TF_VAR_region="europe-west4" # region to use ``` @@ -55,6 +58,7 @@ pytest tests/examples_e2e In `tests/examples_e2e/setup_module` create `terraform.tfvars` with following values: ```hcl billing_account = "123456-123456-123456" # billing account id to associate projects +group_email = "group@example.org" # existing group within organization organization_id = "1234567890" # your organization id parent = "folders/1234567890" # folder under which test resources will be created prefix = "your-unique-prefix" # unique prefix for projects @@ -79,6 +83,7 @@ This will generate also `tests/examples_e2e/setup_module/e2e_tests.tfvars` for y ## Setup your environment ```bash export TFTEST_E2E_TFVARS_PATH=`pwd`/tests/examples_e2e/setup_module/e2e_tests.tfvars # generated above +export TF_VAR_prefix="your-unique-prefix" # unique prefix for projects, no longer than 7 characters ``` ## Run tests diff --git a/tests/examples_e2e/setup_module/e2e_tests.tfvars.tftpl b/tests/examples_e2e/setup_module/e2e_tests.tfvars.tftpl index c21d77422a..31a34d3df5 100644 --- a/tests/examples_e2e/setup_module/e2e_tests.tfvars.tftpl +++ b/tests/examples_e2e/setup_module/e2e_tests.tfvars.tftpl @@ -12,14 +12,14 @@ # See the License for the specific language governing permissions and # limitations under the License. -bucket= "${bucket}" +bucket = "${bucket}" billing_account_id = "${billing_account_id}" -kms_key= { - self_link = "kms_key_self_link" +kms_key = { + id = "${kms_key_id}" } +group_email = "${group_email}" organization_id = "${organization_id}" -folder_id = "${folder_id}" -prefix = "${prefix}" +folder_id = "folders/${folder_id}" project_id = "${project_id}" region = "${region}" service_account = { diff --git a/tests/examples_e2e/setup_module/main.tf b/tests/examples_e2e/setup_module/main.tf index 9bc5a9799c..e781d779bc 100644 --- a/tests/examples_e2e/setup_module/main.tf +++ b/tests/examples_e2e/setup_module/main.tf @@ -13,11 +13,14 @@ # limitations under the License. locals { - prefix = "${var.prefix}-${var.timestamp}-${var.suffix}" + prefix = "${var.prefix}-${var.timestamp}${var.suffix}" services = [ # trimmed down list of services, to be extended as needed + "apigee.googleapis.com", + "bigquery.googleapis.com", "cloudbuild.googleapis.com", "cloudfunctions.googleapis.com", + "cloudkms.googleapis.com", "cloudresourcemanager.googleapis.com", "compute.googleapis.com", "iam.googleapis.com", @@ -77,14 +80,28 @@ 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 "local_file" "terraform_tfvars" { filename = "e2e_tests.tfvars" content = templatefile("e2e_tests.tfvars.tftpl", { bucket = google_storage_bucket.bucket.name billing_account_id = var.billing_account - organization_id = var.organization_id folder_id = google_folder.folder.folder_id - prefix = local.prefix + group_email = var.group_email + kms_key_id = google_kms_crypto_key.key.id + organization_id = var.organization_id project_id = google_project.project.project_id region = var.region service_account = { diff --git a/tests/examples_e2e/setup_module/variables.tf b/tests/examples_e2e/setup_module/variables.tf index d936cb2080..16f110df0a 100644 --- a/tests/examples_e2e/setup_module/variables.tf +++ b/tests/examples_e2e/setup_module/variables.tf @@ -15,6 +15,9 @@ variable "billing_account" { type = string } +variable "group_email" { + type = string +} variable "organization_id" { type = string } diff --git a/tests/examples_e2e/test_plan.py b/tests/examples_e2e/test_plan.py index 84579b6b41..c9936b9bbf 100644 --- a/tests/examples_e2e/test_plan.py +++ b/tests/examples_e2e/test_plan.py @@ -14,16 +14,14 @@ import re from pathlib import Path +from ..examples.test_plan import COUNT_TEST_RE, prepare_files BASE_PATH = Path(__file__).parent -COUNT_TEST_RE = re.compile(r'# tftest +modules=(\d+) +resources=(\d+)' + - r'(?: +files=([\w@,_-]+))?' + - r'(?: +inventory=([\w\-.]+))?') def test_example(e2e_validator, tmp_path, examples_e2e, e2e_tfvars_path): (tmp_path / 'fabric').symlink_to(BASE_PATH.parents[1]) - (tmp_path / 'variables.tf').symlink_to(BASE_PATH / 'variables.tf') + (tmp_path / 'variables.tf').symlink_to(BASE_PATH.parent / 'examples' / 'variables.tf') (tmp_path / 'main.tf').write_text(examples_e2e.code) assets_path = BASE_PATH.parent / str(examples_e2e.module).replace( '-', '_') / 'assets' @@ -31,5 +29,9 @@ def test_example(e2e_validator, tmp_path, examples_e2e, e2e_tfvars_path): (tmp_path / 'assets').symlink_to(assets_path) (tmp_path / 'terraform.tfvars').symlink_to(e2e_tfvars_path) + # add files the same way as it is done for examples + if match := COUNT_TEST_RE.search(examples_e2e.code): + prepare_files(examples_e2e, tmp_path, match.group("files")) + e2e_validator(module_path=tmp_path, extra_files=[], tf_var_files=[(tmp_path / 'terraform.tfvars')]) diff --git a/tests/examples_e2e/variables.tf b/tests/examples_e2e/variables.tf deleted file mode 100644 index 9a65aa7a52..0000000000 --- a/tests/examples_e2e/variables.tf +++ /dev/null @@ -1,92 +0,0 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# common variables used for examples - -variable "bucket" { - default = "bucket" -} - -variable "billing_account_id" { - default = "123456-123456-123456" -} - -variable "kms_key" { - default = { - self_link = "kms_key_self_link" - } -} - -variable "organization_id" { - default = "organizations/1122334455" -} - -variable "folder_id" { - default = "folders/1122334455" -} - -variable "prefix" { - default = "test" -} - -variable "project_id" { - default = "project-id" -} - -variable "region" { - default = "region" -} - -variable "service_account" { - default = { - id = "service_account_id" - email = "service_account_email" - iam_email = "service_account_iam_email" - } -} - -variable "subnet" { - default = { - name = "subnet_name" - region = "subnet_region" - cidr = "subnet_cidr" - self_link = "subnet_self_link" - } -} - -variable "vpc" { - default = { - name = "vpc_name" - self_link = "projects/xxx/global/networks/aaa" - id = "projects/xxx/global/networks/aaa" - } -} - -variable "vpc1" { - default = { - name = "vpc_name" - self_link = "projects/xxx/global/networks/bbb" - } -} - -variable "vpc2" { - default = { - name = "vpc2_name" - self_link = "projects/xxx/global/networks/ccc" - } -} - -variable "zone" { - default = "zone" -} diff --git a/tests/fixtures.py b/tests/fixtures.py index caa9c9456f..01a89f423c 100644 --- a/tests/fixtures.py +++ b/tests/fixtures.py @@ -298,9 +298,12 @@ def e2e_validator(module_path, extra_files, tf_var_files, basedir=None): tf.setup(extra_files=extra_files, upgrade=True) tf_var_files = [(basedir / x).resolve() for x in tf_var_files or []] + # to allow different tests to create projects (or other globally unique resources) with the same name + # bump prefix forward on each test execution + prefix = f'{os.environ.get("TF_VAR_prefix")}-{int(time.time())}{os.environ.get("PYTEST_XDIST_WORKER", "0")[-2:]}' try: - apply = tf.apply(tf_var_file=tf_var_files) - plan = tf.plan(output=True, tf_var_file=tf_var_files) + apply = tf.apply(tf_var_file=tf_var_files, tf_vars={"prefix": prefix}) + plan = tf.plan(output=True, tf_var_file=tf_var_files, tf_vars={"prefix": prefix}) changes = {} for resource_name, value in plan.resource_changes.items(): if value.get('change', {}).get('actions') != ['no-op']: @@ -324,7 +327,7 @@ def e2e_validator(module_path, extra_files, tf_var_files, basedir=None): # If above did not fail, this should not either, but left as a safety check assert changes == {}, f'Plan not empty for following resources: {", ".join(changes.keys())}' finally: - destroy = tf.destroy(tf_var_file=tf_var_files) + destroy = tf.destroy(tf_var_file=tf_var_files, tf_vars={'prefix': prefix}) @pytest.fixture(name='e2e_validator') @@ -371,7 +374,7 @@ def e2e_tfvars_path(): tf = tftest.TerraformTest(test_path, binary=binary) tf_vars_file = None tf_vars = { - 'suffix': os.environ.get("PYTEST_XDIST_WORKER", "0"), + 'suffix': os.environ.get("PYTEST_XDIST_WORKER", "0")[-2:], # take at most 2 last chars for suffix 'timestamp': str(int(time.time())) } if 'TFTEST_E2E_SETUP_TFVARS_PATH' in os.environ: diff --git a/tests/modules/project/examples/basic.yaml b/tests/modules/project/examples/basic.yaml index 56e6ecc02f..919a0581ee 100644 --- a/tests/modules/project/examples/basic.yaml +++ b/tests/modules/project/examples/basic.yaml @@ -17,21 +17,21 @@ values: module.project.google_project.project[0]: auto_create_network: false billing_account: 123456-123456-123456 - folder_id: '1234567890' + folder_id: '1122334455' labels: null - name: foo-myproject + name: test-project org_id: null - project_id: foo-myproject + project_id: test-project skip_delete: false module.project.google_project_service.project_services["container.googleapis.com"]: disable_dependent_services: false disable_on_destroy: false - project: foo-myproject + project: test-project service: container.googleapis.com module.project.google_project_service.project_services["stackdriver.googleapis.com"]: disable_dependent_services: false disable_on_destroy: false - project: foo-myproject + project: test-project service: stackdriver.googleapis.com counts: diff --git a/tests/modules/project/examples/data.yaml b/tests/modules/project/examples/data.yaml new file mode 100644 index 0000000000..b7ec3d23aa --- /dev/null +++ b/tests/modules/project/examples/data.yaml @@ -0,0 +1,338 @@ +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +values: + module.bucket.google_logging_project_bucket_config.bucket[0]: + bucket_id: bucket + project: project-id + module.create-project.google_project.project[0]: + billing_account: 123456-123456-123456 + folder_id: '1122334455' + name: test-project + project_id: test-project + module.dataset.google_bigquery_dataset.default: + dataset_id: bq_sink + delete_contents_on_destroy: true + project: project-id + module.gcs.google_storage_bucket.bucket: + name: test-gcs_sink + project: project-id + module.host-project.google_compute_shared_vpc_host_project.shared_vpc_host[0]: + project: test-host + module.host-project.google_project.project[0]: + billing_account: 123456-123456-123456 + folder_id: '1122334455' + name: test-host + project_id: test-host + module.project.data.google_bigquery_default_service_account.bq_sa[0]: + project: test-project + module.project.data.google_project.project[0]: + project_id: test-project + module.project.data.google_storage_project_service_account.gcs_sa[0]: + project: test-project + module.project.google_bigquery_dataset_iam_member.bq-sinks-binding["info"]: + role: roles/bigquery.dataEditor + module.project.google_compute_shared_vpc_service_project.shared_vpc_service[0]: + host_project: test-host + service_project: test-project + module.project.google_kms_crypto_key_iam_member.service_identity_cmek["compute.kms_key_self_link"]: + crypto_key_id: kms_key_self_link + role: roles/cloudkms.cryptoKeyEncrypterDecrypter + module.project.google_kms_crypto_key_iam_member.service_identity_cmek["storage.kms_key_self_link"]: + crypto_key_id: kms_key_self_link + role: roles/cloudkms.cryptoKeyEncrypterDecrypter + module.project.google_logging_project_exclusion.logging-exclusion["no-gce-instances"]: + filter: resource.type=gce_instance + name: no-gce-instances + project: test-project + module.project.google_logging_project_sink.sink["debug"]: + exclusions: + - description: null + disabled: false + filter: logName:compute + name: no-compute + filter: severity=DEBUG + name: debug + project: test-project + module.project.google_logging_project_sink.sink["info"]: + exclusions: [] + filter: severity=INFO + name: info + project: test-project + module.project.google_logging_project_sink.sink["notice"]: + destination: pubsub.googleapis.com/projects/project-id/topics/pubsub_sink + disabled: false + exclusions: [] + filter: severity=NOTICE + name: notice + project: test-project + module.project.google_logging_project_sink.sink["warnings"]: + destination: storage.googleapis.com/test-gcs_sink + disabled: false + exclusions: [] + filter: severity=WARNING + name: warnings + project: test-project + module.project.google_org_policy_policy.default["compute.disableGuestAttributesAccess"]: + name: projects/test-project/policies/compute.disableGuestAttributesAccess + parent: projects/test-project + spec: + - inherit_from_parent: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + values: [] + module.project.google_org_policy_policy.default["compute.skipDefaultNetworkCreation"]: + name: projects/test-project/policies/compute.skipDefaultNetworkCreation + parent: projects/test-project + spec: + - inherit_from_parent: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + values: [] + module.project.google_org_policy_policy.default["compute.trustedImageProjects"]: + name: projects/test-project/policies/compute.trustedImageProjects + parent: projects/test-project + spec: + - inherit_from_parent: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: null + values: + - allowed_values: + - projects/my-project + denied_values: null + module.project.google_org_policy_policy.default["compute.vmExternalIpAccess"]: + name: projects/test-project/policies/compute.vmExternalIpAccess + parent: projects/test-project + spec: + - inherit_from_parent: null + rules: + - allow_all: null + condition: [] + deny_all: 'TRUE' + enforce: null + values: [] + module.project.google_org_policy_policy.default["iam.allowedPolicyMemberDomains"]: + name: projects/test-project/policies/iam.allowedPolicyMemberDomains + parent: projects/test-project + spec: + - inherit_from_parent: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: null + values: + - allowed_values: + - C0xxxxxxx + - C0yyyyyyy + denied_values: null + module.project.google_org_policy_policy.default["iam.disableServiceAccountKeyCreation"]: + name: projects/test-project/policies/iam.disableServiceAccountKeyCreation + parent: projects/test-project + spec: + - inherit_from_parent: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + values: [] + module.project.google_org_policy_policy.default["iam.disableServiceAccountKeyUpload"]: + name: projects/test-project/policies/iam.disableServiceAccountKeyUpload + parent: projects/test-project + spec: + - inherit_from_parent: null + rules: + - allow_all: null + condition: + - description: test condition + expression: resource.matchTagId('tagKeys/1234', 'tagValues/1234') + location: somewhere + title: condition + deny_all: null + enforce: 'TRUE' + values: [] + - allow_all: null + condition: [] + deny_all: null + enforce: 'FALSE' + values: [] + module.project.google_project_iam_audit_config.default["allServices"]: + audit_log_config: + - exempted_members: + - group:organization-admins@example.org + log_type: ADMIN_READ + project: test-project + service: allServices + module.project.google_project_iam_audit_config.default["storage.googleapis.com"]: + audit_log_config: + - exempted_members: [] + log_type: DATA_READ + - exempted_members: [] + log_type: DATA_WRITE + project: test-project + service: storage.googleapis.com + module.project.google_project_iam_binding.authoritative["roles/apigee.serviceAgent"]: + condition: [] + project: test-project + role: roles/apigee.serviceAgent + module.project.google_project_iam_binding.authoritative["roles/cloudasset.owner"]: + condition: [] + project: test-project + role: roles/cloudasset.owner + module.project.google_project_iam_binding.authoritative["roles/cloudsupport.techSupportEditor"]: + condition: [] + project: test-project + role: roles/cloudsupport.techSupportEditor + module.project.google_project_iam_binding.authoritative["roles/editor"]: + condition: [] + project: test-project + role: roles/editor + module.project.google_project_iam_binding.authoritative["roles/iam.securityReviewer"]: + condition: [] + project: test-project + role: roles/iam.securityReviewer + module.project.google_project_iam_binding.authoritative["roles/logging.admin"]: + condition: [] + project: test-project + role: roles/logging.admin + module.project.google_project_iam_binding.bindings["iam_admin_conditional"]: + condition: + - description: null + expression: "api.getAttribute(\n 'iam.googleapis.com/modifiedGrantsByRole',\ + \ []\n).hasOnly([\n 'roles/compute.networkAdmin'\n])\n" + title: delegated_network_user_one + members: + - group:organization-admins@example.org + project: test-project + role: roles/resourcemanager.projectIamAdmin + module.project.google_project_iam_member.bindings["group-owner"]: + condition: [] + member: group:organization-admins@example.org + project: test-project + role: roles/owner + module.project.google_project_iam_member.bucket-sinks-binding["debug"]: + condition: + - title: debug bucket writer + role: roles/logging.bucketWriter + module.project.google_project_iam_member.shared_vpc_host_robots["roles/cloudasset.owner:cloudservices"]: + condition: [] + project: test-host + role: roles/cloudasset.owner + module.project.google_project_iam_member.shared_vpc_host_robots["roles/cloudasset.owner:container-engine"]: + condition: [] + project: test-host + role: roles/cloudasset.owner + module.project.google_project_iam_member.shared_vpc_host_robots["roles/compute.networkUser:cloudservices"]: + condition: [] + project: test-host + role: roles/compute.networkUser + module.project.google_project_iam_member.shared_vpc_host_robots["roles/compute.networkUser:container"]: + condition: [] + project: test-host + role: roles/compute.networkUser + module.project.google_project_iam_member.shared_vpc_host_robots["roles/compute.securityAdmin:container"]: + condition: [] + project: test-host + role: roles/compute.securityAdmin + module.project.google_project_iam_member.shared_vpc_host_robots["roles/container.hostServiceAgentUser:container"]: + condition: [] + project: test-host + role: roles/container.hostServiceAgentUser + module.project.google_project_iam_member.shared_vpc_host_robots["roles/vpcaccess.user:run"]: + condition: [] + project: test-host + role: roles/vpcaccess.user + module.project.google_project_service.project_services["apigee.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: test-project + service: apigee.googleapis.com + module.project.google_project_service.project_services["bigquery.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: test-project + service: bigquery.googleapis.com + module.project.google_project_service.project_services["container.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: test-project + service: container.googleapis.com + module.project.google_project_service.project_services["logging.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: test-project + service: logging.googleapis.com + module.project.google_project_service.project_services["run.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: test-project + service: run.googleapis.com + module.project.google_project_service.project_services["storage.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: test-project + service: storage.googleapis.com + module.project.google_project_service_identity.jit_si["apigee.googleapis.com"]: + project: test-project + service: apigee.googleapis.com + module.project.google_pubsub_topic_iam_member.pubsub-sinks-binding["notice"]: + condition: [] + project: project-id + role: roles/pubsub.publisher + topic: pubsub_sink + module.project.google_storage_bucket_iam_member.gcs-sinks-binding["warnings"]: + bucket: test-gcs_sink + condition: [] + role: roles/storage.objectCreator + module.pubsub.google_pubsub_topic.default: + name: pubsub_sink + project: project-id + +counts: + google_bigquery_dataset: 1 + google_bigquery_dataset_iam_member: 1 + google_bigquery_default_service_account: 1 + google_compute_shared_vpc_host_project: 1 + google_compute_shared_vpc_service_project: 1 + google_kms_crypto_key_iam_member: 2 + google_logging_project_bucket_config: 1 + google_logging_project_exclusion: 1 + google_logging_project_sink: 4 + google_org_policy_policy: 7 + google_project: 3 + google_project_iam_audit_config: 2 + google_project_iam_binding: 7 + google_project_iam_member: 9 + google_project_service: 6 + google_project_service_identity: 1 + google_pubsub_topic: 1 + google_pubsub_topic_iam_member: 1 + google_storage_bucket: 1 + google_storage_bucket_iam_member: 1 + google_storage_project_service_account: 1 + modules: 7 + resources: 53 + +outputs: {} diff --git a/tests/modules/project/examples/iam-authoritative.yaml b/tests/modules/project/examples/iam-authoritative.yaml index eeb77aa6e5..d889a88312 100644 --- a/tests/modules/project/examples/iam-authoritative.yaml +++ b/tests/modules/project/examples/iam-authoritative.yaml @@ -16,29 +16,29 @@ values: module.project.google_project.project[0]: auto_create_network: false billing_account: 123456-123456-123456 - folder_id: '1234567890' + folder_id: '1122334455' labels: null - name: foo-project-example + name: test-project org_id: null - project_id: foo-project-example + project_id: test-project skip_delete: false timeouts: null module.project.google_project_iam_binding.authoritative["roles/container.hostServiceAgentUser"]: condition: [] members: - serviceAccount:my_gke_service_account - project: foo-project-example + project: test-project role: roles/container.hostServiceAgentUser module.project.google_project_service.project_services["container.googleapis.com"]: disable_dependent_services: false disable_on_destroy: false - project: foo-project-example + project: test-project service: container.googleapis.com timeouts: null module.project.google_project_service.project_services["stackdriver.googleapis.com"]: disable_dependent_services: false disable_on_destroy: false - project: foo-project-example + project: test-project service: stackdriver.googleapis.com timeouts: null diff --git a/tests/modules/project/examples/iam-bindings-additive.yaml b/tests/modules/project/examples/iam-bindings-additive.yaml index 390781f97c..2276622bb3 100644 --- a/tests/modules/project/examples/iam-bindings-additive.yaml +++ b/tests/modules/project/examples/iam-bindings-additive.yaml @@ -15,23 +15,23 @@ values: module.project.google_project.project[0]: auto_create_network: false - billing_account: null - folder_id: null + billing_account: 123456-123456-123456 + folder_id: '1122334455' labels: null - name: project-1 + name: test-project org_id: null - project_id: project-1 + project_id: test-project skip_delete: false timeouts: null module.project.google_project_iam_member.bindings["group-owner"]: condition: [] - member: group:p1-owners@example.org - project: project-1 + member: group:organization-admins@example.org + project: test-project role: roles/owner module.project.google_project_service.project_services["compute.googleapis.com"]: disable_dependent_services: false disable_on_destroy: false - project: project-1 + project: test-project service: compute.googleapis.com timeouts: null diff --git a/tests/modules/project/examples/iam-bindings.yaml b/tests/modules/project/examples/iam-bindings.yaml index c9fee92524..eddc582083 100644 --- a/tests/modules/project/examples/iam-bindings.yaml +++ b/tests/modules/project/examples/iam-bindings.yaml @@ -16,11 +16,11 @@ values: module.project.google_project.project[0]: auto_create_network: false billing_account: 123456-123456-123456 - folder_id: '1234567890' + folder_id: '1122334455' labels: null - name: foo-project-example + name: test-project org_id: null - project_id: foo-project-example + project_id: test-project skip_delete: false timeouts: null module.project.google_project_iam_binding.bindings["iam_admin_conditional"]: @@ -30,19 +30,19 @@ values: \ []\n).hasOnly([\n 'roles/compute.networkAdmin'\n])\n" title: delegated_network_user_one members: - - group:test-admins@example.org - project: foo-project-example + - group:organization-admins@example.org + project: test-project role: roles/resourcemanager.projectIamAdmin module.project.google_project_service.project_services["container.googleapis.com"]: disable_dependent_services: false disable_on_destroy: false - project: foo-project-example + project: test-project service: container.googleapis.com timeouts: null module.project.google_project_service.project_services["stackdriver.googleapis.com"]: disable_dependent_services: false disable_on_destroy: false - project: foo-project-example + project: test-project service: stackdriver.googleapis.com timeouts: null diff --git a/tests/modules/project/examples/iam-group.yaml b/tests/modules/project/examples/iam-group.yaml index 0ca2ecdba9..73f14b80a6 100644 --- a/tests/modules/project/examples/iam-group.yaml +++ b/tests/modules/project/examples/iam-group.yaml @@ -17,26 +17,26 @@ values: module.project.google_project_iam_binding.authoritative["roles/cloudasset.owner"]: condition: [] members: - - group:gcp-security-admins@example.com - project: foo-project-example + - group:organization-admins@example.org + project: test-project role: roles/cloudasset.owner module.project.google_project_iam_binding.authoritative["roles/cloudsupport.techSupportEditor"]: condition: [] members: - - group:gcp-security-admins@example.com - project: foo-project-example + - group:organization-admins@example.org + project: test-project role: roles/cloudsupport.techSupportEditor module.project.google_project_iam_binding.authoritative["roles/iam.securityReviewer"]: condition: [] members: - - group:gcp-security-admins@example.com - project: foo-project-example + - group:organization-admins@example.org + project: test-project role: roles/iam.securityReviewer module.project.google_project_iam_binding.authoritative["roles/logging.admin"]: condition: [] members: - - group:gcp-security-admins@example.com - project: foo-project-example + - group:organization-admins@example.org + project: test-project role: roles/logging.admin counts: diff --git a/tests/modules/project/examples/logging-data-access.yaml b/tests/modules/project/examples/logging-data-access.yaml index 3b35bbdc38..50d3886450 100644 --- a/tests/modules/project/examples/logging-data-access.yaml +++ b/tests/modules/project/examples/logging-data-access.yaml @@ -16,11 +16,11 @@ values: module.project.google_project.project[0]: auto_create_network: false billing_account: 123456-123456-123456 - folder_id: '1234567890' + folder_id: '1122334455' labels: null - name: my-project + name: test-project org_id: null - project_id: my-project + project_id: test-project skip_delete: false timeouts: null module.project.google_project_iam_audit_config.default["allServices"]: @@ -28,7 +28,7 @@ values: - exempted_members: - group:organization-admins@example.org log_type: ADMIN_READ - project: my-project + project: test-project service: allServices module.project.google_project_iam_audit_config.default["storage.googleapis.com"]: audit_log_config: @@ -36,7 +36,7 @@ values: log_type: DATA_READ - exempted_members: [] log_type: DATA_WRITE - project: my-project + project: test-project service: storage.googleapis.com counts: diff --git a/tests/modules/project/examples/logging.yaml b/tests/modules/project/examples/logging.yaml index 9634d8d102..7e96968afe 100644 --- a/tests/modules/project/examples/logging.yaml +++ b/tests/modules/project/examples/logging.yaml @@ -21,7 +21,7 @@ values: disabled: null filter: resource.type=gce_instance name: no-gce-instances - project: my-project + project: test-project module.project-host.google_logging_project_sink.sink["debug"]: description: debug (Terraform-managed). disabled: false @@ -32,7 +32,7 @@ values: name: no-compute filter: severity=DEBUG name: debug - project: my-project + project: test-project unique_writer_identity: true module.project-host.google_logging_project_sink.sink["info"]: description: info (Terraform-managed). @@ -40,7 +40,7 @@ values: exclusions: [] filter: severity=INFO name: info - project: my-project + project: test-project unique_writer_identity: true module.project-host.google_logging_project_sink.sink["notice"]: description: notice (Terraform-managed). @@ -48,25 +48,25 @@ values: exclusions: [] filter: severity=NOTICE name: notice - project: my-project + project: test-project unique_writer_identity: true module.project-host.google_logging_project_sink.sink["warnings"]: description: warnings (Terraform-managed). - destination: storage.googleapis.com/gcs_sink + destination: storage.googleapis.com/test-gcs_sink disabled: false exclusions: [] filter: severity=WARNING name: warnings - project: my-project + project: test-project unique_writer_identity: true module.project-host.google_project.project[0]: auto_create_network: false billing_account: 123456-123456-123456 - folder_id: '1234567890' + folder_id: '1122334455' labels: null - name: my-project + name: test-project org_id: null - project_id: my-project + project_id: test-project skip_delete: false module.project-host.google_project_iam_member.bucket-sinks-binding["debug"]: condition: @@ -76,7 +76,7 @@ values: condition: [] role: roles/pubsub.publisher module.project-host.google_storage_bucket_iam_member.gcs-sinks-binding["warnings"]: - bucket: gcs_sink + bucket: test-gcs_sink condition: [] role: roles/storage.objectCreator diff --git a/tests/modules/project/examples/org-policies.yaml b/tests/modules/project/examples/org-policies.yaml index d4dddc75bf..6539c32c41 100644 --- a/tests/modules/project/examples/org-policies.yaml +++ b/tests/modules/project/examples/org-policies.yaml @@ -14,8 +14,8 @@ values: module.project.google_org_policy_policy.default["compute.disableGuestAttributesAccess"]: - name: projects/foo-project-example/policies/compute.disableGuestAttributesAccess - parent: projects/foo-project-example + name: projects/test-project/policies/compute.disableGuestAttributesAccess + parent: projects/test-project spec: - inherit_from_parent: null reset: null @@ -26,8 +26,8 @@ values: enforce: 'TRUE' values: [] module.project.google_org_policy_policy.default["compute.skipDefaultNetworkCreation"]: - name: projects/foo-project-example/policies/compute.skipDefaultNetworkCreation - parent: projects/foo-project-example + name: projects/test-project/policies/compute.skipDefaultNetworkCreation + parent: projects/test-project spec: - inherit_from_parent: null reset: null @@ -38,8 +38,8 @@ values: enforce: 'TRUE' values: [] module.project.google_org_policy_policy.default["compute.trustedImageProjects"]: - name: projects/foo-project-example/policies/compute.trustedImageProjects - parent: projects/foo-project-example + name: projects/test-project/policies/compute.trustedImageProjects + parent: projects/test-project spec: - inherit_from_parent: null reset: null @@ -53,8 +53,8 @@ values: - projects/my-project denied_values: null module.project.google_org_policy_policy.default["compute.vmExternalIpAccess"]: - name: projects/foo-project-example/policies/compute.vmExternalIpAccess - parent: projects/foo-project-example + name: projects/test-project/policies/compute.vmExternalIpAccess + parent: projects/test-project spec: - inherit_from_parent: null reset: null @@ -65,8 +65,8 @@ values: enforce: null values: [] module.project.google_org_policy_policy.default["iam.allowedPolicyMemberDomains"]: - name: projects/foo-project-example/policies/iam.allowedPolicyMemberDomains - parent: projects/foo-project-example + name: projects/test-project/policies/iam.allowedPolicyMemberDomains + parent: projects/test-project spec: - inherit_from_parent: null reset: null @@ -81,8 +81,8 @@ values: - C0yyyyyyy denied_values: null module.project.google_org_policy_policy.default["iam.disableServiceAccountKeyCreation"]: - name: projects/foo-project-example/policies/iam.disableServiceAccountKeyCreation - parent: projects/foo-project-example + name: projects/test-project/policies/iam.disableServiceAccountKeyCreation + parent: projects/test-project spec: - inherit_from_parent: null reset: null @@ -93,8 +93,8 @@ values: enforce: 'TRUE' values: [] module.project.google_org_policy_policy.default["iam.disableServiceAccountKeyUpload"]: - name: projects/foo-project-example/policies/iam.disableServiceAccountKeyUpload - parent: projects/foo-project-example + name: projects/test-project/policies/iam.disableServiceAccountKeyUpload + parent: projects/test-project spec: - inherit_from_parent: null reset: null @@ -115,10 +115,10 @@ values: values: [] module.project.google_project.project[0]: billing_account: 123456-123456-123456 - folder_id: '1234567890' - name: foo-project-example + folder_id: '1122334455' + name: test-project org_id: null - project_id: foo-project-example + project_id: test-project counts: google_org_policy_policy: 7 diff --git a/tests/modules/project/examples/shared-vpc-auto-grants.yaml b/tests/modules/project/examples/shared-vpc-auto-grants.yaml index 226612394b..4dacb377b9 100644 --- a/tests/modules/project/examples/shared-vpc-auto-grants.yaml +++ b/tests/modules/project/examples/shared-vpc-auto-grants.yaml @@ -14,25 +14,25 @@ values: module.host-project.google_compute_shared_vpc_host_project.shared_vpc_host[0]: - project: my-host-project + project: test-host module.host-project.google_project.project[0]: - project_id: my-host-project + project_id: test-host module.service-project.google_compute_shared_vpc_service_project.shared_vpc_service[0]: - host_project: my-host-project - service_project: my-service-project + host_project: test-host + service_project: test-service module.service-project.google_project.project[0]: - project_id: my-service-project + project_id: test-service module.service-project.google_project_iam_member.shared_vpc_host_robots["roles/compute.networkUser:cloudservices"]: condition: [] - project: my-host-project + project: test-host role: roles/compute.networkUser module.service-project.google_project_iam_member.shared_vpc_host_robots["roles/compute.networkUser:container"]: condition: [] - project: my-host-project + project: test-host role: roles/compute.networkUser module.service-project.google_project_iam_member.shared_vpc_host_robots["roles/container.hostServiceAgentUser:container"]: condition: [] - project: my-host-project + project: test-host role: roles/container.hostServiceAgentUser counts: diff --git a/tests/modules/project/examples/shared-vpc.yaml b/tests/modules/project/examples/shared-vpc.yaml index 169c897de2..4277d56b3d 100644 --- a/tests/modules/project/examples/shared-vpc.yaml +++ b/tests/modules/project/examples/shared-vpc.yaml @@ -14,29 +14,29 @@ values: module.host-project.google_compute_shared_vpc_host_project.shared_vpc_host[0]: - project: my-host-project + project: test-host module.host-project.google_project.project[0]: - project_id: my-host-project + project_id: test-host module.service-project.google_compute_shared_vpc_service_project.shared_vpc_service[0]: - host_project: my-host-project - service_project: my-service-project + host_project: test-host + service_project: test-service module.service-project.google_project.project[0]: - project_id: my-service-project + project_id: test-service module.service-project.google_project_iam_member.shared_vpc_host_robots["roles/compute.networkUser:cloudservices"]: condition: [] - project: my-host-project + project: test-host role: roles/compute.networkUser module.service-project.google_project_iam_member.shared_vpc_host_robots["roles/compute.networkUser:container-engine"]: condition: [] - project: my-host-project + project: test-host role: roles/compute.networkUser module.service-project.google_project_iam_member.shared_vpc_host_robots["roles/container.hostServiceAgentUser:container-engine"]: condition: [] - project: my-host-project + project: test-host role: roles/container.hostServiceAgentUser module.service-project.google_project_iam_member.shared_vpc_host_robots["roles/vpcaccess.user:cloudrun"]: condition: [] - project: my-host-project + project: test-host role: roles/vpcaccess.user counts: