Configure Ephemeral Resources
Ephemeral Resources may require provider-level data or remote system clients to operate correctly. The framework supports the ability to configure this data and/or clients once within the provider, then pass that information to ephemeral resources by adding the Configure
method.
Prepare Provider Configure Method
Implement the provider.ConfigureResponse.EphemeralResourceData
field in the Provider
interface Configure
method. This value can be set to any type, whether an existing client or vendor SDK type, a provider-defined custom type, or the provider implementation itself. It is recommended to use pointer types so that ephemeral resources can determine if this value was configured before attempting to use it.
During execution of the terraform plan
and terraform apply
commands, Terraform calls the ConfigureProvider
RPC, in which the framework calls the provider.Provider
interface Configure
method.
In this example, the Go standard library net/http.Client
is configured in the provider, and made available for ephemeral resources:
// With the provider.Provider implementationfunc (p *ExampleCloudProvider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) { resp.EphemeralResourceData = &http.Client{/* ... */}}
In this example, the code defines an ExampleClient
type that is made available for ephemeral resources:
type ExampleClient struct { /* ... */} // With the provider.Provider implementationfunc (p *ExampleCloudProvider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) { resp.EphemeralResourceData = &ExampleClient{/* ... */}}
In this example, the ExampleCloudProvider
type itself is made available for ephemeral resources:
// With the provider.Provider implementationtype ExampleCloudProvider struct { /* ... */} func (p *ExampleCloudProvider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) { resp.EphemeralResourceData = p}
Define Ephemeral Resource Configure Method
Implement the ephemeral.EphemeralResourceWithConfigure
interface which receives the provider configured data from the Provider
interface Configure
method and saves it into the ephemeral.EphemeralResource
interface implementation.
The ephemeral.EphemeralResourceWithConfigure
interface Configure
method is called during execution of the terraform validate
, terraform plan
and terraform apply
commands when the ValidateEphemeralResourceConfig
RPC is sent. Additionally, the ephemeral.EphemeralResourceWithConfigure
interface Configure
method is called during execution of the terraform plan
and terraform apply
commands when the OpenEphemeralResource
RPC is sent.
Note that Terraform calling the ValidateEphemeralResourceConfig
RPC would not call the ConfigureProvider
RPC first, so implementations need to account for that situation. Configuration validation in Terraform occurs without provider configuration ("offline").
In this example, the provider configured the Go standard library net/http.Client
which the ephemeral resource uses during Open
:
// With the ephemeral.EphemeralResource implementationtype ThingEphemeralResource struct { client *http.Client} func (d *ThingEphemeralResource) Configure(ctx context.Context, req ephemeral.ConfigureRequest, resp *ephemeral.ConfigureResponse) { // Always perform a nil check when handling ProviderData because Terraform // sets that data after it calls the ConfigureProvider RPC. if req.ProviderData == nil { return } client, ok := req.ProviderData.(*http.Client) if !ok { resp.Diagnostics.AddError( "Unexpected Ephemeral Resource Configure Type", fmt.Sprintf("Expected *http.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), ) return } d.client = client} func (d *ThingEphemeralResource) Open(ctx context.Context, req ephemeral.OpenRequest, resp *ephemeral.OpenResponse) { // Prevent panic if the provider has not been configured. if d.client == nil { resp.Diagnostics.AddError( "Unconfigured HTTP Client", "Expected configured HTTP client. Please report this issue to the provider developers.", ) return } httpResp, err := d.client.Get("https://example.com") /* ... */}