All skills
hashicorp avatar

/provider-test-patterns

@4451cec official
by hashicorphashicorp/agent-skills880 stars
130

Terraform provider acceptance test patterns using terraform-plugin-testing with the Plugin Framework. Covers test structure, TestCase/TestStep fields, ConfigStateChecks with custom statecheck.StateCheck implementations, plan checks, CompareValue for cross-step assertions, config helpers, import testing with ImportStateKind, sweepers, and scenario patterns (basic, update, disappears, validation, regression), and ephemeral resource testing with the echoprovider package. Use when writing, reviewing, or debugging provider acceptance tests, including questions about statecheck, plancheck, TestCheckFunc, CheckDestroy, ExpectError, import state verification, ephemeral resources, or how to structure test files.

Use this Skill: https://skilld.dev/gh/hashicorp/agent-skills/provider-test-patterns

This session only. Nothing lands on disk.

referencesephemeral.md

≈1.5k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Ephemeral Resource Testing Reference

Testing patterns for ephemeral resources using terraform-plugin-testing. Ephemeral resources reference external data without persisting it to plan or state artifacts, which means standard plan checks and state checks cannot directly assert on ephemeral resource data.

Source: Ephemeral Resource Acceptance Tests

Requires Terraform >= 1.10.0 — gate all ephemeral tests with tfversion.SkipBelow(tfversion.Version1_10_0).


Table of Contents

  1. Testing Approaches
  2. Direct Integration Testing
  3. Echo Provider Pattern
  4. Multi-Step Testing

Testing Approaches

Two strategies for testing ephemeral resources:

Approach When to use
Direct integration Verify the ephemeral resource successfully provides data to a dependent resource or provider
Echo provider Assert on specific attribute values using ConfigStateChecks via the echoprovider package

Direct Integration Testing

Test that an ephemeral resource successfully provides data to a dependent resource. No direct assertions on ephemeral data — the test passes if the dependent resource applies cleanly.

func TestExampleCloudSecret_DnsKerberos(t *testing.T) {
    resource.UnitTest(t, resource.TestCase{
        TerraformVersionChecks: []tfversion.TerraformVersionCheck{
            tfversion.SkipBelow(tfversion.Version1_10_0),
        },
        ExternalProviders: map[string]resource.ExternalProvider{
            "dns": {
                Source: "hashicorp/dns",
            },
        },
        ProtoV5ProviderFactories: map[string]func() (tfprotov5.ProviderServer, error){
            "examplecloud": providerserver.NewProtocol5WithError(New()),
        },
        Steps: []resource.TestStep{
            {
                Config: `
ephemeral "examplecloud_secret" "krb" {
  name = "example_kerberos_user"
}

provider "dns" {
  update {
    server = "ns.example.com"
    gssapi {
      realm    = ephemeral.examplecloud_secret.krb.secret_data.realm
      username = ephemeral.examplecloud_secret.krb.secret_data.username
      password = ephemeral.examplecloud_secret.krb.secret_data.password
    }
  }
}

resource "dns_a_record_set" "record_set" {
  zone = "example.com."
  addresses = ["192.168.0.1", "192.168.0.2", "192.168.0.3"]
}
                `,
            },
        },
    })
}

Echo Provider Pattern

The echoprovider package (Protocol V6) captures ephemeral data into a managed resource's state, making it assertable with standard ConfigStateChecks.

Setup

Register both your provider and the echo provider:

import (
    "github.com/hashicorp/terraform-plugin-testing/echoprovider"
)

func TestExampleCloudSecret(t *testing.T) {
    resource.UnitTest(t, resource.TestCase{
        TerraformVersionChecks: []tfversion.TerraformVersionCheck{
            tfversion.SkipBelow(tfversion.Version1_10_0),
        },
        ProtoV5ProviderFactories: map[string]func() (tfprotov5.ProviderServer, error){
            "examplecloud": providerserver.NewProtocol5WithError(New()),
        },
        ProtoV6ProviderFactories: map[string]func() (tfprotov6.ProviderServer, error){
            "echo": echoprovider.NewProviderServer(),
        },
        Steps: []resource.TestStep{
            // test configurations
        },
    })
}

Config Pattern

Pass ephemeral data to the echo provider's data attribute, then assert on the echo managed resource:

ephemeral "examplecloud_secret" "krb" {
  name = "example_kerberos_user"
}

