[Terraform] Variables

Terraform allows you to pass values into the script and get the outputs as return values.

Input Variables

You can use input variables as customization parameters to the Terraform script. With input variables, you do not need to hardcode specifics, and the configuration files can be shared among many scenarios.

Define Input Variables

Input variables need to be defined in a “variable” block.

  • You need to specify the type of the variable.
  • Optionally, you can specify the default value.

Type Constraints

A Type constraint is optional but recommended.

  • string
  • number
  • bool
  • object, list, set, map

Validation

You can provide the validation rules for each input variable to detect the error early.

  • condition: expression that returns true or false
  • error_message

Examples

String Type with Validation

variable "image_id" {
  type = string
  description = "AMI id"

  validation {
    condition = (
      length(var.image_id) > 4 && 
      substr(var.image_id, 0, 4) == "ami-")
    error_message = "The image_id value must be a valid AMI id."
  }
}

String Type with Limited Values

variable "country" {
  type = string
  description = "US"

  validation {
    condition = contains(
      ["US", "Canada", "Mexico"] 
      var.country)
    error_message = "The country name is not valid."
  }
}

Object Type with Number Validation

variable "port_mapping" {
  type = object({
    internal = number
    external = number
    protocol = string
  })

  default = {
    internal = 80
    external = 8000
    protocol = "tcp"
  }

  validation {
    condition = (
      var.port_mapping.internal < 65536 && 
      var.port_mapping.external < 65536)
    error_message = "The port number should be valid."
  } 
}

Array Type

varible "az_names" {
  type = list(string)

  default = ["us-east-1a"]

  validation {
    condition = alltrue([
      for az in var.az_names: contains(
        ["us-east-1a", "us-east-1b", "us-east-1c"], az
      )    
    ])
    error_message = "The availability zone name should be valid."
  } 
}

Using Input Variables

  • A variable can be referenced in other blocks.
  • A variable can only be accessed in a module it is declared.
# define a variable
variable "image_id" {
  type = string
}

# use var.{var_name} syntax
resource "aws_instance" "test" {
  instance_type = "t2.micro"
  ami = var.image_id
}

Pass Values to Variables

There are several ways to pass values at runtime.

  • -var command line option
  • In a Terraform Cloud workspace
  • Using the variable definition files: .tfvars or tfvars.json
  • As environment variables (TF_VAR_{variable_name})

variable definition file

image_id=ami-123"
az_names=[
  "us-east-1b",
  "us-east-1c"
]
port_mapping={
  internal:80,
  external:8080,
  protocol:"tcp"
}

Passing Values in a command line

terraform apply -var="image_id=ami-123" \
  -var='az_names=["us-east-1b", "us-east-1c"]'

terraform apply -var='port_mapping={internal:80, external:8080, protocol:"tcp"}'

terraform apply -var-file="test.tfvars"

Terraform loads variables in the following order, with later sources taking precedence over earlier ones:

  • Environment variables.
  • The tfvars file, if present.
  • The tfvars.json, if present.
  • Any *.auto.tfvars or *.auto.tfvars.json
  • Any -var and -var-file options on the command line

Output Variables

  • A child module
    • can pass values to the parent module
  • A root module
    • can print values
    • can pass values to other configurations via terraform_remote_state data source

Define Output Variables

Output variables need to be defined in a “output” block.

output "instance_ip" {
  value = aws_instance.server.private_ip
  description = "Private of of a new EC2 instance"
}

Access Output Variables

You can access the child module’s output in a parent module:

module.{module_name}.{output_name}

Local Variables

In Terraform, you can even define a temporary placeholder to use a value or expression without repeating it in a module.

Define Local Variables

Local variables are defined together in a single “locals” block.

locals {
  app_name = "web"
}

Access Local Variables

# local.{variable_name}
resource "aws_instance" "test" {
  tags = {
    Name = local.app_name
  }
}

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s