From 4e90bee24bad734ec9a8c99f32902b5904f68796 Mon Sep 17 00:00:00 2001 From: Max Portocarrero CI&T <105444618+maxi-cit@users.noreply.github.com> Date: Thu, 28 Jul 2022 14:31:58 -0500 Subject: [PATCH] feat: add private service connect module (#368) * added private-service-connect submodule * added missing default value to environment_code * added firewall usage condition * added private service connect example * fixed output vars for integration testing * Docker image devloper tools bumped to 1.4 * added discover_test.go to test/integration. This was required to run tests * added TestPrivateServiceConnect test * developer tools version bumped to 1.5 * changed names and variables so it generalize to more escenarios * updated private service connect example * added tests for DNS zones, global address and forwarding rule * added private service connect tests to cloudbuild * added versions.tf to private service connect example * fixed reviewed changes * deleting discover_test.go * deleting trailing space * deleted unused comments * fixed undefined variable at int.cloudbuild.yaml * changed example network name * enabled DNS api to test setup * added DNS admin roles to test service account * added requirements to private service connect README * updated Cloud DNS version * change assert functions from Equal to Equalf * added provider meta google-beta * added spaces on example outputs * fixed typos in module private-service-connect README * fixed README example * retargeting output values * Updated default value and name composition for DNS zones * added cft support & cft usage on private-service-connect tests * updated README * updated int.cloudbuild.yaml * bumping route example * Update modules/private-service-connect/README.md Co-authored-by: Bharath KKB --- build/int.cloudbuild.yaml | 15 +++ examples/private_service_connect/README.md | 26 ++++ examples/private_service_connect/main.tf | 47 ++++++++ examples/private_service_connect/outputs.tf | 65 ++++++++++ examples/private_service_connect/variables.tf | 20 +++ examples/private_service_connect/versions.tf | 29 +++++ examples/routes/main.tf | 2 +- examples/routes/versions.tf | 2 +- modules/private-service-connect/README.md | 74 ++++++++++++ modules/private-service-connect/dns.tf | 114 ++++++++++++++++++ modules/private-service-connect/main.tf | 41 +++++++ modules/private-service-connect/outputs.tf | 63 ++++++++++ modules/private-service-connect/variables.tf | 58 +++++++++ modules/private-service-connect/versions.tf | 37 ++++++ test/integration/discover_test.go | 25 ++++ .../private_service_connect_test.go | 60 +++++++++ test/setup/iam.tf | 3 +- test/setup/main.tf | 3 +- 18 files changed, 680 insertions(+), 4 deletions(-) create mode 100644 examples/private_service_connect/README.md create mode 100644 examples/private_service_connect/main.tf create mode 100644 examples/private_service_connect/outputs.tf create mode 100644 examples/private_service_connect/variables.tf create mode 100644 examples/private_service_connect/versions.tf create mode 100644 modules/private-service-connect/README.md create mode 100644 modules/private-service-connect/dns.tf create mode 100644 modules/private-service-connect/main.tf create mode 100644 modules/private-service-connect/outputs.tf create mode 100644 modules/private-service-connect/variables.tf create mode 100644 modules/private-service-connect/versions.tf create mode 100644 test/integration/discover_test.go create mode 100644 test/integration/private_service_connect/private_service_connect_test.go diff --git a/build/int.cloudbuild.yaml b/build/int.cloudbuild.yaml index 3ca78331..f2019457 100644 --- a/build/int.cloudbuild.yaml +++ b/build/int.cloudbuild.yaml @@ -151,6 +151,21 @@ steps: - verify submodule-vpc-serverless-connector-beta name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' args: ['/bin/bash', '-c', 'source /usr/local/bin/task_helper_functions.sh && source_test_env && init_credentials && cd test/integration && RUN_STAGE=teardown go test -v ./... -p 1 -timeout 0 -run TestSubmoduleServerlessConnector'] +- id: converge private-service-connect + waitFor: + - create all + name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' + args: ['/bin/bash', '-c', 'cft test run TestPrivateServiceConnect --stage apply --verbose'] +- id: verify private-service-connect + waitFor: + - converge private-service-connect + name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' + args: ['/bin/bash', '-c', 'cft test run TestPrivateServiceConnect --stage verify --verbose'] +- id: destroy private-service-connect + waitFor: + - verify private-service-connect + name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' + args: ['/bin/bash', '-c', 'cft test run TestPrivateServiceConnect --stage teardown --verbose'] tags: - 'ci' - 'integration' diff --git a/examples/private_service_connect/README.md b/examples/private_service_connect/README.md new file mode 100644 index 00000000..17e54f13 --- /dev/null +++ b/examples/private_service_connect/README.md @@ -0,0 +1,26 @@ +# Private Service Connect +This example configures a single VPC inside a project and enables it to consume a Private Service Connect endpoint. + + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| project\_id | Project ID for Private Service Connect. | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| dns\_zone\_gcr\_name | Name for Managed DNS zone for GCR | +| dns\_zone\_googleapis\_name | Name for Managed DNS zone for GoogleAPIs | +| dns\_zone\_pkg\_dev\_name | Name for Managed DNS zone for PKG\_DEV | +| forwarding\_rule\_name | Forwarding rule resource name. | +| forwarding\_rule\_target | Target resource to receive the matched traffic. Only `all-apis` and `vpc-sc` are valid. | +| global\_address\_id | An identifier for the global address created for the private service connect with format `projects/{{project}}/global/addresses/{{name}}` | +| network\_name | The network name | +| private\_service\_connect\_ip | The private service connect ip | +| private\_service\_connect\_name | Private service connect name | +| project\_id | The project id | + + diff --git a/examples/private_service_connect/main.tf b/examples/private_service_connect/main.tf new file mode 100644 index 00000000..29d5a77e --- /dev/null +++ b/examples/private_service_connect/main.tf @@ -0,0 +1,47 @@ +/** + * Copyright 2022 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. + */ + +# Whenever a new major version of the network module is released, the +# version constraint below should be updated, e.g. to ~> 4.0. +# +# If that new version includes provider updates, validation of this +# example may fail until that is done. + +module "private_service_connect" { + source = "../../modules/private-service-connect" + project_id = var.project_id + network_self_link = module.simple_vpc.network_self_link + private_service_connect_ip = "10.3.0.5" + forwarding_rule_target = "all-apis" +} + +module "simple_vpc" { + source = "terraform-google-modules/network/google" + version = "~> 4.0.1" + project_id = var.project_id + network_name = "my-custom-network" + mtu = 1460 + + subnets = [ + { + subnet_name = "my-subnetwork" + subnet_ip = "10.0.0.0/24" + subnet_region = "us-west1" + subnet_private_access = "true" + subnet_flow_logs = "true" + } + ] +} diff --git a/examples/private_service_connect/outputs.tf b/examples/private_service_connect/outputs.tf new file mode 100644 index 00000000..ebf5be3b --- /dev/null +++ b/examples/private_service_connect/outputs.tf @@ -0,0 +1,65 @@ +/** + * Copyright 2022 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_id" { + value = var.project_id + description = "The project id" +} + +output "network_name" { + value = module.simple_vpc.network_name + description = "The network name" +} + +output "private_service_connect_name" { + value = module.private_service_connect.private_service_connect_name + description = "Private service connect name" +} + +output "private_service_connect_ip" { + value = module.private_service_connect.private_service_connect_ip + description = "The private service connect ip" +} + +output "global_address_id" { + value = module.private_service_connect.global_address_id + description = "An identifier for the global address created for the private service connect with format `projects/{{project}}/global/addresses/{{name}}`" +} + +output "forwarding_rule_name" { + value = module.private_service_connect.forwarding_rule_name + description = "Forwarding rule resource name." +} + +output "forwarding_rule_target" { + value = module.private_service_connect.forwarding_rule_target + description = "Target resource to receive the matched traffic. Only `all-apis` and `vpc-sc` are valid." +} + +output "dns_zone_googleapis_name" { + value = module.private_service_connect.dns_zone_googleapis_name + description = "Name for Managed DNS zone for GoogleAPIs" +} + +output "dns_zone_gcr_name" { + value = module.private_service_connect.dns_zone_gcr_name + description = "Name for Managed DNS zone for GCR" +} + +output "dns_zone_pkg_dev_name" { + value = module.private_service_connect.dns_zone_pkg_dev_name + description = "Name for Managed DNS zone for PKG_DEV" +} diff --git a/examples/private_service_connect/variables.tf b/examples/private_service_connect/variables.tf new file mode 100644 index 00000000..b6833dc1 --- /dev/null +++ b/examples/private_service_connect/variables.tf @@ -0,0 +1,20 @@ +/** + * Copyright 2022 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 "project_id" { + description = "Project ID for Private Service Connect." + type = string +} diff --git a/examples/private_service_connect/versions.tf b/examples/private_service_connect/versions.tf new file mode 100644 index 00000000..6256afb3 --- /dev/null +++ b/examples/private_service_connect/versions.tf @@ -0,0 +1,29 @@ +/** + * Copyright 2022 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.13" + required_providers { + google = { + source = "hashicorp/google" + version = ">= 3.50" + } + google-beta = { + source = "hashicorp/google-beta" + version = ">= 3.50" + } + } +} diff --git a/examples/routes/main.tf b/examples/routes/main.tf index 63143d41..f8a8a092 100644 --- a/examples/routes/main.tf +++ b/examples/routes/main.tf @@ -23,7 +23,7 @@ # [START vpc_static_route_create] module "google_compute_route" { source = "terraform-google-modules/network/google//modules/routes" - version = "~> 3.2.0" + version = "~> 5.0" project_id = var.project_id # Replace this with your project ID in quotes network_name = "default" diff --git a/examples/routes/versions.tf b/examples/routes/versions.tf index f66c07f6..a327e867 100644 --- a/examples/routes/versions.tf +++ b/examples/routes/versions.tf @@ -19,7 +19,7 @@ terraform { required_providers { google = { - version = "~> 3.45.0" + version = "~> 4.0" } null = { version = "~> 2.1" diff --git a/modules/private-service-connect/README.md b/modules/private-service-connect/README.md new file mode 100644 index 00000000..11188c54 --- /dev/null +++ b/modules/private-service-connect/README.md @@ -0,0 +1,74 @@ +# Private Service Connect + +This module enables the usage of [Private Service Connect](https://cloud.google.com/vpc/docs/private-service-connect) for a specific subnetwork. + +The resources created/managed by this module are: + +- Private DNS zone to configure `private.googleapis.com.` +- Private DNS zone to configure `gcr.io.` +- Private DNS zone to configure `pdk.dev.` +- Global Address resource to configure `Private Service Connect` endpoint +- Global Forwarding Rule resource to forward traffic to respective HTTP(S) load balancing + +## Usage + +Basic usage of this module is as follows: + +```hcl +module "private_service_connect" { + source = "terraform-google-modules/network/google//modules/private_service_connect" + + project_id = "" + network_self_link = "" + private_service_connect_ip = "10.3.0.5" + forwarding_rule_target = "all-apis" +} +``` + +Private Service Connect IP must fulfill requirements detailed [here](https://cloud.google.com/vpc/docs/configure-private-service-connect-apis#ip-address-requirements). + +Target subnetwork must have Private Google Access enabled. + +**Note:** All egress traffic is allowed from VPC internal networks by default. + +If you have a firewall rule blocking egress traffic, you will need to configure a [new egress rule](https://cloud.google.com/vpc/docs/using-firewalls#creating_firewall_rules) with following attributes: + +- Direction: Egress +- Priority: Higher than blocking egress rule +- Target tags: +- Destination filters: + - IP ranges: + - Protocols and ports: tcp:443 + +## Requirements + +- Cloud DNS API must be enabled. +- Service Account running Terraform must have `dns.managedZones.*` permissions. You can add them by assigning `DNS Admin` default role to the Service Account. + + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| dns\_code | Code to identify DNS resources in the form of `{dns_code}-{dns_type}` | `string` | `"dz"` | no | +| forwarding\_rule\_name | Forwarding rule resource name. The forwarding rule name for PSC Google APIs must be an 1-20 characters string with lowercase letters and numbers and must start with a letter. Defaults to `globalrule` | `string` | `"globalrule"` | no | +| forwarding\_rule\_target | Target resource to receive the matched traffic. Only `all-apis` and `vpc-sc` are valid. | `string` | n/a | yes | +| network\_self\_link | Network self link for Private Service Connect. | `string` | n/a | yes | +| private\_service\_connect\_ip | The internal IP to be used for the private service connect. | `string` | n/a | yes | +| private\_service\_connect\_name | Private Service Connect endpoint name. Defaults to `global-psconnect-ip` | `string` | `"global-psconnect-ip"` | no | +| project\_id | Project ID for Private Service Connect. | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| dns\_zone\_gcr\_name | Name for Managed DNS zone for GCR | +| dns\_zone\_googleapis\_name | Name for Managed DNS zone for GoogleAPIs | +| dns\_zone\_pkg\_dev\_name | Name for Managed DNS zone for PKG\_DEV | +| forwarding\_rule\_name | Forwarding rule resource name. | +| forwarding\_rule\_target | Target resource to receive the matched traffic. Only `all-apis` and `vpc-sc` are valid. | +| global\_address\_id | An identifier for the global address created for the private service connect with format `projects/{{project}}/global/addresses/{{name}}` | +| private\_service\_connect\_ip | Private service connect ip | +| private\_service\_connect\_name | Private service connect name | + + diff --git a/modules/private-service-connect/dns.tf b/modules/private-service-connect/dns.tf new file mode 100644 index 00000000..2ff0003c --- /dev/null +++ b/modules/private-service-connect/dns.tf @@ -0,0 +1,114 @@ +/** + * Copyright 2022 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. + */ + +/****************************************** + Private Google APIs DNS Zone & records. + *****************************************/ + +module "googleapis" { + source = "terraform-google-modules/cloud-dns/google" + version = "~> 4.1" + project_id = var.project_id + type = "private" + name = "${local.dns_code}apis" + domain = "googleapis.com." + description = "Private DNS zone to configure ${local.googleapis_url}" + + private_visibility_config_networks = [ + var.network_self_link + ] + + recordsets = [ + { + name = "*" + type = "CNAME" + ttl = 300 + records = [local.googleapis_url] + }, + { + name = local.recordsets_name + type = "A" + ttl = 300 + records = [var.private_service_connect_ip] + }, + ] +} + +/****************************************** + GCR DNS Zone & records. + *****************************************/ + +module "gcr" { + source = "terraform-google-modules/cloud-dns/google" + version = "~> 4.1" + project_id = var.project_id + type = "private" + name = "${local.dns_code}gcr" + domain = "gcr.io." + description = "Private DNS zone to configure gcr.io" + + private_visibility_config_networks = [ + var.network_self_link + ] + + recordsets = [ + { + name = "*" + type = "CNAME" + ttl = 300 + records = ["gcr.io."] + }, + { + name = "" + type = "A" + ttl = 300 + records = [var.private_service_connect_ip] + }, + ] +} + +/*********************************************** + Artifact Registry DNS Zone & records. + ***********************************************/ + +module "pkg_dev" { + source = "terraform-google-modules/cloud-dns/google" + version = "~> 4.1" + project_id = var.project_id + type = "private" + name = "${local.dns_code}pkg-dev" + domain = "pkg.dev." + description = "Private DNS zone to configure pkg.dev" + + private_visibility_config_networks = [ + var.network_self_link + ] + + recordsets = [ + { + name = "*" + type = "CNAME" + ttl = 300 + records = ["pkg.dev."] + }, + { + name = "" + type = "A" + ttl = 300 + records = [var.private_service_connect_ip] + }, + ] +} diff --git a/modules/private-service-connect/main.tf b/modules/private-service-connect/main.tf new file mode 100644 index 00000000..53bd647e --- /dev/null +++ b/modules/private-service-connect/main.tf @@ -0,0 +1,41 @@ +/** + * Copyright 2022 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. + */ + +locals { + dns_code = var.dns_code != "" ? "${var.dns_code}-" : "" + googleapis_url = var.forwarding_rule_target == "vpc-sc" ? "restricted.googleapis.com." : "private.googleapis.com." + recordsets_name = split(".", local.googleapis_url)[0] +} + +resource "google_compute_global_address" "private_service_connect" { + provider = google-beta + project = var.project_id + name = var.private_service_connect_name + address_type = "INTERNAL" + purpose = "PRIVATE_SERVICE_CONNECT" + network = var.network_self_link + address = var.private_service_connect_ip +} + +resource "google_compute_global_forwarding_rule" "forwarding_rule_private_service_connect" { + provider = google-beta + project = var.project_id + name = var.forwarding_rule_name + target = var.forwarding_rule_target + network = var.network_self_link + ip_address = google_compute_global_address.private_service_connect.id + load_balancing_scheme = "" +} diff --git a/modules/private-service-connect/outputs.tf b/modules/private-service-connect/outputs.tf new file mode 100644 index 00000000..ecd47908 --- /dev/null +++ b/modules/private-service-connect/outputs.tf @@ -0,0 +1,63 @@ +/** + * Copyright 2022 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 "private_service_connect_name" { + value = google_compute_global_address.private_service_connect.name + description = "Private service connect name" + + depends_on = [ + google_compute_global_forwarding_rule.forwarding_rule_private_service_connect + ] +} + +output "private_service_connect_ip" { + value = google_compute_global_address.private_service_connect.address + description = "Private service connect ip" + + depends_on = [ + google_compute_global_forwarding_rule.forwarding_rule_private_service_connect + ] +} + +output "global_address_id" { + value = google_compute_global_address.private_service_connect.id + description = "An identifier for the global address created for the private service connect with format `projects/{{project}}/global/addresses/{{name}}`" +} + +output "forwarding_rule_name" { + value = google_compute_global_forwarding_rule.forwarding_rule_private_service_connect.name + description = "Forwarding rule resource name." +} + +output "forwarding_rule_target" { + value = google_compute_global_forwarding_rule.forwarding_rule_private_service_connect.target + description = "Target resource to receive the matched traffic. Only `all-apis` and `vpc-sc` are valid." +} + +output "dns_zone_googleapis_name" { + value = module.googleapis.name + description = "Name for Managed DNS zone for GoogleAPIs" +} + +output "dns_zone_gcr_name" { + value = module.gcr.name + description = "Name for Managed DNS zone for GCR" +} + +output "dns_zone_pkg_dev_name" { + value = module.pkg_dev.name + description = "Name for Managed DNS zone for PKG_DEV" +} diff --git a/modules/private-service-connect/variables.tf b/modules/private-service-connect/variables.tf new file mode 100644 index 00000000..f0045575 --- /dev/null +++ b/modules/private-service-connect/variables.tf @@ -0,0 +1,58 @@ +/** + * Copyright 2022 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 "project_id" { + description = "Project ID for Private Service Connect." + type = string +} + +variable "network_self_link" { + description = "Network self link for Private Service Connect." + type = string +} + +variable "dns_code" { + description = "Code to identify DNS resources in the form of `{dns_code}-{dns_type}`" + type = string + default = "dz" +} + +variable "private_service_connect_name" { + description = "Private Service Connect endpoint name. Defaults to `global-psconnect-ip`" + type = string + default = "global-psconnect-ip" +} + +variable "private_service_connect_ip" { + description = "The internal IP to be used for the private service connect." + type = string +} + +variable "forwarding_rule_name" { + description = "Forwarding rule resource name. The forwarding rule name for PSC Google APIs must be an 1-20 characters string with lowercase letters and numbers and must start with a letter. Defaults to `globalrule`" + type = string + default = "globalrule" +} + +variable "forwarding_rule_target" { + description = "Target resource to receive the matched traffic. Only `all-apis` and `vpc-sc` are valid." + type = string + + validation { + condition = var.forwarding_rule_target == "all-apis" || var.forwarding_rule_target == "vpc-sc" + error_message = "For forwarding_rule_target only `all-apis` and `vpc-sc` are valid." + } +} diff --git a/modules/private-service-connect/versions.tf b/modules/private-service-connect/versions.tf new file mode 100644 index 00000000..89e7fab8 --- /dev/null +++ b/modules/private-service-connect/versions.tf @@ -0,0 +1,37 @@ +/** + * Copyright 2022 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.13" + required_providers { + google = { + source = "hashicorp/google" + version = ">= 3.50" + } + google-beta = { + source = "hashicorp/google-beta" + version = ">= 3.50" + } + } + + provider_meta "google" { + module_name = "blueprints/terraform/terraform-google-network:private-service-connect/v5.1.0" + } + + provider_meta "google-beta" { + module_name = "blueprints/terraform/terraform-google-network:private-service-connect/v5.1.0" + } +} diff --git a/test/integration/discover_test.go b/test/integration/discover_test.go new file mode 100644 index 00000000..349a396f --- /dev/null +++ b/test/integration/discover_test.go @@ -0,0 +1,25 @@ +// Copyright 2022 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. + +package test + +import ( + "testing" + + "github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test/pkg/tft" +) + +func TestAll(t *testing.T) { + tft.AutoDiscoverAndTest(t) +} diff --git a/test/integration/private_service_connect/private_service_connect_test.go b/test/integration/private_service_connect/private_service_connect_test.go new file mode 100644 index 00000000..0ba3a089 --- /dev/null +++ b/test/integration/private_service_connect/private_service_connect_test.go @@ -0,0 +1,60 @@ +// Copyright 2022 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. + +package psc + +import ( + "fmt" + "testing" + + "github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test/pkg/gcloud" + "github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test/pkg/tft" + "github.com/stretchr/testify/assert" +) + +func TestPrivateServiceConnect(t *testing.T) { + net := tft.NewTFBlueprintTest(t) + net.DefineVerify( + func(assert *assert.Assertions) { + net.DefaultVerify(assert) + projectID := net.GetStringOutput("project_id") + gcOpts := gcloud.WithCommonArgs([]string{"--project", projectID, "--format", "json"}) + + vpc := gcloud.Run(t, fmt.Sprintf("compute networks describe %s", net.GetStringOutput("network_name")), gcOpts) + assert.Equal(1, len(vpc.Get("subnetworks").Array()), "should be one subnet") + + for _, dnsOutputName := range []string{ + "dns_zone_googleapis_name", + "dns_zone_gcr_name", + "dns_zone_pkg_dev_name", + } { + dnsName := net.GetStringOutput(dnsOutputName) + dnsZone := gcloud.Run(t, fmt.Sprintf("dns managed-zones describe %s", dnsName), gcOpts) + assert.Equalf(dnsName, dnsZone.Get("name").String(), "dnsZone %s should exist", dnsName) + } + + gcOpts = gcloud.WithCommonArgs([]string{"--project", projectID, "--global", "--format", "json"}) + + globalAddressName := net.GetStringOutput("private_service_connect_name") + globalAddressIp := net.GetStringOutput("private_service_connect_ip") + globalAddress := gcloud.Run(t, fmt.Sprintf("compute addresses describe %s", globalAddressName), gcOpts) + assert.Equalf(globalAddressIp, globalAddress.Get("address").String(), "private service connect ip should be %s", globalAddressIp) + + forwardingRuleName := net.GetStringOutput("forwarding_rule_name") + forwardingRuleTarget := net.GetStringOutput("forwarding_rule_target") + forwardingRule := gcloud.Run(t, fmt.Sprintf("compute forwarding-rules describe %s", forwardingRuleName), gcOpts) + assert.Equalf(forwardingRuleTarget, forwardingRule.Get("target").String(), "forwarding rule should target to %s", forwardingRuleTarget) + }) + net.Test() +} diff --git a/test/setup/iam.tf b/test/setup/iam.tf index e8629d44..f3540f88 100644 --- a/test/setup/iam.tf +++ b/test/setup/iam.tf @@ -20,7 +20,8 @@ locals { "roles/compute.securityAdmin", "roles/iam.serviceAccountUser", "roles/vpcaccess.admin", - "roles/serviceusage.serviceUsageAdmin" + "roles/serviceusage.serviceUsageAdmin", + "roles/dns.admin" ] } diff --git a/test/setup/main.tf b/test/setup/main.tf index 30edd87a..5841f97f 100644 --- a/test/setup/main.tf +++ b/test/setup/main.tf @@ -28,6 +28,7 @@ module "project" { "cloudresourcemanager.googleapis.com", "compute.googleapis.com", "serviceusage.googleapis.com", - "vpcaccess.googleapis.com" + "vpcaccess.googleapis.com", + "dns.googleapis.com" ] }