provider "echo" {
  data = ephemeral.examplecloud_secret.krb.secret_data
}

resource "echo" "test_krb" {}

State Assertions

Assert on the echo resource's data attribute using standard state checks:

Steps: []resource.TestStep{
    {
        Config: `...`,
        ConfigStateChecks: []statecheck.StateCheck{
            statecheck.ExpectKnownValue("echo.test_krb",
                tfjsonpath.New("data").AtMapKey("realm"),
                knownvalue.StringExact("EXAMPLE.COM")),
            statecheck.ExpectKnownValue("echo.test_krb",
                tfjsonpath.New("data").AtMapKey("username"),
                knownvalue.StringExact("john-doe")),
            statecheck.ExpectKnownValue("echo.test_krb",
                tfjsonpath.New("data").AtMapKey("password"),
                knownvalue.StringRegexp(regexp.MustCompile(`^.{12}$`))),
        },
    },
},

Multi-Step Testing

The echo resource has special behavior to accommodate ephemeral data variability:

  • During planning for new resources, the data attribute is marked unknown
  • Existing echo resources preserve prior state regardless of config changes
  • Refresh operations always return prior state

Because of this, create new echo resource instances for each test step rather than reusing the same one:

Steps: []resource.TestStep{
    {
        Config: `
ephemeral "examplecloud_secret" "krb" {
  name = "user_one"
}
provider "echo" {
  data = ephemeral.examplecloud_secret.krb
}
resource "echo" "test_krb_one" {}
        `,
        ConfigStateChecks: []statecheck.StateCheck{
            statecheck.ExpectKnownValue("echo.test_krb_one",
                tfjsonpath.New("data").AtMapKey("name"),
                knownvalue.StringExact("user_one")),
        },
    },
    {
        Config: `
ephemeral "examplecloud_secret" "krb" {
  name = "user_two"
}
provider "echo" {
  data = ephemeral.examplecloud_secret.krb
}
resource "echo" "test_krb_two" {}
        `,
        ConfigStateChecks: []statecheck.StateCheck{
            statecheck.ExpectKnownValue("echo.test_krb_two",
                tfjsonpath.New("data").AtMapKey("name"),
                knownvalue.StringExact("user_two")),
        },
    },
},

Source: SKILL.md on GitHub

No alerts17d4 checks · Risk SAFE
  • Gen Agent Trust Hub17d

    This skill provides templates and design patterns for writing Terraform provider acceptance tests. It contains no security issues and adheres to standard testing practices.

  • Socket17d

    No alerts

  • Snyk17d

    Risk: LOW · No issues

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 4451cec. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 3 days ago.

Activeupdated 2 months ago
Other metadata
metadata
{
  "lifecycle-status": "active",
  "copyright": "Copyright IBM Corp. 2026",
  "version": "0.0.1"
}
  • Go
  • terraform
  • provider
  • acceptance-testing
  • plugin-framework
  • statecheck
  • plancheck
  • testing-patterns

README badge

README badge for hashicorp/agent-skills/provider-test-patterns

Terraform provider acceptance test patterns using terraform-plugin-testing with the Plugin Framework. Covers TestCase and TestStep configuration, ConfigStateChecks with custom statecheck implementations, plan checks, import testing, and scenario patterns (basic, update, disappears, validation, regression). Use when writing or reviewing provider acceptance tests.

Generated from the current SKILL.md.

Does this skill cover ephemeral resource testing?
Yes. The skill includes patterns for ephemeral resource testing with the echoprovider package and multi-step patterns, documented in the references/ephemeral.md reference file.
What assertion methods does this skill cover?
The skill prioritizes ConfigStateChecks with statecheck.StateCheck implementations (type-safe, modern approach) but also covers legacy TestCheckFunc patterns for CheckDestroy and migration scenarios. Custom StateCheck implementations for exists and disappears checks are included.
Does this cover import state verification?
Yes. The skill includes ImportState, ImportStateVerify, ImportStateVerifyIgnore, and ImportStateKind patterns for testing resource import workflows.
What plan-checking capabilities are included?
The skill covers ConfigPlanChecks with PreApply plancheck.PlanCheck composition. Full plancheck types and comparers are documented in the references/checks.md reference file.
Does this skill explain sweeper setup?
Yes. Sweeper patterns, TestMain setup, and dependency management are covered in the references/sweepers.md reference file.

Generated from the current SKILL.md. These answers refresh after source changes.