Plugin-framework provider covering projects, environments, applications, Compose stacks, managed databases, domains, mounts, ports, redirects, basic auth, registries, SSH keys, certificates and backup destinations, over Dokploy's tRPC-over-REST API. The shim package exposes the provider to other Go modules, which is how pulumi-dokploy bridges it.
209 lines
5.9 KiB
Markdown
209 lines
5.9 KiB
Markdown
# 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](https://developer.hashicorp.com/terraform/plugin/testing/acceptance-tests/ephemeral-resources)
|
|
|
|
**Requires Terraform >= 1.10.0** — gate all ephemeral tests with
|
|
`tfversion.SkipBelow(tfversion.Version1_10_0)`.
|
|
|
|
---
|
|
|
|
## Table of Contents
|
|
|
|
1. [Testing Approaches](#testing-approaches)
|
|
2. [Direct Integration Testing](#direct-integration-testing)
|
|
3. [Echo Provider Pattern](#echo-provider-pattern)
|
|
4. [Multi-Step Testing](#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.
|
|
|
|
```go
|
|
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:
|
|
|
|
```go
|
|
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:
|
|
|
|
```terraform
|
|
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:
|
|
|
|
```go
|
|
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:
|
|
|
|
```go
|
|
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")),
|
|
},
|
|
},
|
|
},
|
|
```
|