• 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

SDKv2

Skip to main content
  • SDKv2
  • Migrate to the Framework
    (opens in new tab)
    • Overview
    • Schema Types
    • Schema Behaviors
  • Debugging Providers

  • 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. SDKv2
  5. Schemas
  6. Schema Types
  • Plugin SDK
  • v2.23.x
  • v2.22.x
  • v2.21.x
  • v2.20.x
  • v2.19.x
  • v2.18.x
  • v2.17.x
  • v2.16.x
  • v2.15.x

»Schema Attributes and Types

Almost every Terraform Plugin offers user configurable parameters, examples such as a Provider’s region or a Resource's name. Each parameter is defined in the items schema, which is a map of string names to schema structs.

In the below example implementation of a Resource you see parameters uuid and name defined:

func resourceExampleResource() *schema.Resource {
    return &schema.Resource{
        // ... //
        Schema: map[string]*schema.Schema{
            "uuid": {
                Type:     schema.TypeString,
                Computed: true,
            },

            "name": {
                Type:         schema.TypeString,
                Required:     true,
                ForceNew:     true,
                ValidateFunc: validatName,
            },
            // ... //
        },
    }
}

The Schema attribute Type defines what kind of values users can provide in their configuration for this element. Here we define the available schema types supported. See Schema Behaviors for more information on configuring element behaviors.

Types

The schema attribute Type determines what data is valid in configuring the element, as well as the type of data returned when used in an expression. Schemas attributes must be one of the types defined below, and can be loosely categorized as either Primitive or Aggregate types:

Primitive types

Primitive types are simple values such as integers, booleans, and strings. Primitives are stored in the state file as "key": "value" string pairs, where both key and value are string representations.

Aggregate types

Aggregate types form more complicated data types by combining primitive types. Aggregate types may define the types of elements they contain by using the Elem property. If the Elem property is omitted, the default element data type is a string.

Aggregate types are stored in state as a key.index and value pair for each element of the property, with a unique index appended to the key based on the type. There is an additional key.index item included in the state that tracks the number of items the property contains.

Primitive Types

TypeBool

Data structure: bool

Example: true or false

Schema example:

"encrypted": {
  Type:     schema.TypeBool,
},

Configuration example:

resource "example_volume" "ex" {
  encrypted = true
}

State representation:

"encrypted": "true",

TypeInt

Data structure: int

Example: -9, 0, 1, 2, 9

Schema example:

"cores": {
  Type:     schema.TypeInt,
},

Configuration example:

resource "example_compute_instance" "ex" {
  cores = 16
}

State representation:

"cores": "16",

TypeFloat

Data structure: float64

Example: 1.0, 7.19009

Schema example:

"price": {
  Type:     schema.TypeFloat,
},

Configuration example:

resource "example_spot_request" "ex" {
  price = 0.37
}

State representation:

"price": "0.37",

TypeString

Data structure: string

Example: "Hello, world!"

Schema example:

"name": {
  Type:     schema.TypeString,
},

Configuration example:

resource "example_spot_request" "ex" {
  description = "Managed by Terraform"
}

State representation:

"description": "Managed by Terraform",

Date & Time Data

TypeString is also used for date/time data, the preferred format is RFC 3339 (you can use the provided validation function).

Example: 2006-01-02T15:04:05+07:00

Schema example:

"expiration": {
  Type:         schema.TypeString,
  ValidateFunc: validation.IsRFC3339Time,
},

Configuration example:

resource "example_resource" "ex" {
  expiration = "2006-01-02T15:04:05+07:00"
}

State representation:

"expiration": "2006-01-02T15:04:05+07:00",

Aggregate Types

TypeMap

Data structure: map: map[string]any

Example: key = value

A key based map (also known as a dictionary) with string keys and values defined by the Elem property.

NOTE: Using the Elem block to define specific keys for the map is currently not possible. A potential workaround would be to confirm the required keys are set when expanding the Map object inside the resource code.

Schema example:

"tags": {
  Type:     schema.TypeMap,
  Elem: &schema.Schema{
    Type: schema.TypeString,
  },
},

Configuration example:

resource "example_compute_instance" "ex" {
  tags {
    env = "development"
    name = "example tag"
  }
}

State representation:

