There are various points at which the provider needs access to the data from the practitioner's configuration, Terraform's state, or generated plan. The same patterns are used for accessing this data, regardless of its source.
The data is usually stored in a request object:
func (r ThingResource) Create(ctx context.Context,
req resource.CreateRequest, resp *resource.CreateResponse)
In this example, req
holds the configuration and plan, and there is no state value because the resource does not yet exist in state.
One way to interact with configuration, plan, and state values is to convert the entire configuration, plan, or state into a Go type, then treat them as regular Go values. This has the benefit of letting the compiler check all your code that accesses values, but requires defining a type to contain the values.
Use the Get
method to retrieve the first level of configuration, plan, and 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 plan ThingResourceModel
diags := req.Plan.Get(ctx, &plan)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
// values can now be accessed like plan.Name.ValueString()
// check if things are null with plan.Name.IsNull()
// check if things are unknown with plan.Name.IsUnknown()
}
The configuration, plan, and state data is represented as an object, and accessed like an object. Refer to the object type documentation for an explanation on how objects can be converted into Go types.
To descend into deeper nested data structures, the types.List
, types.Map
, and types.Set
types each have an ElementsAs()
method. The types.Object
type has an As()
method.
Use the GetAttribute
method to retrieve a top level attribute or block value from the configuration, plan, and state.
func (r ThingResource) Read(ctx context.Context,
req resource.ReadRequest, resp *resource.ReadResponse) {
var name types.String
diags := req.State.GetAttribute(ctx, path.Root("name"), &name)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
// ...
}
A lot of conversion rules say an error will be returned if a value is unknown or null. It is safe to assume:
Optional
is not true
) will always be unknown in the plan for Create, Read, Update, or Delete methods. They will always be null in the configuration for Create, Read, Update, and Delete methods.In any other circumstances, the provider is responsible for handling the possibility that an unknown or null value may be presented to it.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4