diff --git a/.kitchen.yml b/.kitchen.yml index 1617025d..ed06b86b 100644 --- a/.kitchen.yml +++ b/.kitchen.yml @@ -64,9 +64,23 @@ suites: color: true systems: - name: local + attrs_outputs: + customized_inspec_attribute: output_network_name + customized_inspec_attribute: output_network_self_link + customized_inspec_attribute: output_subnets_ips + customized_inspec_attribute: output_routes + customized_inspec_attribute: output_subnets_flow_logs + customized_inspec_attribute: output_subnets_names + customized_inspec_attribute: output_subnets_private_access + customized_inspec_attribute: output_subnets_regions + customized_inspec_attribute: output_subnets_secondary_ranges + customized_inspec_attribute: output_svpc_host_project_id + + backend: local controls: - gcloud + - inspec_attributes - name: "multi_vpc" driver: name: "terraform" @@ -107,6 +121,18 @@ suites: controls: - gcp - name: local + attrs_outputs: + customized_inspec_attribute: output_network_name + customized_inspec_attribute: output_network_self_link + customized_inspec_attribute: output_subnets_ips + customized_inspec_attribute: output_routes + customized_inspec_attribute: output_subnets_flow_logs + customized_inspec_attribute: output_subnets_names + customized_inspec_attribute: output_subnets_private_access + customized_inspec_attribute: output_subnets_regions + customized_inspec_attribute: output_subnets_secondary_ranges + customized_inspec_attribute: output_svpc_host_project_id backend: local controls: - gcloud + - inspec_attributes diff --git a/CHANGELOG.md b/CHANGELOG.md index 30e23f11..69ce66c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ The format is based on [Keep a Changelog][keepachangelog-site], and this project adheres to [Semantic Versioning][semver-site]. ## [Unreleased] +v2.0.0 is a backwards-incompatible release. Please see the [upgrading guide](./docs/upgrading_to_v2.0.md). + +### Fixed + +- Fixes subnet recreation when a subnet is updated. [#73] + ## [1.4.0] - 2019-10-14 diff --git a/docs/upgrading_to_v2.0.md b/docs/upgrading_to_v2.0.md new file mode 100644 index 00000000..cb397a0c --- /dev/null +++ b/docs/upgrading_to_v2.0.md @@ -0,0 +1,150 @@ +# Upgrading to v2.x + +The v2.x release of _google-network_ is a backwards incompatible +release. + +Because v2.x changed how the subnet resource is iterated on, resources in Terraform state need to be migrated in order to avoid the resources from getting destroyed and recreated. + +## Migration Instructions + +- Upgrade to the new version of this module. + +if you run `terraform plan` at this point. Terraform will inform you that it will attempt to delete and recreate your existing subnets. This is almost certainly not the behavior you want. For example: + +```Shell +Terraform will perform the following actions: + + # module.example.module.test-vpc-module.google_compute_subnetwork.subnetwork will be destroyed + - resource "google_compute_subnetwork" "subnetwork" { + - creation_timestamp = "2019-10-02T08:40:26.282-07:00" -> null + - enable_flow_logs = false -> null + - fingerprint = "f8LZx006zY4=" -> null + - gateway_address = "10.10.10.1" -> null + - id = "us-west1/simple-project-timh-subnet-01" -> null + - ip_cidr_range = "10.10.10.0/24" -> null + - name = "simple-project-timh-subnet-01" -> null + - network = "https://www.googleapis.com/compute/v1/projects/dev-xpn-networking/global/networks/simple-project-timh" -> null + - private_ip_google_access = false -> null + - project = "dev-xpn-networking" -> null + - region = "us-west1" -> null + - secondary_ip_range = [] -> null + - self_link = "https://www.googleapis.com/compute/v1/projects/dev-xpn-networking/regions/us-west1/subnetworks/simple-project-timh-subnet-01" -> null + } + + # module.example.module.test-vpc-module.google_compute_subnetwork.subnetwork[1] will be destroyed + - resource "google_compute_subnetwork" "subnetwork" { + - creation_timestamp = "2019-10-02T08:40:26.292-07:00" -> null + - enable_flow_logs = true -> null + - fingerprint = "wOwStN9lK-Q=" -> null + - gateway_address = "10.10.20.1" -> null + - id = "us-west1/simple-project-timh-subnet-02" -> null + - ip_cidr_range = "10.10.20.0/24" -> null + - name = "simple-project-timh-subnet-02" -> null + - network = "https://www.googleapis.com/compute/v1/projects/dev-xpn-networking/global/networks/simple-project-timh" -> null + - private_ip_google_access = true -> null + - project = "dev-xpn-networking" -> null + - region = "us-west1" -> null + - secondary_ip_range = [] -> null + - self_link = "https://www.googleapis.com/compute/v1/projects/dev-xpn-networking/regions/us-west1/subnetworks/simple-project-timh-subnet-02" -> null + } + + # module.example.module.test-vpc-module.google_compute_subnetwork.subnetwork["us-west1/simple-project-timh-subnet-01"] will be created + + resource "google_compute_subnetwork" "subnetwork" { + + creation_timestamp = (known after apply) + + enable_flow_logs = false + + fingerprint = (known after apply) + + gateway_address = (known after apply) + + id = (known after apply) + + ip_cidr_range = "10.10.10.0/24" + + name = "simple-project-timh-subnet-01" + + network = "simple-project-timh" + + private_ip_google_access = false + + project = "dev-xpn-networking" + + region = "us-west1" + + secondary_ip_range = [] + + self_link = (known after apply) + } + + # module.example.module.test-vpc-module.google_compute_subnetwork.subnetwork["us-west1/simple-project-timh-subnet-02"] will be created + + resource "google_compute_subnetwork" "subnetwork" { + + creation_timestamp = (known after apply) + + enable_flow_logs = true + + fingerprint = (known after apply) + + gateway_address = (known after apply) + + id = (known after apply) + + ip_cidr_range = "10.10.20.0/24" + + name = "simple-project-timh-subnet-02" + + network = "simple-project-timh" + + private_ip_google_access = true + + project = "dev-xpn-networking" + + region = "us-west1" + + secondary_ip_range = [] + + self_link = (known after apply) + } + +Plan: 2 to add, 0 to change, 2 to destroy. + +------------------------------------------------------------------------ + +Note: You didn't specify an "-out" parameter to save this plan, so Terraform +can't guarantee that exactly these actions will be performed if +"terraform apply" is subsequently run. +``` + +### Manual Migration Steps + +In this example here are the two commands used migrate the subnets created by the `simple_project` in the examples directory. _please note the need to escape the quotes on the new resource_. You may also use the migration script. + +- `terraform state mv module.example.module.test-vpc-module.google_compute_subnetwork.subnetwork[0] module.example.module.test-vpc-module.google_compute_subnetwork.subnetwork[\"us-west1/simple-project-timh-subnet-01\"]` + +- `terraform state mv module.example.module.test-vpc-module.google_compute_subnetwork.subnetwork[1] module.example.module.test-vpc-module.google_compute_subnetwork.subnetwork[\"us-west1/simple-project-timh-subnet-02\"]` + +`terraform plan` should now return a no-op and show no new changes. + +```Shell +$ terraform plan +Refreshing Terraform state in-memory prior to plan... +The refreshed state will be used to calculate this plan, but will not be +persisted to local or remote state storage. + +module.example.module.test-vpc-module.google_compute_network.network: Refreshing state... [id=simple-project-timh] +module.example.module.test-vpc-module.google_compute_subnetwork.subnetwork["us-west1/simple-project-timh-subnet-02"]: Refreshing state... [id=us-west1/simple-project-timh-subnet-02] +module.example.module.test-vpc-module.google_compute_subnetwork.subnetwork["us-west1/simple-project-timh-subnet-01"]: Refreshing state... [id=us-west1/simple-project-timh-subnet-01] + +------------------------------------------------------------------------ + +No changes. Infrastructure is up-to-date. + +This means that Terraform did not detect any differences between your +configuration and real physical resources that exist. As a result, no +actions need to be performed. +``` + +### Migration Script + +1. Download the script + + ```sh + curl -O https://raw.githubusercontent.com/terraform-google-modules/terraform-google-network/master/helpers/migrate.sh + chmod +x migrate.sh + ``` + +2. Run the script to output the migration commands: + + ```sh + $ ./migrate.sh --dry-run + terraform state mv module.example.module.test-vpc-module.google_compute_subnetwork.subnetwork[0] module.example.module.test-vpc-module.google_compute_subnetwork.subnetwork[\"us-west1/simple-project-timh-subnet-01\"] + terraform state mv module.example.module.test-vpc-module.google_compute_subnetwork.subnetwork[1] module.example.module.test-vpc-module.google_compute_subnetwork.subnetwork[\"us-west1/simple-project-timh-subnet-02\"] + ``` + +3. Execute the migration command + + ```sh + $ ./migrate.sh + Move "module.example.module.test-vpc-module.google_compute_subnetwork.subnetwork[0]" to "module.example.module.test-vpc-module.google_compute_subnetwork.subnetwork[\"us-west1/simple-project-timh-subnet-01\"]" + Successfully moved 1 object(s). + Move "module.example.module.test-vpc-module.google_compute_subnetwork.subnetwork[1]" to "module.example.module.test-vpc-module.google_compute_subnetwork.subnetwork[\"us-west1/simple-project-timh-subnet-02\"]" + Successfully moved 1 object(s). + ``` + +4. Run `terraform plan` to confirm no changes are expected. diff --git a/examples/secondary_ranges/README.md b/examples/secondary_ranges/README.md index b31e8e3c..3ffc4ec3 100644 --- a/examples/secondary_ranges/README.md +++ b/examples/secondary_ranges/README.md @@ -26,5 +26,6 @@ ranges and the third being given a single secondary range. | subnets\_private\_access | Whether the subnets will have access to Google API's without a public IP | | subnets\_regions | The region where subnets will be created | | subnets\_secondary\_ranges | The secondary ranges associated with these subnets | +| svpc\_host\_project\_id | Shared VPC host project id. | diff --git a/examples/secondary_ranges/outputs.tf b/examples/secondary_ranges/outputs.tf index 2ccc964a..95d5b63e 100644 --- a/examples/secondary_ranges/outputs.tf +++ b/examples/secondary_ranges/outputs.tf @@ -24,6 +24,11 @@ output "network_self_link" { description = "The URI of the VPC being created" } +output "svpc_host_project_id" { + value = module.vpc-secondary-ranges.svpc_host_project_id + description = "Shared VPC host project id." +} + output "subnets_names" { value = module.vpc-secondary-ranges.subnets_names description = "The names of the subnets being created" diff --git a/examples/simple_project/README.md b/examples/simple_project/README.md index 583a5c48..3f6cb802 100644 --- a/examples/simple_project/README.md +++ b/examples/simple_project/README.md @@ -25,5 +25,6 @@ This VPC has two subnets, with no secondary ranges. | subnets\_private\_access | Whether the subnets will have access to Google API's without a public IP | | subnets\_regions | The region where subnets will be created | | subnets\_secondary\_ranges | The secondary ranges associated with these subnets | +| svpc\_host\_project\_id | Shared VPC host project id. | diff --git a/examples/simple_project/outputs.tf b/examples/simple_project/outputs.tf index 429e0b97..b5f631cc 100644 --- a/examples/simple_project/outputs.tf +++ b/examples/simple_project/outputs.tf @@ -24,6 +24,11 @@ output "network_self_link" { description = "The URI of the VPC being created" } +output "svpc_host_project_id" { + value = module.test-vpc-module.svpc_host_project_id + description = "Shared VPC host project id." +} + output "subnets_names" { value = module.test-vpc-module.subnets_names description = "The names of the subnets being created" diff --git a/examples/simple_project_with_regional_network/README.md b/examples/simple_project_with_regional_network/README.md index 898c9e96..445f3111 100644 --- a/examples/simple_project_with_regional_network/README.md +++ b/examples/simple_project_with_regional_network/README.md @@ -25,5 +25,6 @@ This VPC has two subnets, with no secondary ranges. | subnets\_private\_access | Whether the subnets will have access to Google API's without a public IP | | subnets\_regions | The region where subnets will be created | | subnets\_secondary\_ranges | The secondary ranges associated with these subnets | +| svpc\_host\_project\_id | Shared VPC host project id. | diff --git a/examples/simple_project_with_regional_network/outputs.tf b/examples/simple_project_with_regional_network/outputs.tf index 429e0b97..b5f631cc 100644 --- a/examples/simple_project_with_regional_network/outputs.tf +++ b/examples/simple_project_with_regional_network/outputs.tf @@ -24,6 +24,11 @@ output "network_self_link" { description = "The URI of the VPC being created" } +output "svpc_host_project_id" { + value = module.test-vpc-module.svpc_host_project_id + description = "Shared VPC host project id." +} + output "subnets_names" { value = module.test-vpc-module.subnets_names description = "The names of the subnets being created" diff --git a/examples/submodule_firewall/README.md b/examples/submodule_firewall/README.md index 1cb360d8..faf52212 100644 --- a/examples/submodule_firewall/README.md +++ b/examples/submodule_firewall/README.md @@ -19,5 +19,14 @@ This VPC has two subnets, with no secondary ranges. | admin\_ranges | Firewall attributes for admin ranges. | | internal\_ranges | Firewall attributes for internal ranges. | | network\_name | The name of the VPC being created | +| network\_self\_link | The URI of the VPC being created | +| routes | The routes associated with this VPC | +| subnets\_flow\_logs | Whether the subnets will have VPC flow logs enabled | +| subnets\_ips | The IP and cidrs of the subnets being created | +| subnets\_names | The names of the subnets being created | +| subnets\_private\_access | Whether the subnets will have access to Google API's without a public IP | +| subnets\_regions | The region where subnets will be created | +| subnets\_secondary\_ranges | The secondary ranges associated with these subnets | +| svpc\_host\_project\_id | Shared VPC host project id. | diff --git a/examples/submodule_firewall/outputs.tf b/examples/submodule_firewall/outputs.tf index f687da74..0586334f 100644 --- a/examples/submodule_firewall/outputs.tf +++ b/examples/submodule_firewall/outputs.tf @@ -28,3 +28,48 @@ output "admin_ranges" { description = "Firewall attributes for admin ranges." value = module.test-firewall-submodule.admin_ranges } + +output "network_self_link" { + value = module.test-vpc-module.network_self_link + description = "The URI of the VPC being created" +} + +output "svpc_host_project_id" { + value = module.test-vpc-module.svpc_host_project_id + description = "Shared VPC host project id." +} + +output "subnets_names" { + value = module.test-vpc-module.subnets_names + description = "The names of the subnets being created" +} + +output "subnets_ips" { + value = module.test-vpc-module.subnets_ips + description = "The IP and cidrs of the subnets being created" +} + +output "subnets_regions" { + value = module.test-vpc-module.subnets_regions + description = "The region where subnets will be created" +} + +output "subnets_private_access" { + value = module.test-vpc-module.subnets_private_access + description = "Whether the subnets will have access to Google API's without a public IP" +} + +output "subnets_flow_logs" { + value = module.test-vpc-module.subnets_flow_logs + description = "Whether the subnets will have VPC flow logs enabled" +} + +output "subnets_secondary_ranges" { + value = module.test-vpc-module.subnets_secondary_ranges + description = "The secondary ranges associated with these subnets" +} + +output "routes" { + value = module.test-vpc-module.routes + description = "The routes associated with this VPC" +} diff --git a/helpers/migrate.sh b/helpers/migrate.sh new file mode 100755 index 00000000..752fc06a --- /dev/null +++ b/helpers/migrate.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash +# 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. +# shellcheck shell=bash +# Output Terraform Commands to migrate to new subnet config +set -e +set -o pipefail +CMD="terraform state" + +while (( "$#" )); do + # shellcheck disable=SC2221,SC2222 + case "$1" in + -d|--dry-run) + DRY_RUN=true + shift 1 + ;; + --) # end argument parsing + shift + break + ;; + -*|--*=) # unsupported flags + echo "Error: Unsupported flag $1" >&2 + exit 1 + ;; + *) # preserve positional arguments + PARAMS="$PARAMS $1" + shift + ;; + esac +done + +eval set -- "$PARAMS" + +if [ ! -e "$(command -v terraform)" ]; then + echo "can not find terraform" + exit 1 +fi + +MODULES=$(${CMD} list | grep google_compute_network.network) +for module in $MODULES; do + NAME=$(sed 's/.google_compute_network.network//' <<<"${module}") + for x in $($CMD list | grep "${NAME}".google_compute_subnetwork.subnetwork); do + ID=$(${CMD} show "$x" | grep id | grep -v ip_cidr_range | awk '{ print $3 }'| tr -d '"') + if [[ $DRY_RUN ]]; then + echo "${CMD} mv $x ${NAME}.google_compute_subnetwork.subnetwork[\\\"${ID}\\\"]" + else + ${CMD} mv "$x" "${NAME}".google_compute_subnetwork.subnetwork[\""${ID}"\"] + fi + done +done diff --git a/main.tf b/main.tf index 59e436df..3be7e062 100644 --- a/main.tf +++ b/main.tf @@ -14,6 +14,13 @@ * limitations under the License. */ +locals { + subnets = { + for x in var.subnets : + "${x.subnet_region}/${x.subnet_name}" => x + } +} + /****************************************** VPC configuration *****************************************/ @@ -38,25 +45,25 @@ resource "google_compute_shared_vpc_host_project" "shared_vpc_host" { Subnet configuration *****************************************/ resource "google_compute_subnetwork" "subnetwork" { - count = length(var.subnets) - - name = var.subnets[count.index]["subnet_name"] - ip_cidr_range = var.subnets[count.index]["subnet_ip"] - region = var.subnets[count.index]["subnet_region"] - private_ip_google_access = lookup(var.subnets[count.index], "subnet_private_access", "false") - enable_flow_logs = lookup(var.subnets[count.index], "subnet_flow_logs", "false") + for_each = local.subnets + name = each.value.subnet_name + ip_cidr_range = each.value.subnet_ip + region = each.value.subnet_region + private_ip_google_access = lookup(each.value, "subnet_private_access", "false") + enable_flow_logs = lookup(each.value, "subnet_flow_logs", "false") network = google_compute_network.network.name project = var.project_id - secondary_ip_range = [for i in range(length(contains(keys(var.secondary_ranges), var.subnets[count.index]["subnet_name"]) == true ? var.secondary_ranges[var.subnets[count.index]["subnet_name"]] : [])) : var.secondary_ranges[var.subnets[count.index]["subnet_name"]][i]] - description = lookup(var.subnets[count.index], "description", null) -} - -data "google_compute_subnetwork" "created_subnets" { - count = length(var.subnets) - name = element(google_compute_subnetwork.subnetwork.*.name, count.index) - region = element(google_compute_subnetwork.subnetwork.*.region, count.index) - project = var.project_id - depends_on = [google_compute_subnetwork.subnetwork] + description = lookup(each.value, "description", null) + secondary_ip_range = [ + for i in range( + length( + contains( + keys(var.secondary_ranges), each.value.subnet_name) == true + ? var.secondary_ranges[each.value.subnet_name] + : [] + )) : + var.secondary_ranges[each.value.subnet_name][i] + ] } /****************************************** diff --git a/outputs.tf b/outputs.tf index 09591656..11e707a9 100644 --- a/outputs.tf +++ b/outputs.tf @@ -30,37 +30,37 @@ output "svpc_host_project_id" { } output "subnets_names" { - value = google_compute_subnetwork.subnetwork.*.name + value = [for network in google_compute_subnetwork.subnetwork : network.name] description = "The names of the subnets being created" } output "subnets_ips" { - value = google_compute_subnetwork.subnetwork.*.ip_cidr_range + value = [for network in google_compute_subnetwork.subnetwork : network.ip_cidr_range] description = "The IPs and CIDRs of the subnets being created" } output "subnets_self_links" { - value = google_compute_subnetwork.subnetwork.*.self_link + value = [for network in google_compute_subnetwork.subnetwork : network.self_link] description = "The self-links of subnets being created" } output "subnets_regions" { - value = google_compute_subnetwork.subnetwork.*.region + value = [for network in google_compute_subnetwork.subnetwork : network.region] description = "The region where the subnets will be created" } output "subnets_private_access" { - value = google_compute_subnetwork.subnetwork.*.private_ip_google_access + value = [for network in google_compute_subnetwork.subnetwork : network.private_ip_google_access] description = "Whether the subnets will have access to Google API's without a public IP" } output "subnets_flow_logs" { - value = google_compute_subnetwork.subnetwork.*.enable_flow_logs + value = [for network in google_compute_subnetwork.subnetwork : network.enable_flow_logs] description = "Whether the subnets will have VPC flow logs enabled" } output "subnets_secondary_ranges" { - value = data.google_compute_subnetwork.created_subnets.*.secondary_ip_range + value = [for network in google_compute_subnetwork.subnetwork : network.secondary_ip_range] description = "The secondary ranges associated with these subnets" } @@ -68,4 +68,3 @@ output "routes" { value = google_compute_route.route.*.name description = "The routes associated with this VPC" } - diff --git a/test/fixtures/shared/outputs.tf b/test/fixtures/shared/outputs.tf index 68e9e076..fba7438b 100644 --- a/test/fixtures/shared/outputs.tf +++ b/test/fixtures/shared/outputs.tf @@ -23,3 +23,54 @@ output "network_name" { value = module.example.network_name description = "The name of the VPC being created" } + +output "output_network_name" { + value = module.example.network_name + description = "The name of the VPC being created" +} + +output "output_network_self_link" { + value = module.example.network_self_link + description = "The URI of the VPC being created" +} + +output "output_svpc_host_project_id" { + value = module.example.svpc_host_project_id + description = "Shared VPC host project id." +} + +output "output_subnets_names" { + value = module.example.subnets_names + description = "The names of the subnets being created" +} + +output "output_subnets_ips" { + value = module.example.subnets_ips + description = "The IP and cidrs of the subnets being created" +} + + +output "output_subnets_regions" { + value = module.example.subnets_regions + description = "The region where subnets will be created" +} + +output "output_subnets_private_access" { + value = module.example.subnets_private_access + description = "Whether the subnets will have access to Google API's without a public IP" +} + +output "output_subnets_flow_logs" { + value = module.example.subnets_flow_logs + description = "Whether the subnets will have VPC flow logs enabled" +} + +output "output_subnets_secondary_ranges" { + value = module.example.subnets_secondary_ranges + description = "The secondary ranges associated with these subnets" +} + +output "output_routes" { + value = module.example.routes + description = "The routes associated with this VPC" +} diff --git a/test/integration/secondary_ranges/controls/inspec_attributes.rb b/test/integration/secondary_ranges/controls/inspec_attributes.rb new file mode 100644 index 00000000..9e11b6cd --- /dev/null +++ b/test/integration/secondary_ranges/controls/inspec_attributes.rb @@ -0,0 +1,61 @@ +# 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 +# +# 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') +network_name = attribute('network_name') + +control "inspec_attributes" do + title "Terraform Outputs" + desc "Terraform Outputs" + + describe attribute("output_network_name") do + it { should eq "#{network_name}" } + end + + describe attribute("output_network_self_link") do + it { should eq "https://www.googleapis.com/compute/v1/projects/#{project_id}/global/networks/#{network_name}" } + end + + describe attribute("output_subnets_ips") do + it { should eq ["10.10.10.0/24", "10.10.20.0/24", "10.10.30.0/24", "10.10.40.0/24"] } + end + + describe attribute("output_routes") do + it { should eq [] } + end + + describe attribute("output_subnets_flow_logs") do + it { should eq [false, true, false, false] } + end + + describe attribute("output_subnets_names") do + it { should eq ["#{network_name}-subnet-01", "#{network_name}-subnet-02", "#{network_name}-subnet-03", "#{network_name}-subnet-04"] } + end + + describe attribute("output_subnets_private_access") do + it { should eq [false, true, false, false] } + end + + describe attribute("output_subnets_regions") do + it { should eq ["us-west1", "us-west1", "us-west1", "us-west1"] } + end + + describe attribute("output_subnets_secondary_ranges") do + it { should eq [{"ip_cidr_range"=>"192.168.64.0/24", "range_name"=>"#{network_name}-subnet-01-01"}, {"ip_cidr_range"=>"192.168.65.0/24", "range_name"=>"#{network_name}-subnet-01-02"}, {"ip_cidr_range"=>"192.168.66.0/24", "range_name"=>"#{network_name}-subnet-03-01"}] } + end + + describe attribute("output_svpc_host_project_id") do + it { should eq "" } + end +end diff --git a/test/integration/secondary_ranges/inspec.yml b/test/integration/secondary_ranges/inspec.yml index 94f1cbc6..ea9c3b05 100644 --- a/test/integration/secondary_ranges/inspec.yml +++ b/test/integration/secondary_ranges/inspec.yml @@ -6,3 +6,25 @@ attributes: - name: network_name required: true type: string + - name: output_network_name + required: true + type: string + - name: output_network_self_link + required: true + type: string + - name: output_subnets_ips + required: true + - name: output_routes + required: true + - name: output_subnets_flow_logs + required: true + - name: output_subnets_names + required: true + - name: output_subnets_private_access + required: true + - name: output_subnets_regions + required: true + - name: output_subnets_secondary_ranges + required: true + - name: output_svpc_host_project_id + required: true diff --git a/test/integration/submodule_firewall/controls/inspec_attributes.rb b/test/integration/submodule_firewall/controls/inspec_attributes.rb new file mode 100644 index 00000000..05ca71cb --- /dev/null +++ b/test/integration/submodule_firewall/controls/inspec_attributes.rb @@ -0,0 +1,61 @@ +# 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 +# +# 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') +network_name = attribute('network_name') + +control "inspec_attributes" do + title "Terraform Outputs" + desc "Terraform Outputs" + + describe attribute("output_network_name") do + it { should eq "#{network_name}" } + end + + describe attribute("output_network_self_link") do + it { should eq "https://www.googleapis.com/compute/v1/projects/#{project_id}/global/networks/#{network_name}" } + end + + describe attribute("output_subnets_ips") do + it { should eq ["10.10.10.0/24", "10.10.20.0/24"] } + end + + describe attribute("output_routes") do + it { should eq [] } + end + + describe attribute("output_subnets_flow_logs") do + it { should eq [false, true] } + end + + describe attribute("output_subnets_names") do + it { should eq ["#{network_name}-subnet-01", "#{network_name}-subnet-02"] } + end + + describe attribute("output_subnets_private_access") do + it { should eq [false, true] } + end + + describe attribute("output_subnets_regions") do + it { should eq ["us-west1", "us-west1"] } + end + + describe attribute("output_subnets_secondary_ranges") do + it { should eq [[],[]] } + end + + describe attribute("output_svpc_host_project_id") do + it { should eq "" } + end +end diff --git a/test/integration/submodule_firewall/inspec.yml b/test/integration/submodule_firewall/inspec.yml index 7e69b529..67efdd29 100644 --- a/test/integration/submodule_firewall/inspec.yml +++ b/test/integration/submodule_firewall/inspec.yml @@ -10,3 +10,25 @@ attributes: - name: network_name required: true type: string + - name: output_network_name + required: true + type: string + - name: output_network_self_link + required: true + type: string + - name: output_subnets_ips + required: true + - name: output_routes + required: true + - name: output_subnets_flow_logs + required: true + - name: output_subnets_names + required: true + - name: output_subnets_private_access + required: true + - name: output_subnets_regions + required: true + - name: output_subnets_secondary_ranges + required: true + - name: output_svpc_host_project_id + required: true