diff --git a/.kitchen.yml b/.kitchen.yml index 9de35895..48f04d8d 100644 --- a/.kitchen.yml +++ b/.kitchen.yml @@ -50,6 +50,11 @@ suites: name: terraform command_timeout: 1800 root_module_directory: test/fixtures/compute_instance/simple + - name: instance_simple_zone + driver: + name: terraform + command_timeout: 1800 + root_module_directory: test/fixtures/compute_instance/simple_zone - name: disk_snapshot driver: name: terraform diff --git a/examples/compute_instance/simple/README.md b/examples/compute_instance/simple/README.md index 114f1971..e6f46cc9 100644 --- a/examples/compute_instance/simple/README.md +++ b/examples/compute_instance/simple/README.md @@ -14,6 +14,7 @@ This is a simple, minimal example of how to use the compute_instance module | region | The GCP region to create and test resources in | `string` | `"us-central1"` | no | | service\_account | Service account to attach to the instance. See https://www.terraform.io/docs/providers/google/r/compute_instance_template.html#service_account. |
object({| `null` | no | | subnetwork | The subnetwork selflink to host the compute instances in | `any` | n/a | yes | +| zone | The GCP zone to create resources in | `string` | `null` | no | ## Outputs diff --git a/examples/compute_instance/simple/main.tf b/examples/compute_instance/simple/main.tf index 1aed75d6..8a6d32df 100644 --- a/examples/compute_instance/simple/main.tf +++ b/examples/compute_instance/simple/main.tf @@ -30,6 +30,7 @@ module "instance_template" { module "compute_instance" { source = "../../../modules/compute_instance" region = var.region + zone = var.zone subnetwork = var.subnetwork num_instances = var.num_instances hostname = "instance-simple" diff --git a/examples/compute_instance/simple/variables.tf b/examples/compute_instance/simple/variables.tf index 6f10f6dc..842a3269 100644 --- a/examples/compute_instance/simple/variables.tf +++ b/examples/compute_instance/simple/variables.tf @@ -27,6 +27,12 @@ variable "region" { default = "us-central1" } +variable "zone" { + description = "The GCP zone to create resources in" + type = string + default = null +} + variable "subnetwork" { description = "The subnetwork selflink to host the compute instances in" } diff --git a/modules/compute_instance/README.md b/modules/compute_instance/README.md index 661c9550..6894c8d4 100644 --- a/modules/compute_instance/README.md +++ b/modules/compute_instance/README.md @@ -24,6 +24,7 @@ See the [simple](https://github.com/terraform-google-modules/terraform-google-vm | static\_ips | List of static IPs for VM instances | `list(string)` | `[]` | no | | subnetwork | Subnet to deploy to. Only one of network or subnetwork should be specified. | `string` | `""` | no | | subnetwork\_project | The project that subnetwork belongs to | `string` | `""` | no | +| zone | Zone where the instances should be created. If not specified, instances will be spread across available zones in the region. | `string` | `null` | no | ## Outputs diff --git a/modules/compute_instance/main.tf b/modules/compute_instance/main.tf index c6a4476b..f45de5c7 100644 --- a/modules/compute_instance/main.tf +++ b/modules/compute_instance/main.tf @@ -43,7 +43,7 @@ resource "google_compute_instance_from_template" "compute_instance" { count = local.num_instances name = "${local.hostname}-${format("%03d", count.index + 1)}" project = local.project_id - zone = data.google_compute_zones.available.names[count.index % length(data.google_compute_zones.available.names)] + zone = var.zone == null ? data.google_compute_zones.available.names[count.index % length(data.google_compute_zones.available.names)] : var.zone network_interface { network = var.network diff --git a/modules/compute_instance/variables.tf b/modules/compute_instance/variables.tf index 1f2e8c7e..3e9f6367 100644 --- a/modules/compute_instance/variables.tf +++ b/modules/compute_instance/variables.tf @@ -64,3 +64,8 @@ variable "region" { default = null } +variable "zone" { + type = string + description = "Zone where the instances should be created. If not specified, instances will be spread across available zones in the region." + default = null +} diff --git a/test/fixtures/compute_instance/simple_zone/main.tf b/test/fixtures/compute_instance/simple_zone/main.tf new file mode 100644 index 00000000..e6fc7604 --- /dev/null +++ b/test/fixtures/compute_instance/simple_zone/main.tf @@ -0,0 +1,26 @@ +/** + * 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. + */ + + +module "instance_simple" { + source = "../../../../examples/compute_instance/simple" + project_id = var.project_id + region = "us-central1" + zone = "us-central1-b" + subnetwork = google_compute_subnetwork.main.self_link + num_instances = 2 + service_account = var.service_account +} diff --git a/test/fixtures/compute_instance/simple_zone/network.tf b/test/fixtures/compute_instance/simple_zone/network.tf new file mode 120000 index 00000000..2a31e839 --- /dev/null +++ b/test/fixtures/compute_instance/simple_zone/network.tf @@ -0,0 +1 @@ +../../shared/network.tf \ No newline at end of file diff --git a/test/fixtures/compute_instance/simple_zone/outputs.tf b/test/fixtures/compute_instance/simple_zone/outputs.tf new file mode 100644 index 00000000..088dc41d --- /dev/null +++ b/test/fixtures/compute_instance/simple_zone/outputs.tf @@ -0,0 +1,26 @@ +/** + * 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. + */ + +output "instances_self_links" { + description = "List of instance self-links" + value = module.instance_simple.instances_self_links +} + +output "project_id" { + description = "The GCP project to use for integration tests" + value = var.project_id +} + diff --git a/test/fixtures/compute_instance/simple_zone/variables.tf b/test/fixtures/compute_instance/simple_zone/variables.tf new file mode 100644 index 00000000..841f41e2 --- /dev/null +++ b/test/fixtures/compute_instance/simple_zone/variables.tf @@ -0,0 +1,29 @@ +/** + * 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. + */ + +variable "project_id" { + description = "The GCP project to use for integration tests" +} + +variable "service_account" { + default = null + type = object({ + email = string + scopes = list(string) + }) + description = "Service account to attach to the instance. See https://www.terraform.io/docs/providers/google/r/compute_instance_template.html#service_account." +} + diff --git a/test/fixtures/compute_instance/simple_zone/versions.tf b/test/fixtures/compute_instance/simple_zone/versions.tf new file mode 100644 index 00000000..fb3fee63 --- /dev/null +++ b/test/fixtures/compute_instance/simple_zone/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/instance_simple_zone/controls/instance_simple_zone.rb b/test/integration/instance_simple_zone/controls/instance_simple_zone.rb new file mode 100644 index 00000000..c08f3fdc --- /dev/null +++ b/test/integration/instance_simple_zone/controls/instance_simple_zone.rb @@ -0,0 +1,60 @@ +# 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') + +expected_instances = 2 + +control "Compute Instances" do + title "Simple Configuration With Zone Specified" + + describe command("gcloud --project=#{project_id} compute instances list --format=json --filter='name~instance-simple*'") do + its(:exit_status) { should eq 0 } + its(:stderr) { should eq '' } + + let!(:data) do + if subject.exit_status == 0 + JSON.parse(subject.stdout) + else + [] + end + end + + describe "number of instances" do + it "should be #{expected_instances}" do + expect(data.length).to eq(expected_instances) + end + end + + describe "instance 001" do + let(:instance) do + data.find { |i| i['name'] == "instance-simple-001" } + end + + it "should be in zone us-central1-b}" do + expect(instance['zone']).to match(/.*us-central1-b$/) + end + end + + describe "instance 002" do + let(:instance) do + data.find { |i| i['name'] == "instance-simple-002" } + end + + it "should be in zone us-central1-b}" do + expect(instance['zone']).to match(/.*us-central1-b$/) + end + end + end +end diff --git a/test/integration/instance_simple_zone/inspec.yml b/test/integration/instance_simple_zone/inspec.yml new file mode 100644 index 00000000..24e88e1e --- /dev/null +++ b/test/integration/instance_simple_zone/inspec.yml @@ -0,0 +1,20 @@ +# 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. + +--- +name: instance_simple_zone +attributes: + - name: project_id + required: true + type: string
email = string,
scopes = set(string)
})