Writing State
One of the primary jobs of a Terraform provider is to manage the provider's resources and data sources in the Terraform state. Writing values to state is something that provider developers will do frequently.
The state that a provider developer wants to update is usually stored in a response object:
func (r ThingResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse)
In this example, resp
holds the state that the provider developer should
update.
Replace the Entire State
One way to set the state is to replace all the state values for a resource or data source all at once. You need to define a type to contain the values. The benefit is that this allows the compiler to check all code that sets values on state, and only the final call to persist state can return an error.
Use the Set
method to store the entire state data.
type ThingResourceModel struct { Address types.Object `tfsdk:"address"` Age types.Int64 `tfsdk:"age"` Name types.String `tfsdk:"name"` Pets types.List `tfsdk:"pets"` Registered types.Bool `tfsdk:"registered"` Tags types.Map `tfsdk:"tags"`} func (r ThingResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { var newState ThingResourceModel // ... // update newState by modifying each property as usual for Go values newState.Name = types.StringValue("J. Doe") // persist the values to state diags := resp.State.Set(ctx, &newState) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { return }}
The state information is represented as an object, and gets persisted like an object. Refer to the object type documentation for an explanation on how objects get persisted and what Go types are valid for persisting as an object.
Set a Single Attribute or Block Value
Use the SetAttribute
method to set an individual attribute or block value.
The value must not be an untyped nil
. Use a typed nil
or types
package null value function instead. For example with a types.StringType
attribute, use (*string)(nil)
or types.StringNull()
.
func (r ThingResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { // ... diags := resp.State.SetAttribute(ctx, path.Root("age"), 7) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { return }}
Refer to the types documentation for more information about supported Go types.