https://github.com/matmoore/terraform-testing-examples
https://github.com/matmoore/terraform-testing-examples
Last synced: 11 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/matmoore/terraform-testing-examples
- Owner: MatMoore
- Created: 2023-08-29T15:27:25.000Z (almost 3 years ago)
- Default Branch: main
- Last Pushed: 2023-09-29T09:23:30.000Z (over 2 years ago)
- Last Synced: 2025-04-02T22:30:36.100Z (about 1 year ago)
- Language: Go
- Size: 55.7 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Testing terraform examples
Examples of "unit" testing terraform deployments.
Such tests actually deploy a terraform module and then verify the result. For example, you can verify that a service returns a 200 response.
The goal of this repo is to evaluate some of the tools for unit testing infrastructure. See also [adopting_terraform_testing.md](./adopting_terraform_testing.md) for a checklist for actually adopting one of these tools into an existing delivery pipeline.
## Prerequisites
Make sure [terraform](https://developer.hashicorp.com/terraform/downloads?product_intent=terraform) is installed and available on the path.
## Testing with Terratest
These tests are written in Go. It can test terraform in addition to other things, like docker containers.
### Prerequisites
[Install go](https://golang.org/).
Configure dependencies:
```
cd terratest
go mod init "github.com/MatMoore/terraform-testing-examples"
go mod tidy
```
### Run tests
```
go test -v -timeout 30m
```
Warning: If the test times out, the terraform destroy will not run, and you will have hanging resources!
### Test descriptions
#### [terraform_basic_example_test](./terratest/terraform_basic_example_test.go)
This test does not use any external providers, so the test just applies the plan and asserts against the outputs.
#### [terraform_aws_hello_world_example_test](./terratest/terraform_aws_hello_world_example_test.go)
This test deploys a resource to AWS.
[You will need credentials configured to run the test.](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#authentication-and-configuration)
The test applies the plan and retrieves the IP of the web server from the output. Then it queries the server to check it is running as expected.
### Writing new tests
Tests live in files like *_test.go.
The core of each test looks like this:
```go
t.Parallel()
terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{
TerraformDir: "../examples/terraform-aws-hello-world-example",
})
defer terraform.Destroy(t, terraformOptions)
terraform.InitAndApply(t, terraformOptions)
// ... make some assertions
```
To make the test stronger, you can swap out `InitAndApply` for `InitAndApplyIdempotent`, which applies the terraform module twice, and checks nothing changes.
There are different ways to assert against things in the test:
- Directly assert that module outputs (e.g. domains, IPs) match expected values
- Retrieve IDs of AWS resources and interract with them via the [aws subpackage](https://pkg.go.dev/github.com/gruntwork-io/terratest@v0.43.13/modules/aws) ([example 1](https://github.com/gruntwork-io/terratest/blob/v0.43.13/test/terraform_aws_rds_example_test.go) [example 2](https://github.com/gruntwork-io/terratest/blob/v0.43.13/test/terraform_aws_s3_example_test.go)) (only possible for some services)
- Retrieve an IP/Domain and issue an HTTP request, as in [terraform_aws_hello_world_example_test](./test/terraform_aws_hello_world_example_test.go)
## Testing with Python Test Helper for Terraform (tftest)
These tests are written in python and pytest.
Compared to terratest, this tool is more basic/simple. There is no functionality for directly interacting with an AWS stack, the library just manages running the terraform for you.
### Prerequisites
You will need some recent version of python.
```
cd tftest
python3 -m pip install requirements.txt
```
### Run tests
```
pytest
```
### Test descriptions
#### [terraform_basic_example_test](./tftest/test_terraform_basic_example.py)
This test does not use any external providers, so the test just applies the plan and asserts against the outputs.
### Writing new tests
You can test just the planning stage like so
```python
@pytest.fixture
def plan(fixtures_dir):
tf = tftest.TerraformTest('plan', fixtures_dir)
tf.setup(extra_files=['plan.auto.tfvars'])
return tf.plan(output=True)
def test_variables(plan):
assert 'prefix' in plan.variables
assert plan.variables['names'] == ['one', 'two']
```
And apply like so:
```python
@pytest.fixture
def output(fixtures_dir):
tf = tftest.TerraformTest('apply', fixtures_dir)
tf.setup()
tf.apply()
yield tf.output()
tf.destroy(**{"auto_approve": True})
def test_apply(output):
value = output['triggers']
assert len(value) == 2
assert list(value[0].keys()) == ['name', 'template']
assert value[0]['name'] == 'one'
```
Things we can do in the test:
- Directly assert that module outputs (e.g. domains, IPs) match expected values
- Retrieve an IP/Domain and issue an HTTP request (e.g. via `requests`)
If you want to inspect resource configuration, you'll need to import a seperate library like [boto3](https://boto3.amazonaws.com/v1/documentation/api/latest/index.html).