• Overview
    • Enforce Policy as Code
    • Infrastructure as Code
    • Inject Secrets into Terraform
    • Integrate with Existing Workflows
    • Manage Kubernetes
    • Manage Virtual Machine Images
    • Multi-Cloud Deployment
    • Network Infrastructure Automation
    • Terraform CLI
    • Terraform Cloud
    • Terraform Enterprise
  • Registry
  • Tutorials
    • About the Docs
    • Intro to Terraform
    • Configuration Language
    • Terraform CLI
    • Terraform Cloud
    • Terraform Enterprise
    • Provider Use
    • Plugin Development
    • Registry Publishing
    • Integration Program
    • Terraform Tools
    • CDK for Terraform
    • Glossary
  • Community
GitHubTerraform Cloud
Download

    SDKv2

  • Overview
  • Tutorials: Custom Providers
    • Overview
    • Schema Types
    • Schema Behaviors
    • Schema Methods
    • Overview
    • Customizing Differences
    • Import
    • Retries and Customizable Timeouts
    • State Migration
  • Debugging Providers
    • Compatibility with Terraform 0.12
    • Switching to the standalone SDK
    • v2 Upgrade Guide
    • Overview
    • Naming
    • Depending on Providers
    • Deprecations, Removals, and Renames
    • Detecting Drift
    • Handling Sensitive Data
    • Testing Patterns
    • Versioning and Changelog
    • Writing Non-Go Providers
    • Overview
      • Overview
      • Test Cases
      • Test Steps
      • Sweepers
    • Testing API
    • Testing Patterns
    • Unit Testing
  • Other Plugin Docs

  • Plugin Development
  • Framework
  • Logging
  • Combining and Translating
Type '/' to Search

»Schema Behaviors

Schema fields that can have an effect at plan or apply time are collectively referred to as "Behavioral fields", or an element's behaviors. These fields are often combined in several ways to create different behaviors, depending on the need of the element in question, typically customized to match the behavior of a cloud service API. For example, at time of writing, AWS Launch Configurations cannot be updated through the AWS API. As a result, all of the schema elements in the corresponding Terraform Provider resource aws_launch_configuration are marked as ForceNew: true. This behavior instructs Terraform to first destroy and then recreate the resource if any of the attributes change in the configuration, as opposed to trying to update the existing resource.

»Primitive Behaviors

Note: The primitive behavior fields cannot be set to false. You can opt out of a behavior by omitting it.

»Optional

Data structure: bool

Values: true

Restrictions:

  • Cannot be used if Required is true
  • Must be set if Required is omitted and element is not Computed

Indicates that this element is optional to include in the configuration. Note that Optional does not itself establish a default value. See Default below.

Schema example:

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

Configuration example:

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

»Required

Data structure: bool

Values: true

Restrictions:

  • Cannot be used if Optional is true
  • Cannot be used if Computed is true
  • Must be set if Optional is omitted and element is not Computed

Indicates that this element must be provided in the configuration. Omitting this attribute from configuration, or later removing it, will result in a plan-time error.

Schema example:

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

Configuration example:

resource "example_volume" "ex" {
  name = "swap volume"
}
resource "example_volume" "ex" {
  name = "swap volume"
}

»Default

Data structure: interface

Value: any value of an elements Type for primitive types, or the type defined by Elem for complex types.

Restrictions:

  • Cannot be used if Required is true
  • Cannot be used with DefaultFunc

If Default is specified, Terraform will use that value when this item is not set in the configuration.

Schema example:

"encrypted": {
  Type:     schema.TypeBool,
  Optional: true,
  Default: false,
},
"encrypted": {
  Type:     schema.TypeBool,
  Optional: true,
  Default: false,
},

Configuration example (specified):

resource "example_volume" "ex" {
  name = "swap volume"
  encrypted = true
}
resource "example_volume" "ex" {
  name = "swap volume"
  encrypted = true
}

Configuration example (omitted):

resource "example_volume" "ex" {
  name = "swap volume"
  # encrypted receives its default value, false
}
resource "example_volume" "ex" {
  name = "swap volume"
  # encrypted receives its default value, false
}

»Computed

Data structure: bool

Value: true

Restrictions:

  • Cannot be used when Required is true
  • Cannot be used when Default is specified
  • Cannot be used with DefaultFunc

