Custom Plan Checks
The package plancheck
also provides the PlanCheck
interface, which can be implemented for a custom plan check.
The plancheck.CheckPlanRequest
contains the current plan file, parsed by the terraform-json package.
Here is an example implementation of a plan check that asserts that every resource change is a no-op, aka, an empty plan:
package example_testimport ( "context" "fmt" "github.com/hashicorp/terraform-plugin-testing/plancheck")var _ plancheck.PlanCheck = expectEmptyPlan{}type expectEmptyPlan struct{}func (e expectEmptyPlan) CheckPlan(ctx context.Context, req plancheck.CheckPlanRequest, resp *plancheck.CheckPlanResponse) { var result error for _, rc := range req.Plan.ResourceChanges { if !rc.Change.Actions.NoOp() { result = errors.Join(result, fmt.Errorf("expected empty plan, but %s has planned action(s): %v", rc.Address, rc.Change.Actions)) } } resp.Error = result}func ExpectEmptyPlan() plancheck.PlanCheck { return expectEmptyPlan{}}
And example usage:
package example_testimport ( "context" "errors" "fmt" "testing" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/plancheck")func Test_CustomPlanCheck_ExpectEmptyPlan(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{ ExpectEmptyPlan(), }, }, }, }, })}