Skip to content

Commit 86baa96

Browse files
authored
Merge pull request #33 from terraform-google-modules/feature/automatic-fixture-network-creation
Build Network Fixtures and Run Tests with Kitchen-Terraform
2 parents f057964 + 4a32e01 commit 86baa96

File tree

104 files changed

+2716
-999
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

104 files changed

+2716
-999
lines changed

.gitignore

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,9 @@ crash.log
3838
**/.kitchen.local.yml
3939
**/Gemfile.lock
4040

41-
# Ignore any .tfvars files that are generated automatically for each Terraform run. Most
42-
# .tfvars files are managed as part of configuration and so should be included in
43-
# version control.
44-
#
45-
# example.tfvars
46-
**/terraform.tfvars
41+
test/fixtures/shared/terraform.tfvars
4742

4843
test/integration/gcloud/config.sh
4944
test/integration/tmp
45+
46+
credentials.json

.kitchen.yml

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# Copyright 2018 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
---
16+
driver:
17+
name: "terraform"
18+
command_timeout: 1800
19+
20+
provisioner:
21+
name: "terraform"
22+
23+
platforms:
24+
- name: local
25+
26+
suites:
27+
- name: "deploy_service"
28+
driver:
29+
name: "terraform"
30+
command_timeout: 1800
31+
root_module_directory: test/fixtures/deploy_service
32+
verifier:
33+
name: terraform
34+
systems:
35+
- name: deploy_service
36+
backend: local
37+
provisioner:
38+
name: terraform
39+
- name: "node_pool"
40+
driver:
41+
name: "terraform"
42+
command_timeout: 1800
43+
root_module_directory: test/fixtures/node_pool
44+
verifier:
45+
name: terraform
46+
systems:
47+
- name: node_pool
48+
backend: local
49+
provisioner:
50+
name: terraform
51+
- name: "shared_vpc"
52+
driver:
53+
name: "terraform"
54+
command_timeout: 1800
55+
root_module_directory: test/fixtures/shared_vpc
56+
verifier:
57+
name: terraform
58+
systems:
59+
- name: shared_vpc
60+
backend: local
61+
provisioner:
62+
name: terraform
63+
- name: "simple_regional"
64+
driver:
65+
name: "terraform"
66+
command_timeout: 1800
67+
root_module_directory: test/fixtures/simple_regional
68+
verifier:
69+
name: terraform
70+
systems:
71+
- name: simple_regional
72+
backend: local
73+
provisioner:
74+
name: terraform
75+
- name: "simple_zonal"
76+
driver:
77+
name: "terraform"
78+
command_timeout: 1800
79+
root_module_directory: test/fixtures/simple_zonal
80+
verifier:
81+
name: terraform
82+
systems:
83+
- name: simple_zonal
84+
backend: local
85+
provisioner:
86+
name: terraform
87+
- name: "stub_domains"
88+
driver:
89+
name: "terraform"
90+
command_timeout: 1800
91+
root_module_directory: test/fixtures/stub_domains
92+
verifier:
93+
name: terraform
94+
systems:
95+
- name: stub_domains
96+
backend: local
97+
provisioner:
98+
name: terraform

.ruby-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
2.5.3

test/integration/gcloud/Gemfile renamed to Gemfile

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,10 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
ruby '2.4.2'
15+
ruby "~> 2.5"
1616

1717
source 'https://rubygems.org/' do
18-
gem 'googleauth'
19-
gem 'google-api-client'
20-
gem 'kitchen-terraform', '~> 3.3'
21-
gem 'kitchen-inspec', :git => 'https://github.com/inspec/kitchen-inspec.git', :ref => '0590f1b'
18+
gem "kitchen-terraform", "~> 4.0"
19+
gem "kubeclient", "~> 4.0"
20+
gem "rest-client", "~> 2.0"
2221
end

Makefile

Lines changed: 84 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,17 @@
1515
# Make will use bash instead of sh
1616
SHELL := /usr/bin/env bash
1717

