• HashiCorp Developer

  • HashiCorp Cloud Platform
  • Terraform
  • Packer
  • Consul
  • Vault
  • Boundary
  • Nomad
  • Waypoint
  • Vagrant
Terraform
  • Install
  • Tutorials
    • About the Docs
    • Configuration Language
    • Terraform CLI
    • Terraform Cloud
    • Terraform Enterprise
    • CDK for Terraform
    • Provider Use
    • Plugin Development
    • Registry Publishing
    • Integration Program
  • Registry(opens in new tab)
  • Try Cloud(opens in new tab)
  • Sign up
Plugin Development

Framework

Skip to main content
  • Framework
  • Provider Servers
    • Terraform Concepts
    • Schemas
    • Attributes
    • Blocks
    • Paths
    • Path Expressions
    • Accessing Terraform Data
    • Writing Data
    • Conversion Rules
    • Custom Types
  • Returning Errors and Warnings
  • Validation
  • Acceptance Tests
  • Debugging

  • Resources

  • Tutorial Library
  • Certifications
  • Community Forum
    (opens in new tab)
  • Support
    (opens in new tab)
  • GitHub
    (opens in new tab)
  • Terraform Registry
    (opens in new tab)
  1. Developer
  2. Terraform
  3. Plugin Development
  4. Framework
  5. Handling Data
  6. Conversion Rules
  • Plugin Framework
  • 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.9.x
  • v0.8.x
  • v0.7.x

»Conversion Rules

Converting from Framework Types to Go Types

Warning: It can be tempting to use Go types instead of attr.Value implementations when the provider doesn't care about the distinction between an empty value, unknown, and null. But if Terraform has a null or unknown value and the provider asks the framework to store it in a type that can't hold it, Get will return an error. Make sure the types you are using can hold the values they might contain!

String

Strings can be automatically converted to Go's string type (or any aliases of it, like type MyString string) as long as the string value is not null or unknown.

Number

Numbers can be automatically converted to the following numeric types (or any aliases of them, like type MyNumber int) as long as the number value is not null or unknown:

  • int, int8, int16, int32, int64
  • uint, uint8, uint16, uint32, uint64
  • float32, float64
  • *big.Int, *big.Float

An error will be returned if the value of the number cannot be stored in the numeric type supplied because of an overflow or other loss of precision.

Boolean

Booleans can be automatically converted to Go's bool type (or any aliases of it, like type MyBoolean bool) as long as the boolean value is not null or unknown.

List

Lists can be automatically converted to any Go slice type (or alias of a Go slice type, like type MyList []string), with the elements either being attr.Value implementations or being converted according to these rules. Go slice types are considered capable of handling null values; the slice will be set to nil. The Get method will still return an error for unknown list values.

Map

Maps can be automatically converted to any Go map type with string keys (or any alias of a Go map type with string keys, like type MyMap map[string]int), with the elements either being attr.Value implementations or being converted according to these rules. Go map types are considered capable of handling null values; the map will be set to nil. The Get method will still return an error for unknown map values.

Object

Objects can be automatically converted to any Go struct type with that follows these constraints:

  • Every property on the struct must have a tfsdk struct tag.
  • The tfsdk struct tag must name an attribute in the object that it is being mapped to or be set to - to explicitly declare it does not map to an attribute in the object.
  • Every attribute in the object must have a corresponding struct tag.

These rules help prevent typos and human error from unwittingly discarding information by failing as early, consistently, and loudly as possible.

Properties can either be attr.Value implementations or will be converted according to these rules.

Unknown and null objects cannot be represented as structs and will return an error. Their attributes may contain unknown or null values if the attribute's type can hold them.

Pointers

Pointers behave exactly like the type they are referencing, except they can hold null values. A pointer will be set to nil when representing a null value; otherwise, the conversion rules for that type will apply.

Detected Interfaces

Get detects and utilizes the following interfaces, if the target implements them.

