Skip to content

Commit 2a1f786

Browse files
committed
Update testing to CloudBuild and general linting #17
1 parent d501017 commit 2a1f786

32 files changed

+381
-867
lines changed

CONTRIBUTING.md

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# Contributing
2+
3+
This document provides guidelines for contributing to the module.
4+
5+
## Dependencies
6+
7+
The following dependencies must be installed on the development system:
8+
9+
- [Docker Engine][docker-engine]
10+
- [Google Cloud SDK][google-cloud-sdk]
11+
- [make]
12+
13+
## Generating Documentation for Inputs and Outputs
14+
15+
The Inputs and Outputs tables in the READMEs of the root module,
16+
submodules, and example modules are automatically generated based on
17+
the `variables` and `outputs` of the respective modules. These tables
18+
must be refreshed if the module interfaces are changed.
19+
20+
### Execution
21+
22+
Run `make generate_docs` to generate new Inputs and Outputs tables.
23+
24+
## Integration Testing
25+
26+
Integration tests are used to verify the behaviour of the root module,
27+
submodules, and example modules. Additions, changes, and fixes should
28+
be accompanied with tests.
29+
30+
The integration tests are run using [Kitchen][kitchen],
31+
[Kitchen-Terraform][kitchen-terraform], and [InSpec][inspec]. These
32+
tools are packaged within a Docker image for convenience.
33+
34+
The general strategy for these tests is to verify the behaviour of the
35+
[example modules](./examples/), thus ensuring that the root module,
36+
submodules, and example modules are all functionally correct.
37+
38+
### Test Environment
39+
The easiest way to test the module is in an isolated test project. The setup for such a project is defined in [test/setup](./test/setup/) directory.
40+
41+
To use this setup, you need a service account with Project Creator access on a folder. Export the Service Account credentials to your environment like so:
42+
43+
```
44+
export SERVICE_ACCOUNT_JSON=$(< credentials.json)
45+
```
46+
47+
You will also need to set a few environment variables:
48+
```
49+
export TF_VAR_org_id="your_org_id"
50+
export TF_VAR_folder_id="your_folder_id"
51+
export TF_VAR_billing_account="your_billing_account_id"
52+
```
53+
54+
With these settings in place, you can prepare a test project using Docker:
55+
```
56+
make docker_test_prepare
57+
```
58+
59+
### Noninteractive Execution
60+
61+
Run `make docker_test_integration` to test all of the example modules
62+
noninteractively, using the prepared test project.
63+
64+
### Interactive Execution
65+
66+
1. Run `make docker_run` to start the testing Docker container in
67+
interactive mode.
68+
69+
1. Run `kitchen_do create <EXAMPLE_NAME>` to initialize the working
70+
directory for an example module.
71+
72+
1. Run `kitchen_do converge <EXAMPLE_NAME>` to apply the example module.
73+
74+
1. Run `kitchen_do verify <EXAMPLE_NAME>` to test the example module.
75+
76+
1. Run `kitchen_do destroy <EXAMPLE_NAME>` to destroy the example module
77+
state.
78+
79+
## Linting and Formatting
80+
81+
Many of the files in the repository can be linted or formatted to
82+
maintain a standard of quality.
83+
84+
### Execution
85+
86+
Run `make docker_test_lint`.
87+
88+
[docker-engine]: https://www.docker.com/products/docker-engine
89+
[flake8]: http://flake8.pycqa.org/en/latest/
90+
[gofmt]: https://golang.org/cmd/gofmt/
91+
[google-cloud-sdk]: https://cloud.google.com/sdk/install
92+
[hadolint]: https://github.com/hadolint/hadolint
93+
[inspec]: https://inspec.io/
94+
[kitchen-terraform]: https://github.com/newcontext-oss/kitchen-terraform
95+
[kitchen]: https://kitchen.ci/
96+
[make]: https://en.wikipedia.org/wiki/Make_(software)
97+
[shellcheck]: https://www.shellcheck.net/
98+
[terraform-docs]: https://github.com/segmentio/terraform-docs
99+
[terraform]: https://terraform.io/

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,4 +199,4 @@
199199
distributed under the License is distributed on an "AS IS" BASIS,
200200
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201201
See the License for the specific language governing permissions and
202-
limitations under the License.
202+
limitations under the License.

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,4 @@ docker_generate_docs:
8282

8383
# Alias for backwards compatibility
8484
.PHONY: generate_docs
85-
generate_docs: docker_generate_docs
85+
generate_docs: docker_generate_docs

README.md

Lines changed: 38 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -69,92 +69,60 @@ Then perform the following commands on the root folder:
6969
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
7070