18+
# Docker build config variables
19+
BUILD_TERRAFORM_VERSION ?= 0.11.10
20+
BUILD_CLOUD_SDK_VERSION ?= 216.0.0
21+
BUILD_PROVIDER_GOOGLE_VERSION ?= 1.17.1
22+
BUILD_PROVIDER_GSUITE_VERSION ?= 0.1.8
23+
DOCKER_IMAGE_TERRAFORM := cftk/terraform
24+
DOCKER_TAG_TERRAFORM ?= ${BUILD_TERRAFORM_VERSION}_${BUILD_CLOUD_SDK_VERSION}_${BUILD_PROVIDER_GOOGLE_VERSION}_${BUILD_PROVIDER_GSUITE_VERSION}
25+
BUILD_RUBY_VERSION := 2.5.3
26+
DOCKER_IMAGE_KITCHEN_TERRAFORM := cftk/kitchen_terraform
27+
DOCKER_TAG_KITCHEN_TERRAFORM ?= ${BUILD_TERRAFORM_VERSION}_${BUILD_CLOUD_SDK_VERSION}_${BUILD_PROVIDER_GOOGLE_VERSION}_${BUILD_PROVIDER_GSUITE_VERSION}
28+
1829
# All is the first target in the file so it will get picked up when you just run 'make' on its own
1930
all: check_shell check_python check_golang check_terraform check_docker check_base_files test_check_headers check_headers check_trailing_whitespace generate_docs
2031

@@ -63,20 +74,80 @@ check_headers:
6374
@echo "Checking file headers"
6475
@python test/verify_boilerplate.py
6576

77+
# Integration tests
78+
.PHONY: test_integration
79+
test_integration:
80+
bundle install
81+
bundle exec kitchen create
82+
bundle exec kitchen converge
83+
bundle exec kitchen converge
84+
bundle exec kitchen verify
85+
bundle exec kitchen destroy
86+
6687
.PHONY: generate_docs
6788
generate_docs:
6889
@source test/make.sh && generate_docs
6990

70-
# Integration tests
71-
72-
.PHONY: regional_test_integration
73-
regional_test_integration:
74-
./test/integration/gcloud/run.sh regional
75-
76-
.PHONY: zonal_test_integration
77-
zonal_test_integration:
78-
./test/integration/gcloud/run.sh zonal
79-
80-
.PHONY: test_integration
81-
test_integration: regional_test_integration zonal_test_integration
82-
@echo "Running tests for regional and zonal clusters"
91+
# Versioning
92+
.PHONY: version
93+
version:
94+
@source helpers/version-repo.sh
95+
96+
# Build Docker
97+
.PHONY: docker_build_terraform
98+
docker_build_terraform:
99+
docker build -f build/docker/terraform/Dockerfile \
100+
--build-arg BUILD_TERRAFORM_VERSION=${BUILD_TERRAFORM_VERSION} \
101+
--build-arg BUILD_CLOUD_SDK_VERSION=${BUILD_CLOUD_SDK_VERSION} \
102+
--build-arg BUILD_PROVIDER_GOOGLE_VERSION=${BUILD_PROVIDER_GOOGLE_VERSION} \
103+
--build-arg BUILD_PROVIDER_GSUITE_VERSION=${BUILD_PROVIDER_GSUITE_VERSION} \
104+
--build-arg CREDENTIALS_FILE=${CREDENTIALS_FILE} \
105+
-t ${DOCKER_IMAGE_TERRAFORM}:${DOCKER_TAG_TERRAFORM} .
106+
107+
.PHONY: docker_build_kitchen_terraform
108+
docker_build_kitchen_terraform:
109+
docker build -f build/docker/kitchen_terraform/Dockerfile \
110+
--build-arg BUILD_TERRAFORM_IMAGE="${DOCKER_IMAGE_TERRAFORM}:${DOCKER_TAG_TERRAFORM}" \
111+
--build-arg BUILD_RUBY_VERSION="${BUILD_RUBY_VERSION}" \
112+
--build-arg CREDENTIALS_FILE="${CREDENTIALS_FILE}" \
113+
-t ${DOCKER_IMAGE_KITCHEN_TERRAFORM}:${DOCKER_TAG_KITCHEN_TERRAFORM} .
114+
115+
# Run docker
116+
.PHONY: docker_run
117+
docker_run:
118+
docker run --rm -it \
119+
-v $(CURDIR):/cftk/workdir \
120+
${DOCKER_IMAGE_KITCHEN_TERRAFORM}:${DOCKER_TAG_KITCHEN_TERRAFORM} \
121+
/bin/bash
122+
123+
.PHONY: docker_create
124+
docker_create: docker_build_terraform docker_build_kitchen_terraform
125+
docker run --rm -it \
126+
-v $(CURDIR):/cftk/workdir \
127+
${DOCKER_IMAGE_KITCHEN_TERRAFORM}:${DOCKER_TAG_KITCHEN_TERRAFORM} \
128+
/bin/bash -c "kitchen create"
129+
130+
.PHONY: docker_converge
131+
docker_converge:
132+
docker run --rm -it \
133+
-v $(CURDIR):/cftk/workdir \
134+
${DOCKER_IMAGE_KITCHEN_TERRAFORM}:${DOCKER_TAG_KITCHEN_TERRAFORM} \
135+
/bin/bash -c "kitchen converge && kitchen converge"
136+
137+
.PHONY: docker_verify
138+
docker_verify:
139+
docker run --rm -it \
140+
-v $(CURDIR):/cftk/workdir \
141+
${DOCKER_IMAGE_KITCHEN_TERRAFORM}:${DOCKER_TAG_KITCHEN_TERRAFORM} \
142+
/bin/bash -c "kitchen verify"
143+
144+
.PHONY: docker_destroy
145+
docker_destroy:
146+
docker run --rm -it \
147+
-v $(CURDIR):/cftk/workdir \
148+
${DOCKER_IMAGE_KITCHEN_TERRAFORM}:${DOCKER_TAG_KITCHEN_TERRAFORM} \
149+
/bin/bash -c "kitchen destroy"
150+
151+
.PHONY: test_integration_docker
152+
test_integration_docker: docker_create docker_converge docker_verify docker_destroy
153+
@echo "Running test-kitchen tests in docker"

