Terraform
- Plugin Framework
- v1.16.x (latest)
- No versions of this document exist before v1.15.x. Click below to redirect to the version homepage.
- v1.15.x
- v1.14.x
- v1.13.x
- v1.12.x
- v1.11.x
- v1.10.x
- v1.9.x
- v1.8.x
- v1.7.x
- v1.6.x
- v1.5.x
- v1.4.x
- v1.3.x
- v1.2.x
- v1.1.x
- v1.0.x
- v0.17.x
- v0.16.x
- v0.15.x
- v0.14.x
- v0.13.x
- v0.12.x
- v0.11.x
- v0.10.x
- v0.8.x
- v0.7.x
Attribute Types
Attributes are the fields in a resource, data source, or provider. They hold the values that end up in state. Every attribute has an attribute type, which describes the constraints on the data the attribute can hold. When you access an attribute from the configuration, state, or plan, you are accessing attribute values, which are the actual data that was found in the configuration, state, or plan.
You can either use the built-in attribute type and value implementations or implement your own.
Null and Unknown Values
There are two values every attribute in Terraform can hold, regardless of their type: null and unknown.
Null
Null represents the absence of a Terraform value. It is usually encountered with optional attributes that the practitioner neglected to specify a value for, but can show up on any non-required attribute. Required attributes can never be null.
Unknown
Unknown represents a Terraform value that is not yet known. Terraform uses a graph of providers, resources, and data sources to do things in the right order, and when a provider, resource, or data source relies on a value from another provider, resource, or data source that has not been resolved yet, it represents that state by using the unknown value. For example:
resource "example_foo" "bar" {
  hello = "world"
  demo = true
}
resource "example_baz" "quux" {
  foo_id = example_foo.bar.id
}
In the example above, example_baz.quux is relying on the id attribute of
example_foo.bar. The id attribute of example_foo.bar isn't known until
after the apply. The plan would list it as (known after apply).  During the
plan phase, example_baz.quux would get an unknown value as the value for
foo_id.
Because they can result from interpolations in the practitioner's config, you have no control over what attributes may contain an unknown value. However, by the time a resource is expected to be created, read, updated, or deleted, only its computed attributes can be unknown. The rest are guaranteed to have known values (or be null).
Provider configuration values can be unknown, and providers should handle that situation, even if that means just returning an error.
Built-In Types and Values
A collection of attribute type and attribute value implementations is available
in the
types
package.
StringType and String
Strings are a UTF-8 encoded collection of bytes.
hello = "world"
They are used by specifying the types.StringType constant in your
tfsdk.Attribute's Type property, and are represented by a types.String
struct in config, state, and plan. The types.String struct has the following
properties:
- Valuecontains the string's value as a Go- stringtype.
- Nullis set to- truewhen the string's value is null.
- Unknownis set to- truewhen the string's value is unknown.
Int64Type and Int64
Int64 are 64-bit integer values, such as 1234.
hello = 1234
They are used by specifying the types.Int64Type constant in your
tfsdk.Attribute's Type property, and are represented by a types.Int64
struct in config, state, and plan. The types.Int64 struct has the following
properties:
- Valuecontains the number's value as a Go- int64type.
- Nullis set to- truewhen the number's value is null.
- Unknownis set to- truewhen the number's value is unknown.
For 64-bit floating point numbers, see Float64Type and
Float64. For generic number handling, see
NumberType and Number64.
Float64Type and Float64
Float64 are 64-bit floating point values, such as 1234.5.
hello = 1234.5
They are used by specifying the types.Float64Type constant in your
tfsdk.Attribute's Type property, and are represented by a types.Float64
struct in config, state, and plan. The types.Float64 struct has the following
properties:
- Valuecontains the number's value as a Go- float64type.
- Nullis set to- truewhen the number's value is null.
- Unknownis set to- truewhen the number's value is unknown.
For 64-bit integer numbers, see Int64Type and
Int64. For generic number handling, see
NumberType and Number64.
NumberType and Number
Numbers are numeric values, both whole values like 12 or fractional values
like 3.14.
hello = 123
They are used by specifying the types.NumberType constant in your
tfsdk.Attribute's Type property, and are represented by a types.Number
struct in config, state, and plan. The types.Number struct has the following
properties:
- Valuecontains the number's value as a Go- *big.Floattype.
- Nullis set to- truewhen the number's value is null.
- Unknownis set to- truewhen the number's value is unknown.
For 64-bit integer numbers, see Int64Type and
Int64. For 64-bit floating point numbers, see
Float64Type and Float64.
BoolType and Bool
Bools are boolean values that can either be true or false.
hello = true
They are used by specifying the types.BoolType constant in your
tfsdk.Attribute's Type property, and are represented by a types.Bool
struct in config, state, and plan. The types.Bool struct has the following
properties:
- Valuecontains the boolean's value as a Go- booltype.
- Nullis set to- truewhen the boolean's value is null.
- Unknownis set to- truewhen the boolean's value is unknown.
ListType and List
Lists are ordered collections of other types. Their elements, the values inside the list, must all be of the same type.
hello = ["red", "blue", "green"]
They are used by specifying a types.ListType value in your
tfsdk.Attribute's Type property. You must specify an ElemType property
for your list, indicating what type the elements should be. Lists are
represented by a types.List struct in config, state, and plan. The
types.List struct has the following properties:
- ElemTypewill always contain the same type as the- ElemTypeproperty of the- types.ListTypethat created the- types.List.
- Elemcontains a list of values, one for each element in the list. The values will all be of the value type produced by the- ElemTypefor the list.
- Nullis set to- truewhen the entire list's value is null. Individual elements may still be null even if the list's- Nullproperty is- false.
- Unknownis set to- truewhen the entire list's value is unknown. Individual elements may still be unknown even if the list's- Unknownproperty is- false.
Elements of a types.List with a non-null, non-unknown value can be accessed
without using type assertions by using the types.List's ElementsAs
method,
which uses the same conversion rules as the Get methods described in Access
State, Config, and Plan.
For an unordered collection with uniqueness constraints, see SetType and
Set.
MapType and Map
Maps are unordered collections of other types with unique string indexes. Their elements, the values inside the map, must all be of the same type. The keys used to index the elements must be strings, but there are (theoretically) no limitations on what keys are acceptable or how many there can be.
hello = {
  pi = 3.14
  random = 4
  "meaning of life" = 42
}
They are used by specifying a types.MapType value in your
tfsdk.Attribute's Type property. You must specify an ElemType property
for your map, indicating what type the elements should be. Maps are
represented by a types.Map struct in config, state, and plan. The
types.Map struct has the following properties:
- ElemTypewill always contain the same type as the- ElemTypeproperty of the- types.MapTypethat created the- types.Map.
- Elemcontains a map of values, one for each element in the map. The keys will be the keys defined in the config, state, or plan, and the values will all be of the value type produced by the- ElemTypefor the map.
- Nullis set to- truewhen the entire map's value is null. Individual elements may still be null even if the map's- Nullproperty is- false.
- Unknownis set to- truewhen the entire map's value is unknown. Individual elements may still be unknown even if the map's- Unknownproperty is- false.
Elements of a types.Map with a non-null, non-unknown value can be accessed
without using type assertions by using the types.Map's ElementsAs
method,
which uses the same conversion rules as the Get methods described in Access
State, Config, and Plan.
ObjectType and Object
Objects are unordered collections of other types with unique, pre-specified
attributes. The attributes have names represented by strings, and each
attribute can specify its own type, similar to a Go struct type. The
attributes and their types are considered part of the object's type; two
objects are not the same type unless they have the same attributes, and those
attributes have the same types.
hello = {
  pi = 3.14
  demo = true
  color = "red"
}
They are used by specifying a types.ObjectType value in your
tfsdk.Attribute's Type property. You must specify an AttrTypes property
for your object, indicating a map of the attribute names and the types of those
attributes. Objects are represented by a types.Object struct in config,
state, and plan. The types.Object struct has the following properties:
- AttrTypeswill always contain the same attribute names and associated types as the- AttrTypesproperty of the- types.ObjectTypethat created the- types.Object.
- Attrscontains a map of attribute names to values. Each attribute is guaranteed to always be present in the map. The values will always be of the value type for that attribute in the- AttrTypesof the object.
- Nullis set to- truewhen the entire object's value is null. Individual attributes may still be null even if the object's- Nullproperty is false.
- Unknownis set to- truewhen the entire object's value is unknown. Individual attributes may still be unknown even if the object's- Unknownproperty is- false.
A non-null, non-unknown types.Object value can be converted to a Go struct
without using type assertions by using the types.Object's As
method,
which uses the same conversion rules as the Get methods described in Access
State, Config, and Plan.
SetType and Set
Sets are unordered collections of other types. Their elements, the values inside the set, must all be of the same type and must be unique.
hello = ["red", "blue", "green"]
They are used by specifying a types.SetType value in your
tfsdk.Attribute's Type property. You must specify an ElemType property
for your set, indicating what type the elements should be. Sets are
represented by a types.Set struct in config, state, and plan. The
types.Set struct has the following properties:
- ElemTypewill always contain the same type as the- ElemTypeproperty of the- types.SetTypethat created the- types.Set.
- Elemcontains a list of values, one for each element in the set. The values will all be of the value type produced by the- ElemTypefor the list. Each element must be unique.
- Nullis set to- truewhen the entire set's value is null. Individual elements may still be null even if the set's- Nullproperty is- false.
- Unknownis set to- truewhen the entire set's value is unknown. Individual elements may still be unknown even if the set's- Unknownproperty is- false.
Elements of a types.Set with a non-null, non-unknown value can be accessed
without using type assertions by using the types.Set's ElementsAs
method,
which uses the same conversion rules as the Get methods described in Access
State, Config, and Plan.
For an ordered collection without uniqueness constraints, see ListType and
List.
Create Provider-Defined Types and Values
You may want to build your own attribute value and type implementations to allow your provider to combine validation, description, and plan customization behaviors into a reusable bundle. This helps avoid duplication or reimplementation and ensures consistency.
Important: Specifying plan customization for attribute types is not yet supported, limiting their utility. Support is expected in the near future.
attr.Type Interface
Use the attr.Type
interface
to implement an attribute type. It tells Terraform about its constraints and tells the framework how to create new attribute values from the information Terraform supplies. attr.Type has the following methods.
| Method | Description | 
|---|---|
| TerraformType | Returns the tftypes.Typevalue that describes its type constraints. This is how Terraform will know what type of values it can accept. | 
| ValueFromTerraform | Returns an attribute value from the tftypes.Valuethat Terraform supplies, or to return an error if it cannot. This error should not be used for validation purposes, and is expected to indicate programmer error, not practitioner error. | 
| Equal | Returns true if the attribute type is considered equal to the passed attribute type. | 
AttributePathStepper Interface
All attribute types must implement the tftypes.AttributePathStepper
interface,
so the framework can access element or attribute types using attribute paths.
Type-Specific Interfaces
| Case | Interface | Description | 
|---|---|---|
| Elements of the same type | TypeWithElementType | Attribute types that contain elements of the same type, like maps and lists, are required to implement attr.TypeWithElementType, which addsWithElementTypeandElementTypemethods to theattr.Typeinterface.WithElementTypemust return a copy of the attribute type, but with its element type set to the passed type.ElementTypemust return the attribute type's element type. | 
| Elements of different types | TypeWithElementTypes | Attribute types that contain elements of differing types, like tuples, are required to implement the attr.TypeWithElementTypes, which addsWithElementTypesandElementTypesmethods to theattr.Typeinterface.WithElementTypesmust return a copy of the attribute type, but with its element types set to the passed element types.ElementTypesmust return the attribute type's element types. | 
| Contain attributes | TypeWithAttributeTypes | Attribute types that contain attributes, like objects, are required to implement the attr.TypeWithAttributeTypesinterface, which addsWithAttributeTypesandAttributeTypesmethods to theattr.Typeinterface.WithAttributeTypesmust return a copy of the attribute type, but with its attribute types set to the passed attribute types.AttributeTypesmust return the attribute type's attribute types. | 
attr.Value Interface
Use the attr.Value
interface
to implement an attribute value. It tells the framework how to express that
attribute value in a way that Terraform will understand. attr.Value has the
following methods.
| Method | Description | 
|---|---|
| ToTerraformValue | Returns a Go type that is valid input for tftypes.NewValuefor thetftypes.Typespecified by theattr.Typethat creates theattr.Value. | 
| Equal | Returns true if the passed attribute value should be considered to the attribute value the method is being called on. The passed attribute value is not guaranteed to be of the same Go type. |