7171
## Requirements
72-
### Terraform plugins
73-
- [Terraform](https://www.terraform.io/downloads.html) 0.12.x
74-
- [terraform-provider-google](https://github.com/terraform-providers/terraform-provider-google) plugin v2.1
72+
73+
These sections describe requirements for using this module.
74+
75+
### Software
76+
77+
The following dependencies must be available:
78+
79+
- [Terraform][terraform] v0.12
80+
- [Terraform Provider for GCP][terraform-provider-gcp] plugin v2.14
7581

7682
### App Engine
7783
Note that this module requires App Engine being configured in the specified project/region.
7884
This is because Google Cloud Scheduler is dependent on the project being configured with App Engine.
79-
Refer to the [Google Cloud Scheduler documentation](https://cloud.google.com/scheduler/docs/) for more
85+
Refer to the [Google Cloud Scheduler documentation][cloud-scheduler-documentation]
8086
information on the App Engine dependency.
8187

8288
The recommended way to create projects with App Engine enabled is via the [Project Factory module](https://github.com/terraform-google-modules/terraform-google-project-factory).
8389
There is an example of how to create the project [within that module](https://github.com/terraform-google-modules/terraform-google-project-factory/tree/master/examples/app_engine)
8490

85-
### Configure a Service Account
86-
In order to execute this module you must have a Service Account with the following roles.
87-
88-
- roles/storage.admin
89-
- roles/pubsub.editor
90-
- roles/cloudscheduler.admin
91-
- roles/cloudfunctions.developer
92-
- roles/iam.serviceAccountUser
93-
94-
95-
### Enable API's
96-
In order to operate with the Service Account you must activate the following API on the project where the Service Account was created:
97-
98-
- Cloud Scheduler API - cloudscheduler.googleapis.com
99-
- Cloud PubSub API - pubsub.googleapis.com
100-
- Cloud Functions API - cloudfunctions.googleapis.com
91+
### Service Account
10192

102-
## Install
93+
A service account with the following roles must be used to provision
94+
the resources of this module:
10395

104-
### Terraform
105-
Be sure you have the correct Terraform version (0.12.x), you can choose the binary here:
106-
- https://releases.hashicorp.com/terraform/
96+
- Storage Admin: `roles/storage.admin`
97+
- PubSub Editor: `roles/pubsub.editor`
98+
- Cloudscheduler Admin: `roles/cloudscheduler.admin`
99+
- Cloudfunctions Developer: `roles/cloudfunctions.developer`
100+
- IAM ServiceAccount User: `roles/iam.serviceAccountUser`
107101

108-
## Testing and documentation generation
102+
The [Project Factory module][project-factory-module] and the
103+
[IAM module][iam-module] may be used in combination to provision a
104+
service account with the necessary roles applied.
109105

110-
### Requirements
111-
- [docker](https://docker.com)
112-
- [terraform-docs](https://github.com/segmentio/terraform-docs/releases) 0.6.0
106+
### APIs
113107

114-
### Integration test
115-
##### Terraform integration tests
116-
It is recommended to to run the integration tests via docker. To do so, run `make test_integration_docker`. In containers, this will
117-
- Perform `terraform init` command
118-
- Perform `terraform get` command
119-
- Perform `terraform validate` command
120-
- Perform `terraform apply -auto-approve` command and check that it has created the appropriate resources
121-
- Perform `terraform destroy -force` command and check that it has destroyed the appropriate resources
108+
A project with the following APIs enabled must be used to host the
109+
resources of this module:
122110

123-
### Autogeneration of documentation from .tf files
124-
Run
125-
```
126-
make generate_docs
127-
```
128-
129-
### Linting
130-
The makefile in this project will lint or sometimes just format any shell,
131-
Python, golang, Terraform, or Dockerfiles. The linters will only be run if
132-
the makefile finds files with the appropriate file extension.
133-
134-
All of the linter checks are in the default make target, so you just have to
135-
run
111+
- Cloud Scheduler API: `cloudscheduler.googleapis.com`
112+
- Cloud PubSub API: `pubsub.googleapis.com`
113+
- Cloud Functions API: `cloudfunctions.googleapis.com`
114+
- App Engine Admin API: `appengine.googleapis.com`
136115

137-
```
138-
make -s
139-
```
116+
The [Project Factory module][project-factory-module] can be used to
117+
provision a project with the necessary APIs enabled.
140118

141-
The -s is for 'silent'. Successful output looks like this
119+
## Contributing
142120

143-
```
144-
Running shellcheck
145-
Running flake8
146-
Running gofmt
147-
Running terraform validate
148-
Running hadolint on Dockerfiles
149-
Test passed - Verified all file Apache 2 headers
150-
```
121+
Refer to the [contribution guidelines](./CONTRIBUTING.md) for
122+
information on contributing to this module.
151123

152-
The linters
153-
are as follows:
154-
* Shell - shellcheck. Can be found in homebrew
155-
* Python - flake8. Can be installed with 'pip install flake8'
156-
* Golang - gofmt. gofmt comes with the standard golang installation. golang
157-
is a compiled language so there is no standard linter.
158-
* Terraform - terraform has a built-in linter in the 'terraform validate'
159-
command.
160-
* Dockerfiles - hadolint. Can be found in homebrew
124+
[iam-module]: https://registry.terraform.io/modules/terraform-google-modules/iam/google
125+
[project-factory-module]: https://registry.terraform.io/modules/terraform-google-modules/project-factory/google
126+
[terraform-provider-gcp]: https://www.terraform.io/docs/providers/google/index.html
127+
[terraform]: https://www.terraform.io/downloads.html
128+
[cloud-scheduler-documentation]: https://cloud.google.com/scheduler/docs/

build/int.cloudbuild.yaml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Copyright 2019 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+
# https://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+
timeout: 3600s
16+
steps:
17+
- id: prepare
18+
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
19+
args: ['/bin/bash', '-c', 'source /usr/local/bin/task_helper_functions.sh && prepare_environment']
20+
env:
21+
- 'TF_VAR_org_id=$_ORG_ID'
22+
- 'TF_VAR_folder_id=$_FOLDER_ID'
23+
- 'TF_VAR_billing_account=$_BILLING_ACCOUNT'
24+
- id: create
25+
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
26+
args: ['/bin/bash', '-c', 'source /usr/local/bin/task_helper_functions.sh && kitchen_do create']
27+
- id: converge
28+
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
29+
args: ['/bin/bash', '-c', 'source /usr/local/bin/task_helper_functions.sh && kitchen_do converge']
30+
- id: verify
31+
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
32+
args: ['/bin/bash', '-c', 'source /usr/local/bin/task_helper_functions.sh && kitchen_do verify']
33+
- id: destroy
34+
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
35+
args: ['/bin/bash', '-c', 'source /usr/local/bin/task_helper_functions.sh && kitchen_do destroy']
36+
tags:
37+
- 'ci'
38+
- 'integration'
39+
substitutions:
40+
_DOCKER_IMAGE_DEVELOPER_TOOLS: 'cft/developer-tools'
41+
_DOCKER_TAG_VERSION_DEVELOPER_TOOLS: '0.1.0'

test/boilerplate/boilerplate.yaml.txt renamed to build/lint.cloudbuild.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,14 @@
1111
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
14+
15+
steps:
16+
- name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
17+
id: 'lint'
18+
args: ['/usr/local/bin/test_lint.sh']
19+
tags:
20+
- 'ci'
21+
- 'lint'
22+
substitutions:
23+
_DOCKER_IMAGE_DEVELOPER_TOOLS: 'cft/developer-tools'
24+
_DOCKER_TAG_VERSION_DEVELOPER_TOOLS: '0.1.0'

examples/logs-slack-alerts/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Disclaimer (8/1/2019): Test Coverage has currently not been added to this exampl
44

55
This logging slack alerts example module schedules a job to run hourly queries of any errors which have occurred in logs which have been ingested into BigQuery. If any errors are found, the errors are sent as alerts to a slack webhook.
66

7-
Running this module requires log exports into BigQuery in the specified project/region, which is not handled by this example.
7+
Running this module requires log exports into BigQuery in the specified project/region, which is not handled by this example.
88
A good example of exported logging in BigQuery can be found in [Stackdriver Logging](https://cloud.google.com/logging/docs/export/).
99

1010
## Configure a Service Account

examples/logs-slack-alerts/function_source/main.py

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
1-
"""
2-
* Copyright 2019 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-
"""
1+
# Copyright 2019 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+
# https://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.
1614

1715
import os
1816
import logging
@@ -54,12 +52,13 @@
5452
1,2
5553
""".format(**VARIABLES)
5654

55+
5756
def query_for_errors(pubsub_event, pubsub_context):
5857
"""
5958
Cloud Function to query audit logs for errors
6059
and send alerts to Slack Webhook
6160
"""
62-
61+
6362
logging.info("Running: %s", QUERY)
6463
query_job = BQ_CLIENT.query(QUERY)
6564

@@ -76,5 +75,6 @@ def query_for_errors(pubsub_event, pubsub_context):
7675
data=str({"text": text}))
7776
logging.info(req.text)
7877

78+
7979
if __name__ == "__main__":
8080
query_for_errors(None, None)
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
google-cloud-bigquery==1.14.0
2-
requests==2.21.0
2+
requests==2.21.0

0 commit comments

Comments
 (0)