Skip to content

Commit 446ef4c

Browse files
committed
Updates for integration test CI pipeline
This commit includes changes necessary for enabling the integration testing CI pipeline being defined in Concourse. The Makefile has been updated to reference `test/ci_integration.sh` from the `make test_integration` target which will export the correct Cloud SDK environment variables based on environment variables coming out of the CI pipeline (namely `$SERVICE_ACCOUNT_JSON` and `$PROJECT_ID`), handle teardown of the environment correctly, and allow for the exit code of the verify step to be communicated back to CI (instead of the exit code from the destroy step). Also included is the `test/fixtures/simulated_ci_environment` scenario which can be used to setup a project and the same dependencies that are established by the CI pipeline. This will allow a module consumer to be able to test locally (or via the docker container) in the same way that CI testing is happening remotely.
1 parent c9fd6d9 commit 446ef4c

File tree

22 files changed

+437
-296
lines changed

22 files changed

+437
-296
lines changed

Gemfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@
1515
ruby '2.5.3'
1616

1717
source 'https://rubygems.org/' do
18-
gem 'kitchen-terraform', '~> 4.0.3'
18+
gem 'kitchen-terraform', '~> 4.3'
1919
end

Makefile

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,7 @@ check_headers:
6767
# Integration tests
6868
.PHONY: test_integration
6969
test_integration:
70-
bundle install
71-
bundle exec kitchen create
72-
bundle exec kitchen converge
73-
bundle exec kitchen converge
74-
bundle exec kitchen verify
75-
bundle exec kitchen destroy
70+
./test/ci_integration.sh
7671

7772
.PHONY: generate_docs
7873
generate_docs:
@@ -89,6 +84,7 @@ docker_run:
8984
docker run --rm -it \
9085
-e CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE=${CREDENTIALS_PATH} \
9186
-e GOOGLE_APPLICATION_CREDENTIALS=${CREDENTIALS_PATH} \
87+
-e TF_VAR_project_id \
9288
-v $(CURDIR):/cft/workdir \
9389
${DOCKER_REPO_BASE_KITCHEN_TERRAFORM} \
9490
/bin/bash
@@ -98,6 +94,7 @@ docker_create:
9894
docker run --rm -it \
9995
-e CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE=${CREDENTIALS_PATH} \
10096
-e GOOGLE_APPLICATION_CREDENTIALS=${CREDENTIALS_PATH} \
97+
-e TF_VAR_project_id \
10198
-v $(CURDIR):/cft/workdir \
10299
${DOCKER_REPO_BASE_KITCHEN_TERRAFORM} \
103100
/bin/bash -c "kitchen create"
@@ -107,6 +104,7 @@ docker_converge:
107104
docker run --rm -it \
108105
-e CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE=${CREDENTIALS_PATH} \
109106
-e GOOGLE_APPLICATION_CREDENTIALS=${CREDENTIALS_PATH} \
107+
-e TF_VAR_project_id \
110108
-v $(CURDIR):/cft/workdir \
111109
${DOCKER_REPO_BASE_KITCHEN_TERRAFORM} \
112110
/bin/bash -c "kitchen converge && kitchen converge"
@@ -116,6 +114,7 @@ docker_verify:
116114
docker run --rm -it \
117115
-e CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE=${CREDENTIALS_PATH} \
118116
-e GOOGLE_APPLICATION_CREDENTIALS=${CREDENTIALS_PATH} \
117+
-e TF_VAR_project_id \
119118
-v $(CURDIR):/cft/workdir \
120119
${DOCKER_REPO_BASE_KITCHEN_TERRAFORM} \
121120
/bin/bash -c "kitchen verify"
@@ -125,6 +124,7 @@ docker_destroy:
125124
docker run --rm -it \
126125
-e CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE=${CREDENTIALS_PATH} \
127126
-e GOOGLE_APPLICATION_CREDENTIALS=${CREDENTIALS_PATH} \
127+
-e TF_VAR_project_id \
128128
-v $(CURDIR):/cft/workdir \
129129
${DOCKER_REPO_BASE_KITCHEN_TERRAFORM} \
130130
/bin/bash -c "kitchen destroy"

examples/multi_vpc/outputs.tf

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,6 @@ output "network_01_routes" {
6060
description = "The routes associated with network-01"
6161
}
6262