Computed is often used to represent values that are not user configurable or can not be known at time of terraform plan or apply, such as date of creation or a service specific UUID. Computed can be combined with other attributes to achieve specific behaviors, and can be used as output for interpolation into other resources

Schema example:

"uuid": {
  Type:     schema.TypeString,
  Computed: true,
},
"uuid": {
  Type:     schema.TypeString,
  Computed: true,
},

Configuration example:

resource "example_volume" "ex" {
  name = "swap volume"
  encrypted = true
}

output "volume_uuid" {
  value = "${example_volume.ex.uuid}"
}
resource "example_volume" "ex" {
  name = "swap volume"
  encrypted = true
}

output "volume_uuid" {
  value = "${example_volume.ex.uuid}"
}

»ForceNew

Data structure: bool

Value: true

ForceNew indicates that any change in this field requires the resource to be destroyed and recreated.

Schema example:

"base_image": {
  Type:     schema.TypeString,
  Required: true,
  ForceNew: true,
},
"base_image": {
  Type:     schema.TypeString,
  Required: true,
  ForceNew: true,
},

Configuration example:

resource "example_instance" "ex" {
  name = "bastion host"
  base_image = "ubuntu_17.10" 
}
resource "example_instance" "ex" {
  name = "bastion host"
  base_image = "ubuntu_17.10" 
}

»Function Behaviors

»DiffSuppressFunc

Data structure: SchemaDiffSuppressFunc

When provided DiffSuppressFunc will be used by Terraform to calculate the diff of this field. Common use cases are capitalization differences in string names, or logical equivalences in JSON values.

Schema example:

"base_image": {
  Type:     schema.TypeString,
  Required: true,
  ForceNew: true,
  // Suppress the diff shown if the base_image name are equal when both compared in lower case.
  DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
    if strings.ToLower(old) == strings.ToLower(new) {
      return true 
    }
    return false
  },
},
"base_image": {
  Type:     schema.TypeString,
  Required: true,
  ForceNew: true,
  // Suppress the diff shown if the base_image name are equal when both compared in lower case.
  DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
    if strings.ToLower(old) == strings.ToLower(new) {
      return true 
    }
    return false
  },
},

Configuration example:

Here we assume the service API accepts capitalizations of the base_image name and converts it to a lowercase string. The API then returns the lower case value in its responses.

resource "example_instance" "ex" {
  name = "bastion host"
  base_image = "UBunTu_17.10" 
}
resource "example_instance" "ex" {
  name = "bastion host"
  base_image = "UBunTu_17.10" 
}

»DefaultFunc

Data structure: SchemaDefaultFunc

Restrictions:

  • Cannot be used if Default is specified

When provided DefaultFunc will be used to compute a dynamic default for this element. The return value of this function should be "stable", such that it is uncommon to return different values in subsequent plans without any other changes being made, to avoid unnecessary diffs in terraform plan.

DefaultFunc is most commonly used in Provider schemas to allow elements to have defaults that are read from the environment.

Schema example:

In this example, Terraform will attempt to read region from the environment if it is omitted from configuration. If it’s not found in the environment, a default value of us-west is given.

"region": {
  Type:     schema.TypeString,
  Required: true,
  DefaultFunc: func() (interface{}, error) {
    if v := os.Getenv("PROVIDER_REGION"); v != "" {
      return v, nil
    }

    return "us-west", nil
  },
},
"region": {
  Type:     schema.TypeString,
  Required: true,
  DefaultFunc: func() (interface{}, error) {
    if v := os.Getenv("PROVIDER_REGION"); v != "" {
      return v, nil
    }

    return "us-west", nil
  },
},

Configuration example (provided):

provider "example" {
  api_key = "somesecretkey"
  region = "us-east"
}
provider "example" {
  api_key = "somesecretkey"
  region = "us-east"
}

Configuration example (default func with PROVIDER_REGION set to us-east in the environment):

provider "example" {
  api_key = "somesecretkey"
  # region is "us-east"
}
provider "example" {
  api_key = "somesecretkey"
  # region is "us-east"
}

Configuration example (default func with PROVIDER_REGION unset in the environment):

provider "example" {
  api_key = "somesecretkey"
  # region is "us-west" 
}
provider "example" {
  api_key = "somesecretkey"
  # region is "us-west" 
}

»StateFunc

Data structure: SchemaStateFunc

StateFunc is a function used to convert the value of this element to a string to be stored in the state.

Schema example:

In this example, the StateFunc converts a string value to all lower case.

