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
}
}