ValueConverter

If a value is being set on a Go type that implements the tftypes.ValueConverter interface, that interface will be delegated to to handle the conversion.

Unknownable

If the value is being set on a Go type that fills the Unknownable interface:

type Unknownable interface {
    SetUnknown(context.Context, bool) error
    SetValue(context.Context, interface{}) error
    GetUnknown(context.Context) bool
    GetValue(context.Context) interface{}
}

It will be considered capable of handling unknown values, and those methods will be used to populate it and retrieve its value. The interface{} being passed and retrieved will be of a type that can be passed to tftypes.NewValue.

Nullable

If the value is being set on a Go type that fills the Nullable interface:

type Nullable interface {
    SetNull(context.Context, bool) error
    SetValue(context.Context, interface{}) error
    GetNull(context.Context) bool
    GetValue(context.Context) interface{}
}

It will be considered capable of handling null values, and those methods will be used to populate it and retrieve its value. The interface{} being passed and retrieved will be of a type that can be passed to tftypes.NewValue.

Converting from Go Types to Framework Types

The following is a list of schema types and the Go types they know how to accept in Set and SetAttribute.

String

Strings can be automatically created from Go's string type (or any aliases of it, like type MyString string).

Number

Numbers can be automatically created from the following numeric types (or any aliases of them, like type MyNumber int):

  • int, int8, int16, int32, int64
  • uint, uint8, uint16, uint32, uint64
  • float32, float64
  • *big.Int, *big.Float

Boolean

Booleans can be automatically created from Go's bool type (or any aliases of it, like type MyBoolean bool).

List

Lists can be automatically created from any Go slice type (or alias of a Go slice type, like type MyList []string), with the elements either being attr.Value implementations or being converted according to these rules.

Map

Maps can be automatically created from any Go map type with string keys (or any alias of a Go map type with string keys, like type MyMap map[string]int), with the elements either being attr.Value implementations or being converted according to these rules.

Object

Objects can be automatically created from any Go struct type with that follows these constraints:

  • Every property on the struct must have a tfsdk struct tag.
  • The tfsdk struct tag must name an attribute in the object that it is being mapped to or be set to - to explicitly declare it does not map to an attribute in the object.
  • Every attribute in the object must have a corresponding struct tag.

These rules help prevent typos and human error from unwittingly discarding information by failing as early, consistently, and loudly as possible.

Properties can either be attr.Value implementations or will be converted according to these rules.

Pointers

A nil pointer will be treated as a null value. Otherwise, the rules for the type the pointer is referencing apply.

Detected Interfaces

Set detects and utilizes the following interfaces, if the target implements them.

ValueCreator

If a value is set on a Go type that implements the tftypes.ValueCreator interface, that interface will be delegated to to handle the conversion.

Unknownable

If a value is set on a Go type that fills the Unknownable interface:

type Unknownable interface {
    SetUnknown(context.Context, bool) error
    SetValue(context.Context, interface{}) error
    GetUnknown(context.Context) bool
    GetValue(context.Context) interface{}
}

It will be used to convert the value. The interface{} being passed and retrieved will be of a type that can be passed to tftypes.NewValue.

Nullable

If a value is set on a Go type that fills the Nullable interface:

type Nullable interface {
    SetNull(context.Context, bool) error
    SetValue(context.Context, interface{}) error
    GetNull(context.Context) bool
    GetValue(context.Context) interface{}
}

It will be used to convert the value. The interface{} being passed and retrieved will be of a type that can be passed to tftypes.NewValue.

Edit this page on GitHub

On this page

  1. Conversion Rules
  2. Converting from Framework Types to Go Types
  3. Converting from Go Types to Framework Types
Give Feedback(opens in new tab)
  • Certifications
  • System Status
  • Terms of Use
  • Security
  • Privacy
  • Trademark Policy
  • Trade Controls
  • Give Feedback(opens in new tab)