Variables and Outputs
Terraform can accept values as input, transform values inside a configuration, and return values as output.
There’re three different concepts to consider when working with data in a Terraform
- Input variables (variables) : used to pass information to a Terraform configuration
- Local values (locals) : computed values inside the configuration that can be referenced throughout the config
- Output values: the value of each output will depend on what it references inside the configuration
Input Variables
A variable block starts with the variable keyword followed by a single label.
variable "name_label" {
// optional arguments
type = value // Terraform will throw an error if the type of value doesn't matched
description = "value" // helps provide some context for the user when they get an error
default = "value" // If no value is submitted for the variable, Terraform will use this default value
sensitive = true | false // accepts a Boolean value of true or false. It's useful when you have to submit potentially sensitive values like password.
}
Let’s take a look at a few examples of actual variables and how to refer to their value inside a configuration:
variable "billing_tag" {} // no arguments are provided and none are needed. This is a quick way of adding a variable
variable "aws_region" {
type = string
description = "Region to use for AWS resources"
default = "us-east-1" // If no value is specified at execution time, Terraform will use us-east-1.
}
Terraform Data Types
We can group the data types supported by Terraform into three categories.
- primitive: String, number, boolean
- Collection: List, set, map
- Structural: Tuple, object
Data type examples:
# List
variable "aws_regions" {
type = list(string)
description = "Region to use for AWS resources"
default = ["us-east-1", "us-east-2", "us-west-1", "us-west-2"]
}
// we can refer to an element by number, starting with 0.
var.<name_label>[<element_number>]
# Map
variable "aws_instance_sizes" {
type = map(string)
description = "Region to use for AWS resources"
default = {
small = "t2.micro"
medium = "t2.small"
large = "t2.large"
}
}
// Referencing Collection Values
var.<name_label>.<key_name> or var.<name_label>["key_name"]
Adding Variable
provider "aws" {
access_key = var.aws_access_key
secret_key = var.aws_secret_key
region = var.aws_region
}
variable "aws_access_key" {
type = string
description = "AWS Access Key"
sensitive = true
}
variable "aws_secret_key" {
type = string
description = "AWS Secret Key"
sensitive = true
}
variable "aws_region" {
type = string
description = "AWS Region"
default = "us-east-1"
}
our provider is now using all variables for its values. In out networking configuration, we can use variables for CIDR blocks, DNS hostnames, subnets, and map_public_ip_on_launch
.
variable "aws_region" {
type = string
description = "AWS Region"
default = "us-east-1"
}
variable "enable_dns_hostnames" {
type = bool
description = "Enable DNS Hostnames"
default = true
}
variable "vpc_cidr_block" {
type = string
description = "VPC CIDR Block"
default = "10.0.0.0/16"
}
variable "vpc_subnet1_cidr_block" {
type = string
description = "VPC Subnet 1 CIDR Block"
default = "10.0.0.0/24"
}
variable "map_public_ip_on_launch" {
type = bool
description = "Map Public IP on Launch"
default = true
}
variable "instance_type" {
type = string
description = "Instance Type"
default = "t2.micro"
}
Locals Syntax
local values are values computed inside of the configuration. The syntax for locals starts with the keyword locals, and that’s it for labels on the block.
locals {
// defines a local
instance_prefix = "globo"
// define tags
common_tags = {
company = "Globomantics"
project = var.project
billing_code = var.billing_code
}
}
// Reference
local.<name_label>
local.instance_prefix
local.common_tags.company
Let’s create locals.tf
// start by defining a locals block
locals {
// define a map of common tags
common_tags = {
company = var.company
project = "${var.company}-${var.proejct}"
billing_code = var.billing_code
}
}
variable "company" {
type = string
description = "Company name for resource tagging"
default = "Globomantics"
}
variable "project" {
type = string
description = "Project name for resource tagging"
}
variable "billing_code" {
type = string
description = "Billing code for resource tagging"
}
add tag to main.tf
resource "aws_vpc" "vpc" {
cidr_block = var.vpc_cidr_block
enable_dns_hostnames = var.enable_dns_hostnames
tags = local.common_tags
}
Outputs Syntax
// the syntax for an output starts with the output keyword
output "name_label {
// only required argument is the value of the output
value = output_value
description = "Description of output"
sensitive = true | false
}
For example, let’s add a file for the output
output "aws_instance_public_dns" {
value = aws_instance.web_server.public_dns
description = "Public DNS hostname web server"
}