Skip to content

Latest commit

 

History

History
473 lines (336 loc) · 33.2 KB

File metadata and controls

473 lines (336 loc) · 33.2 KB
page_title description
Plugin Development - Framework: Attribute Types
Learn the attributes in the provider development framework and how to make your own. Attributes are fields in a resource, data source, or provider.

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.

Framework Types and Value Types

A collection of attribute types (attr.Type) and attribute value types (attr.Value) is available in the types package. These types bridge the implementation details between Terraform's type system and Go code in providers.

Terraform Type Framework Schema Type Framework Value Type Known Value Go Type Use Case
bool types.BoolType types.Bool bool Boolean true or false
number types.Float64Type types.Float64 float64 64-bit floating point number
number types.Int64Type types.Int64 int64 64-bit integer
list types.ListType types.List []attr.Value Ordered collection of single element type
map types.MapType types.Map map[string]attr.Value Mapping of string keys to single element type
number types.NumberType types.Number *big.Float Large floating point or number
object types.ObjectType types.Object map[string]attr.Value Structure mapping string attibute keys to any value type
set types.SetType types.Set []attr.Value Unordered, unique collection of single element type
string types.StringType types.String string Collection of UTF-8 encoded characters

StringType and String

Strings are a UTF-8 encoded collection of bytes.

Given an example Terraform configuration that sets a string value to the example_attribute attribute:

example_attribute = "terraform"

The associated schema type is types.StringType:

"example_attribute": {
  Type: types.StringType,
  // ... other fields ...
}

The associated value type is types.String in configuration, plan, and state data.

Access types.String information via the following methods:

The (types.String).String() method is reserved for debugging purposes and returns "<null>" if the value is null and "<unknown>" if the value is unknown. Use (types.String).ValueString() for any Terraform data handling.

Call one of the following to create a types.String:

Int64Type and Int64

Int64 are 64-bit integer values, such as 1234. For 64-bit floating point numbers, use Float64Type and Float64. For generic number handling, use NumberType and Number.

Given an example Terraform configuration that sets an integer value to the example_attribute attribute:

example_attribute = 1234

The associated schema type is types.Int64Type:

"example_attribute": {
  Type: types.Int64Type,
  // ... other fields ...
}

The associated value type is types.Int64 in configuration, plan, and state data.

Access types.Int64 information via the following methods:

Call one of the following to create a types.Int64:

Float64Type and Float64

Float64 are 64-bit floating point values, such as 1234.5. For 64-bit integer numbers, use Int64Type and Int64. For generic number handling, use NumberType and Number.

Given an example Terraform configuration that sets a floating point value to the example_attribute attribute:

example_attribute = 1234.5

The associated schema type is types.Float64Type:

"example_attribute": {
  Type: types.Float64Type,
  // ... other fields ...
}

The associated value type is types.Float64 in configuration, plan, and state data.

Access types.Float64 information via the following methods:

Call one of the following to create a types.Float64:

NumberType and Number

Numbers are numeric values, both whole values like 12 or fractional values like 3.14. Use this type for exceptionally large numbers. For 64-bit integer numbers, use Int64Type and Int64. For 64-bit floating point numbers, use Float64Type and Float64.

Given an example Terraform configuration that sets a number value to the example_attribute attribute:

example_attribute = 123

The associated schema type is types.NumberType:

"example_attribute": {
  Type: types.NumberType,
  // ... other fields ...
}

The associated value type is types.Number in configuration, plan, and state data.

Access types.Number information via the following methods:

Call one of the following to create a types.Number:

BoolType and Bool

Bools are boolean values that can either be true or false.

Given an example Terraform configuration that sets a boolean value to the example_attribute attribute:

example_attribute = true

The associated schema type is types.BoolType:

"example_attribute": {
  Type: types.BoolType,
  // ... other fields ...
}

The associated value type is types.Bool in configuration, plan, and state data.

Access types.Bool information via the following methods:

Call one of the following to create a types.Bool:

ListType and List

Lists are ordered collections of a single element type.

-> Use ListNestedAttributes for lists of objects that need additional schema information. Use SetType and Set for unordered collections.

Given an example Terraform configuration that sets a list of string values to the example_attribute attribute:

example_attribute = ["red", "blue", "green"]

The associated schema type is types.ListType:

"example_attribute": {
  Type: types.ListType{
    ElemType: types.StringType,
  },
  // ... other fields ...
}

The associated value type is types.List in configuration, plan, and state data.

Access types.List information via the following methods:

Call one of the following to create a types.List:

MapType and Map

Maps are mappings of string keys to values of a single element type.

-> Use MapNestedAttributes for maps of objects that need additional schema information. Use ObjectType and Object for structures of string attribute names to any value.

Given an example Terraform configuration that sets a map of string values to the example_attribute attribute:

example_attribute = {
  red   = "fire",
  blue  = "sky",
  green = "plant",
}

The associated schema type is types.MapType:

"example_attribute": {
  Type: types.MapType{
    ElemType: types.StringType,
  },
  // ... other fields ...
}

The associated value type is types.Map in configuration, plan, and state data.

Access types.Map information via the following methods:

Call one of the following to create a types.Map:

ObjectType and Object

Objects are mappings of string attribute names to values of any type. Objects must always declare all attribute values, even when those attributes are null or unknown, unless the entire object is null or unknown.

-> Use SingleNestedAttributes for objects that need additional schema information. Use MapType and Map for mappings of string keys to a single element type.

Given an example Terraform configuration that sets a map of string values to the example_attribute attribute:

example_attribute = {
  pi    = 3.14
  demo  = true
  color = "red"
}

The associated schema type is types.ObjectType:

"example_attribute": {
  Type: types.ObjectType{
    AttrTypes: map[string]attr.Type{
      "pi":    types.Float64Type,
      "demo":  types.BoolType,
      "color": types.StringType,
    },
  },
  // ... other fields ...
}

The associated value type is types.Object in configuration, plan, and state data.

Access types.Object information via the following methods:

Call one of the following to create a types.Object:

SetType and Set

Set are unordered, unique collections of a single element type.

-> Use SetNestedAttributes for sets of objects that need additional schema information. Use ListType and List for ordered collections.

Given an example Terraform configuration that sets a set of string values to the example_attribute attribute:

example_attribute = ["red", "blue", "green"]

The associated schema type is types.SetType:

"example_attribute": {
  Type: types.SetType{
    ElemType: types.StringType,
  },
  // ... other fields ...
}

The associated value type is types.Set in configuration, plan, and state data.

Access types.Set information via the following methods:

Call one of the following to create a types.Set:

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.Type value 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.Value that 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.

xattr.TypeWithValidation Interface

If validation for type values is desired, use the xattr.TypeWithValidation interface to include validation logic for type values. The framework will call this functionality when validating all values based on the schema.

Method Description
Validate Returns any warning or error diagnostics for the given value.

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 adds WithElementType and ElementType methods to the attr.Type interface. WithElementType must return a copy of the attribute type, but with its element type set to the passed type. ElementType must 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 adds WithElementTypes and ElementTypes methods to the attr.Type interface. WithElementTypes must return a copy of the attribute type, but with its element types set to the passed element types. ElementTypes must return the attribute type's element types.
Contain attributes TypeWithAttributeTypes Attribute types that contain attributes, like objects, are required to implement the attr.TypeWithAttributeTypes interface, which adds WithAttributeTypes and AttributeTypes methods to the attr.Type interface. WithAttributeTypes must return a copy of the attribute type, but with its attribute types set to the passed attribute types. AttributeTypes must 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.NewValue for the tftypes.Type specified by the attr.Type that creates the attr.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.