diff --git a/.kitchen.yml b/.kitchen.yml index b4e629d4..d2ae219c 100644 --- a/.kitchen.yml +++ b/.kitchen.yml @@ -32,6 +32,11 @@ suites: name: terraform command_timeout: 1800 root_module_directory: test/fixtures/minimal + - name: vpc_sc_project + driver: + name: terraform + command_timeout: 1800 + root_module_directory: test/fixtures/vpc_sc_project - name: fabric_project driver: name: terraform diff --git a/README.md b/README.md index c82be3c2..5a7db6b6 100644 --- a/README.md +++ b/README.md @@ -148,6 +148,8 @@ determining that location is as follows: | usage\_bucket\_name | Name of a GCS bucket to store GCE usage reports in (optional) | string | `""` | no | | usage\_bucket\_prefix | Prefix in the GCS bucket to store GCE usage reports in (optional) | string | `""` | no | | use\_tf\_google\_credentials\_env\_var | Use GOOGLE_CREDENTIALS environment variable to run gcloud auth activate-service-account with. | bool | `"false"` | no | +| vpc\_service\_control\_attach\_enabled | Whether the project will be attached to a VPC Service Control Perimeter | bool | `"false"` | no | +| vpc\_service\_control\_perimeter\_name | The name of a VPC Service Control Perimeter to add the created project to | string | `"null"` | no | ## Outputs diff --git a/build/int.cloudbuild.yaml b/build/int.cloudbuild.yaml index 2b78568c..418f247a 100644 --- a/build/int.cloudbuild.yaml +++ b/build/int.cloudbuild.yaml @@ -28,13 +28,19 @@ steps: args: ['/bin/bash', '-c', 'ln -s /root/.terraform.d/plugins ~/.terraform.d/plugins && source /usr/local/bin/task_helper_functions.sh && kitchen_do create'] - id: converge name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' - args: ['/bin/bash', '-c', 'ln -s /root/.terraform.d/plugins ~/.terraform.d/plugins && source /usr/local/bin/task_helper_functions.sh && kitchen_do converge'] + args: ['/bin/bash', '-c', 'ln -s /root/.terraform.d/plugins ~/.terraform.d/plugins && source /usr/local/bin/task_helper_functions.sh && export TF_VAR_policy_id=$(gcloud access-context-manager policies list --organization="${TF_VAR_org_id:?}" --format="value(name)") && kitchen_do converge'] + env: + - 'TF_VAR_org_id=$_ORG_ID' + - 'TF_VAR_domain=test.infra.cft.tips.' - id: verify name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' args: ['/bin/bash', '-c', 'ln -s /root/.terraform.d/plugins ~/.terraform.d/plugins && source /usr/local/bin/task_helper_functions.sh && kitchen_do verify'] - id: destroy name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' - args: ['/bin/bash', '-c', 'ln -s /root/.terraform.d/plugins ~/.terraform.d/plugins && source /usr/local/bin/task_helper_functions.sh && kitchen_do destroy'] + args: ['/bin/bash', '-c', 'ln -s /root/.terraform.d/plugins ~/.terraform.d/plugins && source /usr/local/bin/task_helper_functions.sh && export TF_VAR_policy_id=$(gcloud access-context-manager policies list --organization="${TF_VAR_org_id:?}" --format="value(name)") && kitchen_do destroy'] + env: + - 'TF_VAR_org_id=$_ORG_ID' + - 'TF_VAR_domain=test.infra.cft.tips.' tags: - 'ci' - 'integration' diff --git a/examples/app_engine/main.tf b/examples/app_engine/main.tf index 98c58868..06e864a5 100644 --- a/examples/app_engine/main.tf +++ b/examples/app_engine/main.tf @@ -15,11 +15,11 @@ */ provider "google" { - version = "~> 3.6.0" + version = "~> 3.30" } provider "google-beta" { - version = "~> 3.6.0" + version = "~> 3.30" } provider "null" { diff --git a/examples/budget_project/main.tf b/examples/budget_project/main.tf index a008bfdf..0a9fd0e2 100644 --- a/examples/budget_project/main.tf +++ b/examples/budget_project/main.tf @@ -15,11 +15,11 @@ */ provider "google" { - version = "~> 3.6.0" + version = "~> 3.30" } provider "google-beta" { - version = "~> 3.6.0" + version = "~> 3.30" } provider "null" { diff --git a/examples/fabric_project/main.tf b/examples/fabric_project/main.tf index e2ebd457..b14e6343 100644 --- a/examples/fabric_project/main.tf +++ b/examples/fabric_project/main.tf @@ -15,7 +15,7 @@ */ provider "google" { - version = "~> 3.6.0" + version = "~> 3.30" } provider "random" { diff --git a/examples/gke_shared_vpc/main.tf b/examples/gke_shared_vpc/main.tf index 4131841a..d3b61dea 100644 --- a/examples/gke_shared_vpc/main.tf +++ b/examples/gke_shared_vpc/main.tf @@ -20,12 +20,12 @@ locals { provider "google" { credentials = file(local.credentials_file_path) - version = "~> 3.6.0" + version = "~> 3.30" } provider "google-beta" { credentials = file(local.credentials_file_path) - version = "~> 3.6.0" + version = "~> 3.30" } provider "null" { diff --git a/examples/group_project/main.tf b/examples/group_project/main.tf index ef65ae7b..23d30901 100644 --- a/examples/group_project/main.tf +++ b/examples/group_project/main.tf @@ -23,12 +23,12 @@ locals { *****************************************/ provider "google" { credentials = file(local.credentials_file_path) - version = "~> 3.6.0" + version = "~> 3.30" } provider "google-beta" { credentials = file(local.credentials_file_path) - version = "~> 3.6.0" + version = "~> 3.30" } provider "gsuite" { diff --git a/examples/project-hierarchy/main.tf b/examples/project-hierarchy/main.tf index 75aeed09..04df72e7 100644 --- a/examples/project-hierarchy/main.tf +++ b/examples/project-hierarchy/main.tf @@ -23,12 +23,12 @@ locals { *****************************************/ provider "google" { credentials = file(local.credentials_file_path) - version = "~> 3.6.0" + version = "~> 3.30" } provider "google-beta" { credentials = file(local.credentials_file_path) - version = "~> 3.6.0" + version = "~> 3.30" } provider "gsuite" { diff --git a/examples/project_services/main.tf b/examples/project_services/main.tf index c1784ef4..5a5fdc5d 100644 --- a/examples/project_services/main.tf +++ b/examples/project_services/main.tf @@ -18,7 +18,7 @@ Provider configuration *****************************************/ provider "google" { - version = "~> 3.6.0" + version = "~> 3.30" } module "project-services" { diff --git a/examples/shared_vpc/main.tf b/examples/shared_vpc/main.tf index f4bc54e7..ec16870e 100644 --- a/examples/shared_vpc/main.tf +++ b/examples/shared_vpc/main.tf @@ -23,11 +23,11 @@ locals { Provider configuration *****************************************/ provider "google" { - version = "~> 3.6.0" + version = "~> 3.30" } provider "google-beta" { - version = "~> 3.6.0" + version = "~> 3.30" } provider "null" { diff --git a/examples/simple_project/main.tf b/examples/simple_project/main.tf index b4c01a57..90f8d21a 100644 --- a/examples/simple_project/main.tf +++ b/examples/simple_project/main.tf @@ -23,12 +23,12 @@ locals { *****************************************/ provider "google" { credentials = file(local.credentials_file_path) - version = "~> 3.6.0" + version = "~> 3.30" } provider "google-beta" { credentials = file(local.credentials_file_path) - version = "~> 3.6.0" + version = "~> 3.30" } provider "null" { diff --git a/main.tf b/main.tf index d198ea19..6b37a315 100644 --- a/main.tf +++ b/main.tf @@ -28,37 +28,39 @@ module "gsuite_group" { module "project-factory" { source = "./modules/core_project_factory" - group_email = module.gsuite_group.email - group_role = var.group_role - lien = var.lien - manage_group = var.group_name != "" ? "true" : "false" - random_project_id = var.random_project_id - org_id = var.org_id - name = var.name - project_id = var.project_id - shared_vpc = var.shared_vpc - shared_vpc_enabled = var.shared_vpc != "" - billing_account = var.billing_account - folder_id = var.folder_id - sa_role = var.sa_role - activate_apis = var.activate_apis - usage_bucket_name = var.usage_bucket_name - usage_bucket_prefix = var.usage_bucket_prefix - credentials_path = var.credentials_path - impersonate_service_account = var.impersonate_service_account - shared_vpc_subnets = var.shared_vpc_subnets - labels = var.labels - bucket_project = var.bucket_project - bucket_name = var.bucket_name - bucket_location = var.bucket_location - auto_create_network = var.auto_create_network - disable_services_on_destroy = var.disable_services_on_destroy - default_service_account = var.default_service_account - disable_dependent_services = var.disable_dependent_services - python_interpreter_path = var.python_interpreter_path - pip_executable_path = var.pip_executable_path - use_tf_google_credentials_env_var = var.use_tf_google_credentials_env_var - skip_gcloud_download = var.skip_gcloud_download + group_email = module.gsuite_group.email + group_role = var.group_role + lien = var.lien + manage_group = var.group_name != "" ? "true" : "false" + random_project_id = var.random_project_id + org_id = var.org_id + name = var.name + project_id = var.project_id + shared_vpc = var.shared_vpc + shared_vpc_enabled = var.shared_vpc != "" + billing_account = var.billing_account + folder_id = var.folder_id + sa_role = var.sa_role + activate_apis = var.activate_apis + usage_bucket_name = var.usage_bucket_name + usage_bucket_prefix = var.usage_bucket_prefix + credentials_path = var.credentials_path + impersonate_service_account = var.impersonate_service_account + shared_vpc_subnets = var.shared_vpc_subnets + labels = var.labels + bucket_project = var.bucket_project + bucket_name = var.bucket_name + bucket_location = var.bucket_location + auto_create_network = var.auto_create_network + disable_services_on_destroy = var.disable_services_on_destroy + default_service_account = var.default_service_account + disable_dependent_services = var.disable_dependent_services + python_interpreter_path = var.python_interpreter_path + pip_executable_path = var.pip_executable_path + use_tf_google_credentials_env_var = var.use_tf_google_credentials_env_var + skip_gcloud_download = var.skip_gcloud_download + vpc_service_control_attach_enabled = var.vpc_service_control_attach_enabled + vpc_service_control_perimeter_name = var.vpc_service_control_perimeter_name } /****************************************** diff --git a/modules/core_project_factory/main.tf b/modules/core_project_factory/main.tf index 1cec673f..e9ba793e 100644 --- a/modules/core_project_factory/main.tf +++ b/modules/core_project_factory/main.tf @@ -471,3 +471,21 @@ resource "google_project_iam_member" "gke_host_agent" { module.project_services, ] } + +/****************************************** + Attachment to VPC Service Control Perimeter + *****************************************/ +resource "google_access_context_manager_service_perimeter_resource" "service_perimeter_attachment" { + count = var.vpc_service_control_attach_enabled ? 1 : 0 + perimeter_name = var.vpc_service_control_perimeter_name + resource = "projects/${google_project.main.number}" +} + +/****************************************** + Enable Access Context Manager API + *****************************************/ +resource "google_project_service" "enable_access_context_manager" { + count = var.vpc_service_control_attach_enabled ? 1 : 0 + project = google_project.main.number + service = "accesscontextmanager.googleapis.com" +} diff --git a/modules/core_project_factory/variables.tf b/modules/core_project_factory/variables.tf index 000a91f6..c85ecf58 100644 --- a/modules/core_project_factory/variables.tf +++ b/modules/core_project_factory/variables.tf @@ -195,3 +195,15 @@ variable "skip_gcloud_download" { type = bool default = false } + +variable "vpc_service_control_attach_enabled" { + description = "Whether the project will be attached to a VPC Service Control Perimeter" + type = bool + default = false +} + +variable "vpc_service_control_perimeter_name" { + description = "The name of a VPC Service Control Perimeter to add the created project to" + type = string + default = null +} diff --git a/modules/core_project_factory/versions.tf b/modules/core_project_factory/versions.tf index 32d91be1..a8a9d2f9 100644 --- a/modules/core_project_factory/versions.tf +++ b/modules/core_project_factory/versions.tf @@ -18,8 +18,8 @@ terraform { required_version = "~> 0.12.6" required_providers { - google = ">= 2.1, < 4.0" - google-beta = ">= 2.1, < 4.0" + google = ">= 3.8, < 4.0" + google-beta = ">= 3.8, < 4.0" null = "~> 2.1" random = "~> 2.2" } diff --git a/test/fixtures/full/main.tf b/test/fixtures/full/main.tf index 30f70b05..7d1ccf92 100644 --- a/test/fixtures/full/main.tf +++ b/test/fixtures/full/main.tf @@ -15,11 +15,11 @@ */ provider "google" { - version = "~> 3.6.0" + version = "~> 3.30" } provider "google-beta" { - version = "~> 3.6.0" + version = "~> 3.30" } provider "gsuite" { diff --git a/test/fixtures/minimal/main.tf b/test/fixtures/minimal/main.tf index 0c0bd8e5..fcf6d8d3 100644 --- a/test/fixtures/minimal/main.tf +++ b/test/fixtures/minimal/main.tf @@ -15,11 +15,11 @@ */ provider "google" { - version = "~> 3.6.0" + version = "~> 3.30" } provider "google-beta" { - version = "~> 3.6.0" + version = "~> 3.30" } provider "null" { diff --git a/test/fixtures/shared_vpc_no_subnets/main.tf b/test/fixtures/shared_vpc_no_subnets/main.tf index 0281767a..8c6d60dd 100644 --- a/test/fixtures/shared_vpc_no_subnets/main.tf +++ b/test/fixtures/shared_vpc_no_subnets/main.tf @@ -15,11 +15,11 @@ */ provider "google" { - version = "~> 3.6.0" + version = "~> 3.30" } provider "google-beta" { - version = "~> 3.6.0" + version = "~> 3.30" } provider "gsuite" { diff --git a/test/fixtures/vpc_sc_project/.gitignore b/test/fixtures/vpc_sc_project/.gitignore new file mode 100644 index 00000000..3f5ca68a --- /dev/null +++ b/test/fixtures/vpc_sc_project/.gitignore @@ -0,0 +1 @@ +terraform.tfvars diff --git a/test/fixtures/vpc_sc_project/main.tf b/test/fixtures/vpc_sc_project/main.tf new file mode 100644 index 00000000..94f7bbba --- /dev/null +++ b/test/fixtures/vpc_sc_project/main.tf @@ -0,0 +1,73 @@ +/** + * Copyright 2018 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. + */ + +provider "google" { + version = "~> 3.30" +} + +provider "google-beta" { + version = "~> 3.30" +} + +provider "null" { + version = "~> 2.1" +} + +provider "random" { + version = "~> 2.2" +} + +locals { + perimeter_name = "regular_service_perimeter_${var.random_string_for_testing}" +} + +module "regular_service_perimeter_1" { + source = "terraform-google-modules/vpc-service-controls/google//modules/regular_service_perimeter" + policy = var.policy_id + perimeter_name = local.perimeter_name + description = "New service perimeter" + resources = [] + + restricted_services = ["storage.googleapis.com"] +} + +module "project-factory" { + source = "../../../" + + name = "test-vpc-sc-proj-${var.random_string_for_testing}" + random_project_id = true + org_id = var.org_id + folder_id = var.folder_id + billing_account = var.billing_account + + activate_apis = [ + "compute.googleapis.com", + "accesscontextmanager.googleapis.com", + "storage-component.googleapis.com" + ] + + default_service_account = "disable" + disable_services_on_destroy = "false" + + vpc_service_control_attach_enabled = "true" + vpc_service_control_perimeter_name = "accessPolicies/${var.policy_id}/servicePerimeters/${local.perimeter_name}" +} + +resource "google_project_iam_member" "iam-binding" { + project = module.project-factory.project_id + role = "roles/editor" + member = "serviceAccount:${module.project-factory.service_account_email}" +} diff --git a/test/fixtures/vpc_sc_project/outputs.tf b/test/fixtures/vpc_sc_project/outputs.tf new file mode 100644 index 00000000..adef4a41 --- /dev/null +++ b/test/fixtures/vpc_sc_project/outputs.tf @@ -0,0 +1,55 @@ +/** + * Copyright 2019 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. + */ + +output "project_name" { + value = module.project-factory.project_name +} + +output "project_id" { + value = module.project-factory.project_id +} + +output "project_number" { + value = module.project-factory.project_number +} + +output "perimeter_name" { + value = local.perimeter_name +} + +output "policy_id" { + value = var.policy_id +} + +output "service_account_email" { + value = module.project-factory.service_account_email + description = "The email of the default service account" +} + +output "compute_service_account_email" { + value = "${module.project-factory.project_number}-compute@developer.gserviceaccount.com" + description = "The email of the default compute engine service account" +} + +output "container_service_account_email" { + value = "service-${module.project-factory.project_number}@container-engine-robot.iam.gserviceaccount.com" + description = "The email of the default gke service account" +} + +output "group_email" { + value = module.project-factory.group_email + description = "The email of the G Suite group with group_name" +} diff --git a/test/fixtures/vpc_sc_project/variables.tf b/test/fixtures/vpc_sc_project/variables.tf new file mode 100644 index 00000000..4fc57464 --- /dev/null +++ b/test/fixtures/vpc_sc_project/variables.tf @@ -0,0 +1,46 @@ +/** + * Copyright 2019 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. + */ + +variable "policy_name" { + type = string + description = "The policy's name" + default = "" +} + +variable "org_id" { + type = string + description = "The organization ID" +} + +variable "folder_id" { + type = string + description = "The ID of a folder to host this project" +} + +variable "billing_account" { + type = string + description = "Billing account ID" +} + +variable "random_string_for_testing" { + type = string + description = "A random string of characters to be appended to resource names to ensure uniqueness" +} + +variable "policy_id" { + type = string + description = "The ID of the access context manager policy the perimeter lies in" +} diff --git a/test/fixtures/vpc_sc_project/versions.tf b/test/fixtures/vpc_sc_project/versions.tf new file mode 100644 index 00000000..1a9363a3 --- /dev/null +++ b/test/fixtures/vpc_sc_project/versions.tf @@ -0,0 +1,19 @@ +/** + * Copyright 2018 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. + */ + +terraform { + required_version = "~> 0.12.6" +} diff --git a/test/integration/vpc_sc_project/controls/vpc_sc_project.rb b/test/integration/vpc_sc_project/controls/vpc_sc_project.rb new file mode 100644 index 00000000..3935709e --- /dev/null +++ b/test/integration/vpc_sc_project/controls/vpc_sc_project.rb @@ -0,0 +1,69 @@ +# Copyright 2018 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 +# +# https://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. + +project_id = attribute('project_id') +project_number = attribute('project_number') +service_account_email = attribute('service_account_email') +compute_service_account_email = attribute('compute_service_account_email') +group_email = attribute('group_email') +group_name = attribute('group_name') +perimeter_name = attribute('perimeter_name') +policy_id = attribute('policy_id') + +control 'project-factory-vpc-sc-project' do + title 'Project Factory VPC service control perimeter project configuration' + + describe command("gcloud projects describe #{project_id} --format=json") do + its('exit_status') { should be 0 } + its('stderr') { should eq '' } + + let(:metadata) do + if subject.exit_status == 0 + JSON.parse(subject.stdout, symbolize_names: true) + else + {} + end + end + + it { expect(metadata).to include(name: project_id[0...-5]) } + it { expect(metadata).to include(projectId: project_id) } + end + + describe command("gcloud access-context-manager perimeters list --policy #{policy_id} --format=json") do + its('exit_status') { should be 0 } + its('stderr') { should eq '' } + + let(:all_perimeters) do + if subject.exit_status == 0 + JSON.parse(subject.stdout) + else + {} + end + end + describe "correct perimeter" do + let(:perimeter) { all_perimeters.select { |p| p['title'] == perimeter_name }.first } + it "exists" do + expect(perimeter).to include( + "description" => "New service perimeter", + "name" => "accessPolicies/#{policy_id}/servicePerimeters/#{perimeter_name}", + "status" => including( + "resources" => match_array(["projects/#{project_number}"]), + "restrictedServices" => match_array(["storage.googleapis.com"]), + ), + "title" => perimeter_name, + ) + end + end + end +end diff --git a/test/integration/vpc_sc_project/inspec.yml b/test/integration/vpc_sc_project/inspec.yml new file mode 100644 index 00000000..e1d53ed3 --- /dev/null +++ b/test/integration/vpc_sc_project/inspec.yml @@ -0,0 +1,28 @@ +name: vpc_sc_project +attributes: + - name: project_id + required: true + + - name: project_number + required: true + + - name: service_account_email + required: true + + - name: compute_service_account_email + required: true + + - name: container_service_account_email + required: true + + - name: group_email + required: true + + - name: group_name + required: true + + - name: perimeter_name + required: true + + - name: policy_id + required: true diff --git a/test/integration/vpc_sc_project/libraries/.gitkeep b/test/integration/vpc_sc_project/libraries/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/test/setup/iam.tf b/test/setup/iam.tf index dadfdd19..f55d1ccd 100644 --- a/test/setup/iam.tf +++ b/test/setup/iam.tf @@ -33,6 +33,11 @@ locals { "roles/billing.projectManager", "roles/compute.xpnAdmin" ] + + int_required_org_roles = [ + "roles/accesscontextmanager.policyAdmin", + "roles/resourcemanager.organizationViewer", + ] } resource "google_service_account" "int_test" { @@ -42,18 +47,26 @@ resource "google_service_account" "int_test" { } resource "google_project_iam_member" "int_test_project" { - count = length(local.int_required_project_roles) + for_each = toset(local.int_required_project_roles) project = module.pfactory_project.project_id - role = local.int_required_project_roles[count.index] + role = each.value member = "serviceAccount:${google_service_account.int_test.email}" } resource "google_folder_iam_member" "int_test_folder" { - count = length(local.int_required_folder_roles) + for_each = toset(local.int_required_folder_roles) folder = google_folder.ci_pfactory_folder.name - role = local.int_required_folder_roles[count.index] + role = each.value + member = "serviceAccount:${google_service_account.int_test.email}" +} + +resource "google_organization_iam_member" "int_test_org" { + for_each = toset(local.int_required_org_roles) + + org_id = var.org_id + role = each.value member = "serviceAccount:${google_service_account.int_test.email}" } diff --git a/test/setup/main.tf b/test/setup/main.tf index e26ca185..851d9be3 100644 --- a/test/setup/main.tf +++ b/test/setup/main.tf @@ -15,11 +15,11 @@ */ provider "google" { - version = "~> 3.6.0" + version = "~> 3.8" } provider "google-beta" { - version = "~> 3.6.0" + version = "~> 3.8" } provider "null" { @@ -41,7 +41,7 @@ resource "google_folder" "ci_pfactory_folder" { module "pfactory_project" { source = "terraform-google-modules/project-factory/google" - version = "~> 7.0" + version = "~> 8.0" name = "ci-pfactory-tests" random_project_id = true @@ -61,6 +61,7 @@ module "pfactory_project" { "serviceusage.googleapis.com", "billingbudgets.googleapis.com", "pubsub.googleapis.com", + "accesscontextmanager.googleapis.com", ] } diff --git a/test/setup/outputs.tf b/test/setup/outputs.tf index a0bb883d..1432aaea 100644 --- a/test/setup/outputs.tf +++ b/test/setup/outputs.tf @@ -54,3 +54,7 @@ output "domain" { output "group_name" { value = "ci-pfactory-test-group-${random_id.folder_rand.hex}" } + +output "service_account_email" { + value = google_service_account.int_test.email +} diff --git a/variables.tf b/variables.tf index f4be6c55..30077d44 100644 --- a/variables.tf +++ b/variables.tf @@ -208,3 +208,15 @@ variable "skip_gcloud_download" { type = bool default = false } + +variable "vpc_service_control_attach_enabled" { + description = "Whether the project will be attached to a VPC Service Control Perimeter" + type = bool + default = false +} + +variable "vpc_service_control_perimeter_name" { + description = "The name of a VPC Service Control Perimeter to add the created project to" + type = string + default = null +}