Terraform
Timeouts
The Framework can be used in conjunction with the terraform-plugin-framework-timeouts module in order to allow defining timeouts in configuration and have them be available in CRUD functions.
Specifying Timeouts in Configuration
Timeouts can be defined using either nested blocks or nested attributes.
If you are writing a new provider using terraform-plugin-framework then we recommend using nested attributes.
If you are migrating a provider from SDKv2 to the Framework and you are already using timeouts you can either continue to use block syntax, or switch to using nested attributes. However, switching to using nested attributes will require that practitioners that are using your provider update their Terraform configuration.
Block
If your configuration is using a nested block to define timeouts, such as the following:
resource "timeouts_example" "example" {
/* ... */
timeouts {
create = "60m"
}
}
Import the timeouts module.
import (
/* ... */
"github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts"
)
You can use this module to mutate the schema.Schema
as follows:
func (t *exampleResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
resp.Schema = schema.Schema{
/* ... */
Blocks: map[string]schema.Block{
"timeouts": timeouts.Block(ctx, timeouts.Opts{
Create: true,
}),
},
Attribute
If your configuration is using nested attributes to define timeouts, such as the following:
resource "timeouts_example" "example" {
/* ... */
timeouts = {
create = "60m"
}
}
You can use this module to mutate the schema.Schema
as follows:
func (t *exampleResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
/* ... */
"timeouts": timeouts.Attributes(ctx, timeouts.Opts{
Create: true,
}),
},
Updating Models
In functions in which the config, state or plan is being unmarshalled, for instance, the Create
function, the model
will need to be updated.
func (e *exampleResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
var data exampleResourceData
diags := req.Plan.Get(ctx, &data)
resp.Diagnostics.Append(diags...)
Modify the exampleResourceData
model to include a field for timeouts using a timeouts.Value
type.
type exampleResourceData struct {
/* ... */
Timeouts timeouts.Value `tfsdk:"timeouts"`
Accessing Timeouts in CRUD Functions
Once the model has been populated with the config, state or plan the duration of the timeout can be accessed by calling
the appropriate helper function (e.g., timeouts.Create
) and then used to configure timeout behaviour, for instance:
func (e *exampleResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
var data exampleResourceData
diags := req.Plan.Get(ctx, &data)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
createTimeout, diags := data.Timeouts.Create(ctx, 20*time.Minute)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
ctx, cancel := context.WithTimeout(ctx, createTimeout)
defer cancel()
/* ... */
}