Terraform
Plan Checks
During the Lifecycle (config) and Refresh modes of a TestStep
, the testing framework will run terraform plan
before and after certain operations. For example, the Lifecycle (config) mode will run a plan before the terraform apply
phase, as well as a plan before and after the terraform refresh
phase.
These terraform plan
operations results in a plan file and can be represented by this JSON format.
A plan check is a test assertion that inspects the plan file at a specific phase during the current testing mode. Multiple plan checks can be run at each defined phase, all assertion errors returned are aggregated, reported as a test failure, and all test cleanup logic is executed.
- Available plan phases for Lifecycle (config) mode are defined in the
TestStep.ConfigPlanChecks
struct - Available plan phases for Refresh mode are defined in the
TestStep.RefreshPlanChecks
struct - Import mode currently does not run any plan operations, and therefore does not support plan checks.
Refer to:
- General Plan Checks for built-in general purpose plan checks.
- Resource Plan Checks for built-in managed resource and data source plan checks.
- Output Plan Checks for built-in output-related plan checks.
- Custom Plan Checks for defining bespoke plan checks.
General Plan Checks
The terraform-plugin-testing
module provides a package plancheck
with built-in general plan checks for common use-cases:
Check | Description |
---|---|
ExpectEmptyPlan | Asserts the entire plan has no operations for apply. |
ExpectNonEmptyPlan | Asserts the entire plan contains at least one operation for apply. |
ExpectEmptyPlan
Plan Check
One of the built-in plan checks, plancheck.ExpectEmptyPlan
, is useful for determining a plan is a no-op prior to, for instance, the terraform apply
phase.
Given the following example with the random provider, we have written a test that asserts that there are no planned changes:
package example_test
import (
"testing"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/plancheck"
)
func Test_Random_EmptyPlan(t *testing.T) {
t.Parallel()
resource.Test(t, resource.TestCase{
ExternalProviders: map[string]resource.ExternalProvider{
"random": {
Source: "registry.terraform.io/hashicorp/random",
},
},
Steps: []resource.TestStep{
{
Config: `resource "random_string" "one" {
length = 16
}`,
},
{
Config: `resource "random_string" "one" {
length = 16
}`,
ConfigPlanChecks: resource.ConfigPlanChecks{
PreApply: []plancheck.PlanCheck{
plancheck.ExpectEmptyPlan(),
},
},
},
},
})
}
ExpectNonEmptyPlan
Plan Check
One of the built-in plan checks, plancheck.ExpectNonEmptyPlan
, is useful for determining whether a plan contains changes prior to, for instance, the terraform apply
phase.
The following example, which uses the built-in terraform_data resource, asserts that there are planned changes:
package example_test
import (
"testing"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/plancheck"
"github.com/hashicorp/terraform-plugin-testing/tfversion"
)
func Test_ExpectNonEmptyPlan_ResourceChanges(t *testing.T) {
t.Parallel()
resource.UnitTest(t, resource.TestCase{
TerraformVersionChecks: []tfversion.TerraformVersionCheck{
tfversion.SkipBelow(tfversion.Version1_4_0),
},
ExternalProviders: map[string]resource.ExternalProvider{
"terraform": {Source: "terraform.io/builtin/terraform"},
},
Steps: []resource.TestStep{
{
Config: `resource "terraform_data" "one" {
triggers_replace = ["original"]
}`,
},
{
Config: `resource "terraform_data" "one" {
triggers_replace = ["new"]
}`,
ConfigPlanChecks: resource.ConfigPlanChecks{
PreApply: []plancheck.PlanCheck{
plancheck.ExpectNonEmptyPlan(),
},
},
},
},
})
}