Terraform
Close Ephemeral Resources
Close is an optional part of the Terraform lifecycle for an ephemeral resource, which is different from the managed resource lifecycle. During any Terraform operation (like terraform plan
or terraform apply
), when an ephemeral resource's data is needed, Terraform initially retrieves that data with the Open
lifecycle handler. Once the ephemeral resource data is no longer needed, Terraform calls the provider CloseEphemeralResource
RPC, in which the framework calls the ephemeral.EphemeralResourceWithClose
interface Close
method. The request contains any Private
data set in the latest Open
or Renew
call.
Close
is an optional lifecycle implementation for an ephemeral resource, other lifecycle implementations include:
- Open an ephemeral resource by receiving Terraform configuration, retrieving a remote object, and returning ephemeral result data to Terraform.
- Renew an expired remote object at a specified time.
Define Close Method
The ephemeral.EphemeralResourceWithClose
interface on the ephemeral.EphemeralResource
interface implementation will enable close support for an ephemeral resource.
Implement the Close
method by:
- Accessing private data from
ephemeral.CloseRequest.Private
field needed to close the remote object. - Performing logic or external calls to close the remote object.
If the logic needs to return warning or error diagnostics, they can be added into the ephemeral.CloseResponse.Diagnostics
field.
In this example, an ephemeral resource named examplecloud_thing
with hardcoded behavior is defined. Private
data needed to execute Close
is passed from the Open
response:
var _ ephemeral.EphemeralResourceWithClose = (*ThingEphemeralResource)(nil)
// ThingEphemeralResource defines the ephemeral resource implementation, which also implements Close.
type ThingEphemeralResource struct{}
type ThingEphemeralResourceModel struct {
Name types.String `tfsdk:"name"`
Token types.String `tfsdk:"token"`
}
type ThingPrivateData struct {
Name string `json:"name"`
}
func (e *ThingEphemeralResource) Schema(ctx context.Context, req ephemeral.SchemaRequest, resp *ephemeral.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
"name": schema.StringAttribute{
Description: "Name of the thing to retrieve a token for.",
Required: true,
},
"token": schema.StringAttribute{
Description: "Token for the thing.",
Computed: true,
},
},
}
}
func (e *ThingEphemeralResource) Open(ctx context.Context, req ephemeral.OpenRequest, resp *ephemeral.OpenResponse) {
var data ThingEphemeralResourceModel
// Read Terraform config data into the model
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
if resp.Diagnostics.HasError() {
return
}
// Typically ephemeral resources will make external calls and reference returned data,
// however this example hardcodes the setting of result and private data for brevity.
data.Token = types.StringValue("token-123")
// When closing, pass along this data (error handling omitted for brevity).
privateData, _ := json.Marshal(ThingPrivateData{Name: data.Name.ValueString()})
resp.Private.SetKey(ctx, "thing_data", privateData)
// Save data into ephemeral result data
resp.Diagnostics.Append(resp.Result.Set(ctx, &data)...)
}
func (e *ThingEphemeralResource) Close(ctx context.Context, req ephemeral.CloseRequest, resp *ephemeral.CloseResponse) {
privateBytes, diags := req.Private.GetKey(ctx, "thing_data")
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
// Unmarshal private data (error handling omitted for brevity).
var privateData ThingPrivateData
json.Unmarshal(privateBytes, &privateData)
// Perform external call to close/clean up "thing" data
}