TypeMap items are stored in state with the key as the index. The count of items in a map is denoted by the % index:

"tags.%": "2",
"tags.env": "development",
"tags.name": "example tag",

TypeList

Data structure: Slice: []any

Example: []interface{"2", "3", "4"}

Used to represent an ordered collection of items, where the order the items are presented can impact the behavior of the resource being modeled. An example of ordered items would be network routing rules, where rules are examined in the order they are given until a match is found. The items are all of the same type defined by the Elem property.

Schema example:

"termination_policies": {
  Type:     schema.TypeList,
  Elem: &schema.Schema{
    Type: schema.TypeString,
  },
},

Configuration example:

resource "example_compute_instance" "ex" {
  termination_policies = ["OldestInstance","ClosestToNextInstanceHour"]
}

State representation:

TypeList items are stored in state in a zero based index data structure.

"name_servers.#": "4",
"name_servers.0": "ns-1508.awsdns-60.org",
"name_servers.1": "ns-1956.awsdns-52.co.uk",
"name_servers.2": "ns-469.awsdns-58.com",
"name_servers.3": "ns-564.awsdns-06.net",

TypeSet

Data structure: *schema.Set

Example: []string{"one", "two", "three"}

TypeSet implements set behavior and is used to represent an unordered collection of items, meaning that their ordering specified does not need to be consistent, and the ordering itself has no impact on the behavior of the resource.

The elements of a set can be any of the other types allowed by Terraform, including another schema. Set items cannot be repeated.

Schema example:

"ingress": {
  Type:     schema.TypeSet,
  Elem: &schema.Resource{
    Schema: map[string]*schema.Schema{
      "from_port": {
        Type:     schema.TypeInt,
        Required: true,
      },
  
      "to_port": {
        Type:     schema.TypeInt,
        Required: true,
      },
  
      "protocol": {
        Type:      schema.TypeString,
        Required:  true,
        StateFunc: protocolStateFunc,
      },
  
      "cidr_blocks": {
        Type:     schema.TypeList,
        Optional: true,
        Elem: &schema.Schema{
          Type:         schema.TypeString,
        },
      },
    },
  },
}

Configuration example:

resource "example_security_group" "ex" {
  name        = "sg_test"              
  description = "managed by Terraform" 
                                       
  ingress {                            
    protocol    = "tcp"                
    from_port   = 80                   
    to_port     = 9000                 
    cidr_blocks = ["10.0.0.0/8"]       
  }                                    
                                       
  ingress {                            
    protocol    = "tcp"                
    from_port   = 80                   
    to_port     = 8000                 
    cidr_blocks = ["0.0.0.0/0", "10.0.0.0/8"]
  }                                    
}                                      

State representation:

TypeSet items are stored in state with an index value calculated by the hash of the attributes of the set.

"ingress.#": "2",
"ingress.1061987227.cidr_blocks.#": "1",
"ingress.1061987227.cidr_blocks.0": "10.0.0.0/8",
"ingress.1061987227.description": "",
"ingress.1061987227.from_port": "80",
"ingress.1061987227.ipv6_cidr_blocks.#": "0",
"ingress.1061987227.protocol": "tcp",
"ingress.1061987227.security_groups.#": "0",
"ingress.1061987227.self": "false",
"ingress.1061987227.to_port": "9000",
"ingress.493694946.cidr_blocks.#": "2",
"ingress.493694946.cidr_blocks.0": "0.0.0.0/0",
"ingress.493694946.cidr_blocks.1": "10.0.0.0/8",
"ingress.493694946.description": "",
"ingress.493694946.from_port": "80",
"ingress.493694946.ipv6_cidr_blocks.#": "0",
"ingress.493694946.protocol": "tcp",
"ingress.493694946.security_groups.#": "0",
"ingress.493694946.self": "false",
"ingress.493694946.to_port": "8000",

Next Steps

Checkout Schema Behaviors to learn how to customize each schema elements behavior.

Edit this page on GitHub

On this page

  1. Schema Attributes and Types
  2. Types
  3. Primitive Types
  4. Aggregate Types
  5. Next Steps
Give Feedback(opens in new tab)
  • Certifications
  • System Status
  • Terms of Use
  • Security
  • Privacy
  • Trademark Policy
  • Trade Controls
  • Give Feedback(opens in new tab)