"name": &schema.Schema{
  Type:     schema.TypeString,
  ForceNew: true,
  Required: true,
  StateFunc: func(val interface{}) string {
    return strings.ToLower(val.(string))
  },
},
"name": &schema.Schema{
  Type:     schema.TypeString,
  ForceNew: true,
  Required: true,
  StateFunc: func(val interface{}) string {
    return strings.ToLower(val.(string))
  },
},

Configuration example (provided):

resource "example" "ex_instance" {
  name = "SomeValueCASEinsensitive"
}
resource "example" "ex_instance" {
  name = "SomeValueCASEinsensitive"
}

Value in statefile:

"name": "somevaluecaseinsensitive"
"name": "somevaluecaseinsensitive"

»ValidateFunc

Deprecated: Use ValidateDiagFunc instead.

Data structure: SchemaValidateFunc

Restrictions:

  • Only works with primitive types

ValidateFunc is a function used to validate the value of a primitive type. Common use cases include ensuring an integer falls within a range or a string value is present in a list of valid options. The function returns two slices; the first for warnings, the second for errors which can be used to catch multiple invalid cases. Terraform will only halt execution if an error is returned. Returning warnings will warn the user but the data provided is considered valid.

Terraform includes a number of validators for use in plugins in the validation package. A full list can be found here: https://pkg.go.dev/github.com/hashicorp/terraform-plugin-sdk/helper/validation

Schema example:

In this example, the ValidateFunc ensures the integer provided is a value between 0 and 10.

"amount": &schema.Schema{
 Type:     schema.TypeInt,
 Required: true,
 ValidateFunc: func(val interface{}, key string) (warns []string, errs []error) {
   v := val.(int)
   if v < 0 || v > 10 {
     errs = append(errs, fmt.Errorf("%q must be between 0 and 10 inclusive, got: %d", key, v))
   }
   return
 },
},
"amount": &schema.Schema{
 Type:     schema.TypeInt,
 Required: true,
 ValidateFunc: func(val interface{}, key string) (warns []string, errs []error) {
   v := val.(int)
   if v < 0 || v > 10 {
     errs = append(errs, fmt.Errorf("%q must be between 0 and 10 inclusive, got: %d", key, v))
   }
   return
 },
},

Configuration example:

resource "example" "ex_instance" {
 amount = "-1"
}
resource "example" "ex_instance" {
 amount = "-1"
}

»ValidateDiagFunc

Data structure: SchemaValidateDiagFunc

Restrictions:

  • Only works with primitive types

ValidateDiagFunc is a function used to validate the value of a primitive type. Common use cases include ensuring an integer falls within a range or a string value is present in a list of valid options. The function returns a collection of Diagnostics. Developers should append and build the list of diagnostics up until a fatal error is reached, at which point they should return the Diagnostics. Terraform will only halt execution if an error is returned. Warnings will display a warning message to the practitioner, but continue execution.

The SDK includes some basic validators in the helper/validation package.

Schema example:

In this example, the ValidateDiagFunc ensures the string is abc.

"sample": &schema.Schema{
 Type:             schema.TypeString,
 Required:         true,
 ValidateDiagFunc: func(v interface{}, p cty.Path) diag.Diagnostics {
        value := v.(string)
    expected := "abc"
        var diags diag.Diagnostics
        if value != expected {
            diag := diag.Diagnostic{
                Severity: diag.Error,
                Summary:  "wrong value",
                Detail:   fmt.Sprintf("%q is not %q", value, expected),
            }
            diags = append(diags, diag)
        }
        return diags
    },
},
"sample": &schema.Schema{
 Type:             schema.TypeString,
 Required:         true,
 ValidateDiagFunc: func(v interface{}, p cty.Path) diag.Diagnostics {
        value := v.(string)
    expected := "abc"
        var diags diag.Diagnostics
        if value != expected {
            diag := diag.Diagnostic{
                Severity: diag.Error,
                Summary:  "wrong value",
                Detail:   fmt.Sprintf("%q is not %q", value, expected),
            }
            diags = append(diags, diag)
        }
        return diags
    },
},

Configuration example:

resource "example" "ex_instance" {
 sample = "efg"
}
resource "example" "ex_instance" {
 sample = "efg"
}
github logoEdit this page
  • Overview
  • Docs
  • Extend
  • Privacy
  • Security
  • Press Kit
  • Consent Manager