README.md

Lines changed: 61 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ Then perform the following commands on the root folder:
9797
| ip_range_pods | The secondary ip range to use for pods | string | - | yes |
9898
| ip_range_services | The secondary ip range to use for pods | string | - | yes |
9999
| kubernetes_dashboard | Enable kubernetes dashboard addon | string | `false` | no |
100-
| kubernetes_version | The Kubernetes version of the masters. If set to 'latest' it will pull latest available version in the selected region. | string | `1.10.6-gke.2` | no |
100+
| kubernetes_version | The Kubernetes version of the masters. If set to 'latest' it will pull latest available version in the selected region. | string | `latest` | no |
101101
| logging_service | The logging service that the cluster should write logs to. Available options include logging.googleapis.com, logging.googleapis.com/kubernetes (beta), and none | string | `logging.googleapis.com` | no |
102102
| maintenance_start_time | Time window specified for daily maintenance operations in RFC3339 format | string | `05:00` | no |
103103
| master_authorized_networks_config | The desired configuration options for master authorized networks. Omit the nested cidr_blocks attribute to disallow external access (except the cluster node IPs, which GKE automatically whitelists)<br><br> ### example format ### master_authorized_networks_config = [{ cidr_blocks = [{ cidr_block = "10.0.0.0/8" display_name = "example_network" }], }] | list | `<list>` | no |
@@ -115,6 +115,7 @@ Then perform the following commands on the root folder:
115115
| project_id | The project ID to host the cluster in (required) | string | - | yes |
116116
| region | The region to host the cluster in (required) | string | - | yes |
117117
| regional | Whether is a regional cluster (zonal cluster if set false. WARNING: changing this after cluster creation is destructive!) | string | `true` | no |
118+
| service_account | The service account to default running nodes as if not overridden in `node_pools`. Defaults to the compute engine default service account | string | `` | no |
118119
| stub_domains | Map of stub domains and their resolvers to forward DNS queries for a certain domain to an external DNS server | map | `<map>` | no |
119120
| subnetwork | The subnetwork to host the cluster in (required) | string | - | yes |
120121
| zones | The zones to host the cluster in (optional if regional cluster / required if zonal) | list | `<list>` | no |
@@ -163,12 +164,12 @@ The [project factory](https://github.com/terraform-google-modules/terraform-goog
163164
- [terraform-provider-google](https://github.com/terraform-providers/terraform-provider-google) plugin v1.8.0
164165

165166
### Configure a Service Account
166-
In order to execute this module you must have a Service Account with the following:
167-
168-
#### IAM Roles
169-
The service account with the following roles:
170-
- roles/compute.viewer on the project
171-
- roles/container.clusterAdmin on the project
167+
In order to execute this module you must have a Service Account with the
168+
following project roles:
169+
- roles/compute.viewer
170+
- roles/container.clusterAdmin
171+
- roles/container.developer
172+
- roles/iam.serviceAccountUser
172173

173174
### Enable APIs
174175
In order to operate with the Service Account you must activate the following APIs on the project where the Service Account was created:
@@ -199,7 +200,6 @@ The project has the following folders and files:
199200
### Requirements
200201
- [bundler](https://github.com/bundler/bundler)
201202
- [gcloud](https://cloud.google.com/sdk/install)
202-
- [jq](https://stedolan.github.io/jq/) 1.5
203203
- [terraform-docs](https://github.com/segmentio/terraform-docs/releases) 0.3.0
204204

205205
### Autogeneration of documentation from .tf files
@@ -209,27 +209,59 @@ make generate_docs
209209
```
210210

211211
### Integration test
212-
#### Terraform integration tests
213-
The integration tests for this module leverage [kitchen-terraform](https://github.com/newcontext-oss/kitchen-terraform) and [kitchen-inspec](https://github.com/inspec/kitchen-inspec).
214-
215-
The tests will do the following:
216-
- Perform `bundle install` command
217-
- Installs `kitchen-terraform` and `kitchen-inspec` gems
218-
- Perform `kitchen create` command
219-
- Performs a `terraform init`
220-
- Perform `kitchen converge` command
221-
- Performs a `terraform apply -auto-approve`
222-
- Perform `kitchen validate` command
223-
- Performs inspec tests.
224-
- Shell out to `gcloud` to validate expected resources in GCP.
225-
- Shell out to `kubectl` to validate expected resource in Kubernetes.
226-
- Shell out to `terraform` to validate outputs.
227-
- Permos `kitchen destroy` command
228-
- Performs a `terraform destroy -force`
229-
230-
You can use the following command to run the integration test in the root folder
231-
232-
`make test_integration`
212+
213+
Integration tests are run though [test-kitchen](https://github.com/test-kitchen/test-kitchen), [kitchen-terraform](https://github.com/newcontext-oss/kitchen-terraform), and [InSpec](https://github.com/inspec/inspec).
214+
215+
Six test-kitchen instances are defined:
216+
217+
- `deploy_service`
218+
- `node_pool`
219+
- `shared_vpc`
220+
- `simple_regional`
221+
- `simple_zonal`
222+
- `stub_domains`
223+
224+
The test-kitchen instances in `test/fixtures/` wrap identically-named examples in the `examples/` directory.
225+
226+
#### Setup
227+
228+
1. Configure the [test fixtures](#test-configuration)
229+
2. Download a Service Account key with the necessary permissions and put it in the module's root directory with the name `credentials.json`.
230+
3. Build the Docker containers for testing:
231+
232+
```
233+
CREDENTIALS_FILE="credentials.json" make docker_build_terraform
234+
CREDENTIALS_FILE="credentials.json" make docker_build_kitchen_terraform
235+
```
236+
4. Run the testing container in interactive mode:
237+
238+
```
239+
make docker_run
240+
```
241+
242+
The module root directory will be loaded into the Docker container at `/cftk/workdir/`.
243+
5. Run kitchen-terraform to test the infrastructure:
244+
245+
1. `kitchen create` creates Terraform state and downloads modules, if applicable.
246+
2. `kitchen converge` creates the underlying resources. Run `kitchen converge <INSTANCE_NAME>` to create resources for a specific test case.
247+
3. `kitchen verify` tests the created infrastructure. Run `kitchen verify <INSTANCE_NAME>` to run a specific test case.
248+
4. `kitchen destroy` tears down the underlying resources created by `kitchen converge`. Run `kitchen destroy <INSTANCE_NAME>` to tear down resources for a specific test case.
249+
250+
Alternatively, you can simply run `CREDENTIALS_FILE="credentials.json" make test_integration_docker` to run all the test steps non-interactively.
251+
252+
#### Test configuration
253+
254+
Each test-kitchen instance is configured with a `variables.tfvars` file in the test fixture directory, e.g. `test/fixtures/node_pool/terraform.tfvars`.
255+
For convenience, since all of the variables are project-specific, these files have been symlinked to `test/fixtures/shared/terraform.tfvars`.
256+
Similarly, each test fixture has a `variables.tf` to define these variables, and an `outputs.tf` to facilitate providing necessary information for `inspec` to locate and query against created resources.
257+
258+
Each test-kitchen instance creates a GCP Network and Subnetwork fixture to house resources, and may create any other necessary fixture data as needed.
259+
260+
### Autogeneration of documentation from .tf files
261+
Run
262+
```
263+
make generate_docs
264+
```
233265

234266
### Linting
235267
The makefile in this project will lint or sometimes just format any shell,

0 commit comments

Comments
 (0)