Resource Plan Checks
The terraform-plugin-testing
module provides a package plancheck
with built-in managed resource, and data source plan checks for common use-cases:
Check | Description |
---|---|
ExpectKnownValue | Asserts the specified attribute at the given managed resource, or data source, has the specified type, and value. |
ExpectResourceAction | Asserts the given managed resource, or data source, has the specified operation for apply. |
ExpectSensitiveValue | Asserts the specified attribute at the given managed resource, or data source, has a sensitive value. |
ExpectUnknownValue | Asserts the specified attribute at the given managed resource, or data source, has an unknown value. |
ExpectKnownValue
Plan Check
The plancheck.ExpectKnownValue(address, path, value)
plan check provides a basis for asserting that a specific resource attribute has a known type, and value.
Refer to Known Value Checks for details, and examples of the available knownvalue.Check types that can be used with the ExpectKnownValue
plan check.
package example_test import ( "testing" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/knownvalue" "github.com/hashicorp/terraform-plugin-testing/plancheck" "github.com/hashicorp/terraform-plugin-testing/tfjsonpath") func TestExpectKnownValue_CheckPlan_String(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ // Provider definition omitted. Steps: []resource.TestStep{ { // Example resource containing a computed string attribute named "computed_attribute" Config: `resource "test_resource" "one" {}`, ConfigPlanChecks: resource.ConfigPlanChecks{ PreApply: []plancheck.PlanCheck{ plancheck.ExpectKnownValue( "test_resource.one", tfjsonpath.New("computed_attribute"), knownvalue.StringExact("str")), }, }, }, }, })}
ExpectResourceAction
Plan Check
One of the built-in plan checks, plancheck.ExpectResourceAction
, is useful for determining the exact action type a resource will under-go during, say, the terraform apply
phase.
Given the following example with the random provider, we have written a test that asserts that random_string.one
will be destroyed and re-created when the length
attribute is changed:
package example_test import ( "testing" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/plancheck") func Test_Random_ForcesRecreate(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 = 15 }`, ConfigPlanChecks: resource.ConfigPlanChecks{ PreApply: []plancheck.PlanCheck{ plancheck.ExpectResourceAction("random_string.one", plancheck.ResourceActionDestroyBeforeCreate), }, }, }, }, })}
Another example with the time provider asserts that time_offset.one
will be updated in-place when the offset_days
attribute is changed:
package example_test import ( "testing" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/plancheck") func Test_Time_UpdateInPlace(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ ExternalProviders: map[string]resource.ExternalProvider{ "time": { Source: "registry.terraform.io/hashicorp/time", }, }, Steps: []resource.TestStep{ { Config: `resource "time_offset" "one" { offset_days = 1 }`, }, { Config: `resource "time_offset" "one" { offset_days = 2 }`, ConfigPlanChecks: resource.ConfigPlanChecks{ PreApply: []plancheck.PlanCheck{ plancheck.ExpectResourceAction("time_offset.one", plancheck.ResourceActionUpdate), }, }, }, }, })}
Multiple plan checks can be combined if you want to assert multiple resource actions:
package example_test import ( "testing" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/plancheck") func Test_Time_UpdateInPlace_and_NoOp(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ ExternalProviders: map[string]resource.ExternalProvider{ "time": { Source: "registry.terraform.io/hashicorp/time", }, }, Steps: []resource.TestStep{ { Config: `resource "time_offset" "one" { offset_days = 1 } resource "time_offset" "two" { offset_days = 1 }`, }, { Config: `resource "time_offset" "one" { offset_days = 2 } resource "time_offset" "two" { offset_days = 1 }`, ConfigPlanChecks: resource.ConfigPlanChecks{ PreApply: []plancheck.PlanCheck{ plancheck.ExpectResourceAction("time_offset.one", plancheck.ResourceActionUpdate), plancheck.ExpectResourceAction("time_offset.two", plancheck.ResourceActionNoop), }, }, }, }, })}
ExpectSensitiveValue
Plan Check
The built-in plancheck.ExpectSensitiveValue(address, path)
plan check is used to determine whether the specified attribute at the given managed resource, or data source, has a sensitive value.
package example_test import ( "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/plancheck" "github.com/hashicorp/terraform-plugin-testing/tfjsonpath" "github.com/hashicorp/terraform-plugin-testing/tfversion") func Test_ExpectSensitiveValue_SensitiveStringAttribute(t *testing.T) { t.Parallel() resource.UnitTest(t, resource.TestCase{ TerraformVersionChecks: []tfversion.TerraformVersionCheck{ tfversion.SkipBelow(tfversion.Version1_0_0), // Change.AfterSensitive }, // Provider definition omitted. Steps: []resource.TestStep{ { Config: ` resource "test_resource" "one" { sensitive_string_attribute = "test" } `, ConfigPlanChecks: resource.ConfigPlanChecks{ PreApply: []plancheck.PlanCheck{ plancheck.ExpectSensitiveValue("test_resource.one", tfjsonpath.New("sensitive_string_attribute")), }, }, }, }, })}
ExpectUnknownValue
Plan Check
The built-in plancheck.ExpectUnknownValue(address, path)
plan check is used to determine whether the specified attribute at the given managed resource, or data source, has an unknown value.
package example_test import ( "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/plancheck" "github.com/hashicorp/terraform-plugin-testing/tfjsonpath") func Test_ExpectUnknownValue_StringAttribute(t *testing.T) { t.Parallel() resource.Test(t, resource.TestCase{ ExternalProviders: map[string]resource.ExternalProvider{ "time": { Source: "registry.terraform.io/hashicorp/time", }, }, // Provider definition for `test` omitted. Steps: []resource.TestStep{ { Config: `resource "time_static" "one" {} resource "test_resource" "two" { string_attribute = time_static.one.rfc3339 } `, ConfigPlanChecks: resource.ConfigPlanChecks{ PreApply: []plancheck.PlanCheck{ plancheck.ExpectUnknownValue("test_resource.two", tfjsonpath.New("string_attribute")), }, }, }, }, })}