Terraform - Testing

 Terraform provides numerous testing capabilities to validate your infrastructure.

These testing capabilities fit into two main categories:

  1. Validating your configuration and infrastructure as part of your regular Terraform operations.
  2. Performing traditional unit and integration testing on your configuration.

Refer to Custom Conditions and Checks to learn more about the first testing capability. Terraform's test command provides the second capability.

A brief history

The various testing capabilities were introduced in the following versions:

  • Terraform v0.13.0 introduced Input Variable Validation.
  • Terraform v0.15.0 introduced an experimental Terraform test command.
  • Terraform v1.2.0 introduced Pre and Post-conditions.
  • Terraform v1.5.0 introduced Checks.
  • Terraform v1.6.0 deprecated the experimental Terraform test command, and released an updated and finalized Terraform test command.

Note the introduction and deprecation of the experimental test command, followed by the introduction of the finalized test command. Refer to the v1.6.x Upgrade Guide for a summary of the changes between the experimental and finalized command.

The test command

The Terraform test command:

  • Locates Terraform testing files within your configuration directory.
  • Provisions the infrastructure within your configuration as specified by each testing file.
  • Runs the assertions from the test file against the provisioned infrastructure.
  • Destroys the provisioned infrastructure at the end of the test.

The test command, along with command-line flags and options, is discussed in detail within Command: test.

Write configuration for tests

Terraform test files have their own configuration syntax. This test file syntax focuses on customizing Terraform executions for the current configuration and overriding variables and providers to test different behaviors.

Validations

Validations allow you to verify aspects of your configuration and infrastructure as it is applied and created. Terraform Cloud also supports automated Continuous Validation.

The Terraform test command also executes any validations within your configuration as part of the tests it executes. For more information on the available validation, refer to Checks and Custom Conditions.

Tests or Validations

You can write many validations as test assertions, but there are specific use cases for both.

Validations are executed during Terraform plan and apply operations, and the Terraform test command also runs validations while executing tests. Therefore, use validations to validate aspects of your configuration that should always be true and could impact the valid execution of your infrastructure.

Module authors should note that validations are executed and exposed to module users, so if they fail, ensure the failure messages are understandable and actionable.

In contrast, Terraform only executes tests when you run terraform test. Use tests to assert the correctness of any logical operations or specific behavior within your configuration. For example, you can test that Terraform creates conditional resources based on an input by setting the input controlling those resources to a certain value then verifying the resources Terraform creates.

Command: test

The terraform test command reads in Terraform testing files and executes the tests within.

The test command, and the test file syntax, are particularly helpful for module authors who want to validate and test their shared modules. You can also use the test command to validate root modules.

Usage

Usage: terraform test [options]

This command searches the current directory and the specified testing directory (tests, by default) for any Terraform testing files, and executes the specified tests. Refer to Tests for more details on test files.

Terraform then executes a series of Terraform plan or apply commands according to the test files' specifications, and also validates the relevant plan and state files according to the test files' specifications.

Warning: The Terraform test command can create real infrastructure than can cost you money. Refer to the Terraform Test Cleanup section for best practices on ensuring created infrastructure is destroyed.

General Options

The following options apply to the Terraform test command:

  • -cloud-run=<module source> - This test run executes remotely on Terraform Cloud within the specified Terraform private registry module.

  • -filter=testfile - Limits the terraform test operation to the specified test files.

  • -json - Displays machine-readable JSON output for your testing results.

  • -test-directory=<relative directory> - Overrides the directory that Terraform looks into for test files. Note that Terraform always loads testing files within the main configuration directory. The default testing directory is tests.

  • -verbose - Prints out the plan or state for each run block within a test file, based on the command attribute of each run block.

State Management

Each Terraform test file will maintain all Terraform state it requires within memory as it executes, starting empty. This state is entirely separate from any existing state for the configuration under test, so you can safely execute Terraform test commands without affecting any live infrastructure.

Terraform Test Cleanup

The Terraform test command creates real infrastructure. Once Terraform fully executes each test file, Terraform attempts to destroy any remaining infrastructure. If it cannot do this, Terraform reports a list of resources it created but could not destroy.

You should monitor the output of the test command closely to ensure Terraform removes the infrastructure it created or perform manual cleanup if not. We recommend creating dedicated testing accounts within the target providers that you can routinely and safely purge to ensure any accidental and costly resources aren't left behind.

Terraform also provides diagnostics explaining why it could not automatically clean up. You should review these diagnostics to ensure that future clean-up operations are successful.

Terraform Cloud execution

You can execute tests remotely on Terraform Cloud using the -cloud-run option.

The -cloud-run option accepts a private registry module source. This option associates the test run with your specified private module within the Terraform Cloud user interface.

You must provide a module from a private registry, not the public Terraform registry.

You must execute terraform login before using this option, and ensure that your hostname argument matches the private registry hostname of your target module.

Example: Test Directory Structure and Commands

The following directory structure represents an example directory tree for a Terraform module with tests and a setup module.

project/
|-- main.tf
|-- outputs.tf
|-- terraform.tf
|-- variables.tf
|-- tests/
|   |-- validations.tftest.hcl
|   |-- outputs.tftest.hcl
|-- testing/
    |-- setup/
        |-- main.tf
        |-- outputs.tf
        |-- terraform.tf
        |-- variables.tf

At the root directory of the project, there are some typical Terraform configuration files: main.tfoutputs.tfterraform.tf, and variables.tf. The test files, validations.tftest.hcl and outputs.tftest.hcl, are within the default tests directory: tests.

In addition, a setup module for the tests exists within the testing directory.

In order to execute the tests you should run terraform test from the root configuration directory as if running terraform plan or terraform apply. Despite the actual test files being in the nested tests directory, Terraform executes from the main configuration directory.

Specific test files can be executed using the -filter option.

Linux, Mac OS, and UNIX:

terraform test -filter=tests/validations.tftest.hcl

PowerShell:

terraform test -filter='tests\validations.tftest.hcl'

Windows cmd.exe:

terraform test -filter=tests\validations.tftest.hcl

Alternate Test Directories

In the above example the tests are in the default testing directory of tests. Test files can also be included directly within the main configuration directory:

project/
|-- main.tf
|-- outputs.tf
|-- terraform.tf
|-- variables.tf
|-- validations.tftest.hcl
|-- outputs.tftest.hcl
|-- testing/
    |-- setup/
        |-- main.tf
        |-- outputs.tf
        |-- terraform.tf
        |-- variables.tf

The location of the testing files does not affect the operation of terraform test. All references to, and absolute file paths within, the testing files should be relative to the main configuration directory.

You can also use the -test-directory argument to change the location of the testing files. For example, terraform test -test-directory=testing would instruct Terraform to load tests from the directory testing instead of tests.

The testing directory must be beneath the main configuration directory, but it can be nested many times.

Note: Test files within the root configuration directory are always loaded, regardless of the -test-directory value.

We do not recommend changing the default test directory. The option for customization is included for configuration authors who may have included a tests submodule in their configuration before the terraform test command was released. In general, the default test directory of tests should always be used.

Comments

Popular posts from this blog

Terraform

Scrum Master Interview help - Bootcamp

Kubernetes