63-
output "network_01_route_data" {
64-
value = "${local.network_01_routes}"
65-
description = "The route data for network 01 that was passed into the network module"
66-
}
67-
6863
# vpc 2
6964
output "network_02_name" {
7065
value = "${module.test-vpc-module-02.network_name}"
@@ -110,8 +105,3 @@ output "network_02_routes" {
110105
value = "${module.test-vpc-module-02.routes}"
111106
description = "The routes associated with network-02"
112107
}
113-
114-
output "network_02_route_data" {
115-
value = "${local.network_02_routes}"
116-
description = "The route data for network 02 that was passed into the network module"
117-
}

examples/secondary_ranges/main.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ resource "random_string" "random_suffix" {
2727
module "vpc-secondary-ranges" {
2828
source = "../../"
2929
project_id = "${var.project_id}"
30-
network_name = "test-network-${local.network_name}"
30+
network_name = "${local.network_name}"
3131

3232
subnets = [
3333
{

examples/simple_project_with_regional_network/main.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ resource "random_string" "random_suffix" {
2727
module "test-vpc-module" {
2828
source = "../../"
2929
project_id = "${var.project_id}"
30-
network_name = "test-network-${local.network_name}"
30+
network_name = "${local.network_name}"
3131
routing_mode = "REGIONAL"
3232

3333
subnets = [

test/ci_integration.sh

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#! /bin/bash
2+
# Copyright 2018 Google LLC
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
# Entry point for CI Integration Tests. This script is expected to be run
17+
# inside the same docker image specified in the CI Pipeline definition.
18+
19+
# Always clean up.
20+
DELETE_AT_EXIT="$(mktemp -d)"
21+
22+
finish() {
23+
echo 'BEGIN: finish() trap handler' >&2
24+
set +e
25+
bundle exec kitchen destroy
26+
[[ -d "${DELETE_AT_EXIT}" ]] && rm -rf "${DELETE_AT_EXIT}"
27+
echo 'END: finish() trap handler' >&2
28+
}
29+
30+
# Map the input parameters provided by Concourse CI, or whatever mechanism is
31+
# running the tests to Terraform input variables. Also setup credentials for
32+
# use with kitchen-terraform, inspec, and gcloud.
33+
setup_environment() {
34+
local tmpfile
35+
tmpfile="$(mktemp)"
36+
echo "${SERVICE_ACCOUNT_JSON}" > "${tmpfile}"
37+
38+
# Terraform and most other tools respect GOOGLE_CREDENTIALS
39+
export GOOGLE_CREDENTIALS="${SERVICE_ACCOUNT_JSON}"
40+
# gcloud variables
41+
export CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE="${tmpfile}"
42+
export CLOUDSDK_CORE_PROJECT="${PROJECT_ID}"
43+
export GOOGLE_APPLICATION_CREDENTIALS="${tmpfile}"
44+
45+
# Terraform input variables
46+
export TF_VAR_project_id="${PROJECT_ID}"
47+
}
48+
49+
main() {
50+
set -eu
51+
# Setup trap handler to auto-cleanup
52+
export TMPDIR="${DELETE_AT_EXIT}"
53+
trap finish EXIT
54+
55+
# Setup environment
56+
setup_environment
57+
set -x
58+
# Execute the test lifecycle
59+
bundle install --path vendor
60+
bundle exec kitchen create
61+
bundle exec kitchen converge -c 4
62+
bundle exec kitchen verify
63+
}
64+
65+
# if script is being executed and not sourced.
66+
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
67+
main "$@"
68+
fi

test/fixtures/all_examples/test_output.tf

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,6 @@
1818
// They do not need to be included in real-world uses of this module
1919

2020
output "project_id" {
21-
value = "${var.project_id}"
21+
value = "${var.project_id}"
22+
description = "The ID of the project to which resources are applied."
2223
}

test/fixtures/multi_vpc/outputs.tf

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -18,33 +18,3 @@ output "project_id" {
1818
value = "${var.project_id}"
1919
description = "The ID of the project being used"
2020
}
21-
22-
output "network_01_name" {
23-
value = "${module.example.network_01_name}"
24-
description = "The name of the VPC network-01"
25-
}
26-
27-
output "network_01_routes" {
28-
value = "${module.example.network_01_routes}"
29-
description = "The routes associated with network-01"
30-
}
31-
32-
output "network_01_route_data" {
33-
value = "${module.example.network_01_route_data}"
34-
description = "The route data for network 01 that was passed into the network module"
35-
}
36-
37-
output "network_02_name" {
38-
value = "${module.example.network_02_name}"
39-
description = "The name of the VPC network-02"
40-
}
41-
42-
output "network_02_routes" {
43-
value = "${module.example.network_02_routes}"
44-
description = "The routes associated with network-02"
45-
}
46-
47-
output "network_02_route_data" {
48-
value = "${module.example.network_02_route_data}"
49-
description = "The route data for network 02 that was passed into the network module"
50-
}

test/fixtures/shared/outputs.tf

Lines changed: 1 addition & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -19,47 +19,7 @@ output "project_id" {
1919
description = "The ID of the project being used"
2020
}
2121

22-
output "network_self_link" {
23-
value = "${module.example.network_self_link}"
24-
description = "The URI of the VPC being created"
25-
}
26-
2722
output "network_name" {
2823
value = "${module.example.network_name}"
29-
description = "The name of the VPC network being created"
30-
}
31-
32-
output "subnets_names" {
33-
value = "${module.example.subnets_names}"
34-
description = "The names of the subnets being created"
35-
}
36-
37-
output "subnets_ips" {
38-
value = "${module.example.subnets_ips}"
39-
description = "The IP and cidrs of the subnets being created"
40-
}
41-
42-
output "subnets_regions" {
43-
value = "${module.example.subnets_regions}"
44-
description = "The region where subnets will be created"
45-
}
46-
47-
output "subnets_private_access" {
48-
value = "${module.example.subnets_private_access}"
49-
description = "Whether the subnets will have access to Google API's without a public IP"
50-
}
51-
52-
output "subnets_flow_logs" {
53-
value = "${module.example.subnets_flow_logs}"
54-
description = "Whether the subnets will have VPC flow logs enabled"
55-
}
56-
57-
output "subnets_secondary_ranges" {
58-
value = "${module.example.subnets_secondary_ranges}"
59-
description = "The secondary ranges associated with these subnets"
60-
}
61-
62-
output "routes" {
63-
value = "${module.example.routes}"
64-
description = "The routes associated with this VPC"
24+
description = "The name of the VPC being created"
6525
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Integration Testing
2+
3+
Use this directory to create resources reflecting the same resource fixtures
4+
created for use by the CI environment CI integration test pipelines. The intent
5+
of these resources is to run the integration tests locally as closely as
6+
possible to how they will run in the CI system.
7+
8+
Once created, store the service account key content into the
9+
`GOOGLE_CREDENTIALS` environment variable. This reflects the same behavior as
10+
used in CI.
11+
12+
For example:
13+
14+
```bash
15+
terraform init
16+
terraform apply
17+
terraform output service_account_private_key > ~/.credentials/network-sa.json
18+
```
19+
20+
Then, configure the environment (suggest using direnv) like so:
21+
22+
```bash
23+
export GOOGLE_CREDENTIALS_PATH="${HOME}/.credentials/network-sa.json"
24+
export GOOGLE_CREDENTIALS="${HOME}/.credentials/network-sa.json"
25+
export TF_VAR_project_id="network-module"
26+
```
27+
28+
With these variables set, change to the root of the module and execute the `make test_integration` task.
29+
This make target is the same that is executed by this module's CI pipeline during integration testing, and
30+
will run the integration tests from your machine.
31+
32+
Alternatively, to run the integration tests directly from the Docker container used by the module's CI pipeline, copy
33+
the credentials file to the root of the module and then run the `make test_integration_docker` target:
34+
35+
```
36+
# Change to the root of the module
37+
cd /path/to/module
38+
39+
# Copy credentials and run test
40+
cp $GOOGLE_CREDENTIALS_PATH ./credentials.json
41+
make test_integration_docker
42+
```
43+
44+
[^]: (autogen_docs_start)
45+
46+
47+
## Inputs
48+
49+
| Name | Description | Type | Default | Required |
50+
|------|-------------|:----:|:-----:|:-----:|
51+
| billing_account | The billing account id associated with the project, e.g. XXXXXX-YYYYYY-ZZZZZZ | string | - | yes |
52+
| folder_id | The numeric folder id to create resources | string | - | yes |
53+
| organization_id | The numeric organization id | string | - | yes |
54+
| region | The region to deploy to | string | `us-west1` | no |
55+
56+
## Outputs
57+
58+
| Name | Description |
59+
|------|-------------|
60+
| service_account_private_key | The SA KEY JSON content. Store in GOOGLE_CREDENTIALS. |
61+
62+
[^]: (autogen_docs_end)

0 commit comments

Comments
 (0)