From d63a425b623de0cb7b031a0175d514b85d596ce5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wiktor=20Niesiob=C4=99dzki?= Date: Sat, 5 Apr 2025 14:30:34 +0000 Subject: [PATCH] Allow same filename in different directories As long, as they do override default project name using `name`. --- modules/project-factory/automation.tf | 2 +- modules/project-factory/factory-projects.tf | 21 +- tests/modules/project_factory/bucket_iam.yaml | 248 +++++++++++++++++- .../hierarchy/team-a/automation.yaml | 20 ++ .../bucket_iam/hierarchy/team-b/_config.yaml | 15 ++ .../hierarchy/team-b/automation.yaml | 20 ++ .../bucket_iam/hierarchy/team-b/project3.yaml | 20 ++ .../data/bucket_iam/projects/project3.yaml | 21 ++ .../data_overrides_defaults.yaml | 1 - 9 files changed, 348 insertions(+), 20 deletions(-) create mode 100644 tests/modules/project_factory/data/bucket_iam/hierarchy/team-a/automation.yaml create mode 100644 tests/modules/project_factory/data/bucket_iam/hierarchy/team-b/_config.yaml create mode 100644 tests/modules/project_factory/data/bucket_iam/hierarchy/team-b/automation.yaml create mode 100644 tests/modules/project_factory/data/bucket_iam/hierarchy/team-b/project3.yaml create mode 100644 tests/modules/project_factory/data/bucket_iam/projects/project3.yaml diff --git a/modules/project-factory/automation.tf b/modules/project-factory/automation.tf index 8ddbe2a07..18c9f45f1 100644 --- a/modules/project-factory/automation.tf +++ b/modules/project-factory/automation.tf @@ -35,7 +35,7 @@ locals { ] ]) } -output "foo" { value = local.automation_buckets } + module "automation-bucket" { source = "../gcs" for_each = local.automation_buckets diff --git a/modules/project-factory/factory-projects.tf b/modules/project-factory/factory-projects.tf index 6efcc9c32..aa7b891ae 100644 --- a/modules/project-factory/factory-projects.tf +++ b/modules/project-factory/factory-projects.tf @@ -17,10 +17,10 @@ # tfdoc:file:description Projects factory locals. locals { - _hierarchy_projects = ( + _hierarchy_projects_full_path = ( { for f in try(fileset(local._folders_path, "**/*.yaml"), []) : - basename(trimsuffix(f, ".yaml")) => merge( + trimsuffix(f, ".yaml") => merge( { parent = dirname(f) == "." ? "default" : dirname(f) }, yamldecode(file("${local._folders_path}/${f}")) ) @@ -28,13 +28,16 @@ locals { } ) _project_path = try(pathexpand(var.factories_config.projects_data_path), null) - _projects_input = merge( - { - for f in try(fileset(local._project_path, "**/*.yaml"), []) : - basename(trimsuffix(f, ".yaml")) => yamldecode(file("${local._project_path}/${f}")) - }, - local._hierarchy_projects - ) + _projects_full_path = { + for f in try(fileset(local._project_path, "**/*.yaml"), []) : + trimsuffix(f, ".yaml") => yamldecode(file("${local._project_path}/${f}")) + } + _projects_input = { + # will raise error, if the same filename is raised multiple times + # and project name is not set via name in YAML + for k, v in merge(local._hierarchy_projects_full_path, local._projects_full_path) : + lookup(v, "name", basename(k)) => v + } _project_budgets = flatten([ for k, v in local._projects_input : [ for b in try(v.billing_budgets, []) : { diff --git a/tests/modules/project_factory/bucket_iam.yaml b/tests/modules/project_factory/bucket_iam.yaml index fc7bf9f95..c321b3d62 100644 --- a/tests/modules/project_factory/bucket_iam.yaml +++ b/tests/modules/project_factory/bucket_iam.yaml @@ -83,6 +83,124 @@ values: - group:gcp-devops@example.org - group:team-a-admins@example.org role: roles/viewer + module.hierarchy-folder-lvl-1["team-b"].google_folder.folder[0]: + deletion_protection: false + display_name: Team B + parent: folders/5678901234 + tags: null + timeouts: null + module.projects["auto-team-a"].data.google_storage_project_service_account.gcs_sa[0]: + project: test-pf-auto-team-a + user_project: null + module.projects["auto-team-a"].google_essential_contacts_contact.contact["admin@example.org"]: + email: admin@example.org + language_tag: en + notification_category_subscriptions: + - ALL + parent: projects/test-pf-auto-team-a + timeouts: null + module.projects["auto-team-a"].google_project.project[0]: + auto_create_network: false + billing_account: 012345-67890A-BCDEF0 + deletion_policy: DELETE + effective_labels: + environment: test + goog-terraform-provisioned: 'true' + labels: + environment: test + name: test-pf-auto-team-a + project_id: test-pf-auto-team-a + tags: null + terraform_labels: + environment: test + goog-terraform-provisioned: 'true' + timeouts: null + module.projects["auto-team-a"].google_project_iam_member.service_agents["container-engine-robot"]: + condition: [] + project: test-pf-auto-team-a + role: roles/container.serviceAgent + module.projects["auto-team-a"].google_project_iam_member.service_agents["gkenode"]: + condition: [] + project: test-pf-auto-team-a + role: roles/container.defaultNodeServiceAgent + module.projects["auto-team-a"].google_project_service.project_services["container.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: test-pf-auto-team-a + service: container.googleapis.com + timeouts: null + module.projects["auto-team-a"].google_project_service.project_services["stackdriver.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: test-pf-auto-team-a + service: stackdriver.googleapis.com + timeouts: null + module.projects["auto-team-a"].google_project_service.project_services["storage.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: test-pf-auto-team-a + service: storage.googleapis.com + timeouts: null + module.projects["auto-team-a"].google_project_service_identity.default["container.googleapis.com"]: + project: test-pf-auto-team-a + service: container.googleapis.com + timeouts: null + module.projects["auto-team-b"].data.google_storage_project_service_account.gcs_sa[0]: + project: test-pf-auto-team-b + user_project: null + module.projects["auto-team-b"].google_essential_contacts_contact.contact["admin@example.org"]: + email: admin@example.org + language_tag: en + notification_category_subscriptions: + - ALL + parent: projects/test-pf-auto-team-b + timeouts: null + module.projects["auto-team-b"].google_project.project[0]: + auto_create_network: false + billing_account: 012345-67890A-BCDEF0 + deletion_policy: DELETE + effective_labels: + environment: test + goog-terraform-provisioned: 'true' + labels: + environment: test + name: test-pf-auto-team-b + project_id: test-pf-auto-team-b + tags: null + terraform_labels: + environment: test + goog-terraform-provisioned: 'true' + timeouts: null + module.projects["auto-team-b"].google_project_iam_member.service_agents["container-engine-robot"]: + condition: [] + project: test-pf-auto-team-b + role: roles/container.serviceAgent + module.projects["auto-team-b"].google_project_iam_member.service_agents["gkenode"]: + condition: [] + project: test-pf-auto-team-b + role: roles/container.defaultNodeServiceAgent + module.projects["auto-team-b"].google_project_service.project_services["container.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: test-pf-auto-team-b + service: container.googleapis.com + timeouts: null + module.projects["auto-team-b"].google_project_service.project_services["stackdriver.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: test-pf-auto-team-b + service: stackdriver.googleapis.com + timeouts: null + module.projects["auto-team-b"].google_project_service.project_services["storage.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: test-pf-auto-team-b + service: storage.googleapis.com + timeouts: null + module.projects["auto-team-b"].google_project_service_identity.default["container.googleapis.com"]: + project: test-pf-auto-team-b + service: container.googleapis.com + timeouts: null module.projects["project1"].data.google_storage_project_service_account.gcs_sa[0]: project: test-pf-project1 user_project: null @@ -174,6 +292,118 @@ values: project: test-pf-project2 service: stackdriver.googleapis.com timeouts: null + module.projects["project3"].data.google_storage_project_service_account.gcs_sa[0]: + project: test-pf-project3 + user_project: null + module.projects["project3"].google_essential_contacts_contact.contact["admin@example.org"]: + email: admin@example.org + language_tag: en + notification_category_subscriptions: + - ALL + parent: projects/test-pf-project3 + timeouts: null + module.projects["project3"].google_project.project[0]: + auto_create_network: false + billing_account: 012345-67890A-BCDEF0 + deletion_policy: DELETE + effective_labels: + environment: test + goog-terraform-provisioned: 'true' + labels: + environment: test + name: test-pf-project3 + project_id: test-pf-project3 + tags: null + terraform_labels: + environment: test + goog-terraform-provisioned: 'true' + timeouts: null + module.projects["project3"].google_project_iam_member.service_agents["container-engine-robot"]: + condition: [] + project: test-pf-project3 + role: roles/container.serviceAgent + module.projects["project3"].google_project_iam_member.service_agents["gkenode"]: + condition: [] + project: test-pf-project3 + role: roles/container.defaultNodeServiceAgent + module.projects["project3"].google_project_service.project_services["container.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: test-pf-project3 + service: container.googleapis.com + timeouts: null + module.projects["project3"].google_project_service.project_services["stackdriver.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: test-pf-project3 + service: stackdriver.googleapis.com + timeouts: null + module.projects["project3"].google_project_service.project_services["storage.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: test-pf-project3 + service: storage.googleapis.com + timeouts: null + module.projects["project3"].google_project_service_identity.default["container.googleapis.com"]: + project: test-pf-project3 + service: container.googleapis.com + timeouts: null + module.projects["top-project3"].data.google_storage_project_service_account.gcs_sa[0]: + project: test-pf-top-project3 + user_project: null + module.projects["top-project3"].google_essential_contacts_contact.contact["admin@example.org"]: + email: admin@example.org + language_tag: en + notification_category_subscriptions: + - ALL + parent: projects/test-pf-top-project3 + timeouts: null + module.projects["top-project3"].google_project.project[0]: + auto_create_network: false + billing_account: 012345-67890A-BCDEF0 + deletion_policy: DELETE + effective_labels: + environment: test + goog-terraform-provisioned: 'true' + labels: + environment: test + name: test-pf-top-project3 + project_id: test-pf-top-project3 + tags: null + terraform_labels: + environment: test + goog-terraform-provisioned: 'true' + timeouts: null + module.projects["top-project3"].google_project_iam_member.service_agents["container-engine-robot"]: + condition: [] + project: test-pf-top-project3 + role: roles/container.serviceAgent + module.projects["top-project3"].google_project_iam_member.service_agents["gkenode"]: + condition: [] + project: test-pf-top-project3 + role: roles/container.defaultNodeServiceAgent + module.projects["top-project3"].google_project_service.project_services["container.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: test-pf-top-project3 + service: container.googleapis.com + timeouts: null + module.projects["top-project3"].google_project_service.project_services["stackdriver.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: test-pf-top-project3 + service: stackdriver.googleapis.com + timeouts: null + module.projects["top-project3"].google_project_service.project_services["storage.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: test-pf-top-project3 + service: storage.googleapis.com + timeouts: null + module.projects["top-project3"].google_project_service_identity.default["container.googleapis.com"]: + project: test-pf-top-project3 + service: container.googleapis.com + timeouts: null module.service-accounts["project1/app-be-0"].google_service_account.service_account[0]: account_id: app-be-0 create_ignore_already_exists: null @@ -252,19 +482,19 @@ values: timeouts: null counts: - google_essential_contacts_contact: 2 - google_folder: 1 + google_essential_contacts_contact: 6 + google_folder: 2 google_folder_iam_binding: 1 - google_project: 2 - google_project_iam_member: 6 - google_project_service: 4 - google_project_service_identity: 1 + google_project: 6 + google_project_iam_member: 14 + google_project_service: 16 + google_project_service_identity: 5 google_service_account: 6 google_storage_bucket: 2 google_storage_bucket_iam_binding: 1 - google_storage_project_service_account: 1 - modules: 11 - resources: 27 + google_storage_project_service_account: 5 + modules: 16 + resources: 64 outputs: buckets: diff --git a/tests/modules/project_factory/data/bucket_iam/hierarchy/team-a/automation.yaml b/tests/modules/project_factory/data/bucket_iam/hierarchy/team-a/automation.yaml new file mode 100644 index 000000000..0a744e97f --- /dev/null +++ b/tests/modules/project_factory/data/bucket_iam/hierarchy/team-a/automation.yaml @@ -0,0 +1,20 @@ +# Copyright 2025 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. + +billing_account: 012345-67890A-BCDEF0 +services: + - container.googleapis.com + - storage.googleapis.com + +name: auto-team-a diff --git a/tests/modules/project_factory/data/bucket_iam/hierarchy/team-b/_config.yaml b/tests/modules/project_factory/data/bucket_iam/hierarchy/team-b/_config.yaml new file mode 100644 index 000000000..fbdc4437e --- /dev/null +++ b/tests/modules/project_factory/data/bucket_iam/hierarchy/team-b/_config.yaml @@ -0,0 +1,15 @@ +# Copyright 2025 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. + +name: Team B diff --git a/tests/modules/project_factory/data/bucket_iam/hierarchy/team-b/automation.yaml b/tests/modules/project_factory/data/bucket_iam/hierarchy/team-b/automation.yaml new file mode 100644 index 000000000..58a698cd7 --- /dev/null +++ b/tests/modules/project_factory/data/bucket_iam/hierarchy/team-b/automation.yaml @@ -0,0 +1,20 @@ +# Copyright 2025 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. + +billing_account: 012345-67890A-BCDEF0 +services: + - container.googleapis.com + - storage.googleapis.com + +name: auto-team-b diff --git a/tests/modules/project_factory/data/bucket_iam/hierarchy/team-b/project3.yaml b/tests/modules/project_factory/data/bucket_iam/hierarchy/team-b/project3.yaml new file mode 100644 index 000000000..c953163bd --- /dev/null +++ b/tests/modules/project_factory/data/bucket_iam/hierarchy/team-b/project3.yaml @@ -0,0 +1,20 @@ +# Copyright 2025 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. + +billing_account: 012345-67890A-BCDEF0 +services: + - container.googleapis.com + - storage.googleapis.com + +prefix: team-b diff --git a/tests/modules/project_factory/data/bucket_iam/projects/project3.yaml b/tests/modules/project_factory/data/bucket_iam/projects/project3.yaml new file mode 100644 index 000000000..e6b2fdd4c --- /dev/null +++ b/tests/modules/project_factory/data/bucket_iam/projects/project3.yaml @@ -0,0 +1,21 @@ +# Copyright 2025 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. + +billing_account: 012345-67890A-BCDEF0 +services: + - container.googleapis.com + - storage.googleapis.com + +name: top-project3 +parent: team-b diff --git a/tests/modules/project_factory/data_overrides_defaults.yaml b/tests/modules/project_factory/data_overrides_defaults.yaml index 8afed2dc6..9250d9189 100644 --- a/tests/modules/project_factory/data_overrides_defaults.yaml +++ b/tests/modules/project_factory/data_overrides_defaults.yaml @@ -59,6 +59,5 @@ counts: outputs: buckets: {} folders: {} - foo: {} projects: __missing__ service_accounts: {}