Terraform Variable Types

Bits Lovers
Written by Bits Lovers on
Terraform Variable Types

I want to walk you through Terraform variable types. If you’ve worked with other programming languages, you’ll find Terraform’s approach familiar. Variables hold your data, and you need to know what types you can use.

Terraform gives you solid flexibility here. You can build configurations that adapt to different environments without rewriting code.

The Variable Block

You declare variables with the variable block. Here’s the simplest form:

variable "db_host" {}

No required attributes. No need to specify a type or default value either—Terraform can infer the type from context.

If you skip the default, you must provide a value when you run Terraform:

terraform apply -var db_host="db.example.com"

String

Strings are straightforward. Define a variable and set the type:

variable "web_service_protocol" {
  type    = string
  default = "https://"
}

Double quotes around the value. The type = string annotation is optional since Terraform infers it, but I always include it for clarity.

Multiline Strings

If you need a large block of text with newlines, use heredoc syntax:

variable "policy" {
  type = string
  default = <<POLICY
{
  "Version": "2012-10-17",
  "Statement": {
    "Effect": "Allow",
    "Action": "*",
    "Resource": "*"
  }
}
POLICY
}

The <<POLICY marker tells Terraform to capture everything until it sees POLICY on its own line.

Number

For numeric values, use number:

variable "db_port" {
  type    = number
  default = 5432
}

Boolean

Boolean variables hold true or false. Terraform infers the type if you don’t specify:

variable "enable_debug" {
  default = false
}

Override the value at runtime:

terraform apply -var enable_debug=true

You might see people use 0 and "1" as boolean substitutes—that still works, but I prefer being explicit with true and false.

Map

Maps let you associate keys with values. A common use case is storing AMI IDs by region:

variable "images_map" {
  type = map(string)
  default = {
    "ap-east-1" = "ami-0b59bfac6be064b78"
    "us-west-1" = "ami-e7768380"
  }
}

Access a value with var.images_map["us-west-1"]. Much cleaner than maintaining separate variables for each region.

List

Lists hold ordered sequences. Each element has an index, starting at zero:

variable "aws_zones" {
  type    = list(string)
  default = ["us-east-1a", "us-west-1c"]
}

In this example, var.aws_zones[0] gives you "us-east-1a", and var.aws_zones[1] gives you "us-west-1c".

Object

Objects let you define structured data. Suppose you need to store database connection details:

variable "db_config" {
  type = object({
    external = number
    internal = number
    protocol = string
  })
  default = {
    external = 5432
    internal = 5433
    protocol = "tcp"
  }
}

List of Objects

You can nest these. Here’s a list of database configurations:

variable "db_ports" {
  type = list(object({
    external = number
    internal = number
    protocol = string
  }))
  default = [
    {
      external = 5432
      internal = 5433
      protocol = "tcp"
    }
  ]
}

Complex Nesting

You can build more sophisticated structures. Here’s a block device mapping that contains an EBS object:

variable "block_device_mappings" {
  description = "Volumes to attach to the instance"
  type = list(object({
    device_name  = string
    no_device    = bool
    virtual_name = string
    ebs = object({
      delete_on_termination = bool
      encrypted              = bool
      iops                  = number
      kms_key_id            = string
      snapshot_id           = string
      volume_size           = number
      volume_type           = string
    })
  }))
  default = []
}

The ebs attribute is itself an object. Terraform lets you compose these types to match almost any infrastructure configuration.

Wrapping Up

Terraform gives you these core types to work with: string, number, bool, map, list, and object. You can combine them—lists of objects, maps of lists, objects containing objects—to match your infrastructure’s shape.

The goal is reuse. Define a value once in a variable, then reference it everywhere you need it. When requirements change, you update the variable definition and Terraform handles the rest.

Bits Lovers

Bits Lovers

Professional writer and blogger. Focus on Cloud Computing.

Comments

comments powered by Disqus