Terraform Variables (Part 2)
Variables are fundamental constructs in every programming language because they are inherently useful in building dynamic programs. We use variables to store temporary values so that they can assist programming logic in simple as well as complex programs.
In this post, we discuss the types of Terraform variables and how they are used in Terraform.
We will create a variables.tf which will hold all the variables.
Create a Directory for terraform variables
cd terraform-course
mkdir terraform-variable
cd terraform-variable
First create a local resource for the recap
# vi main.tf
resource "local_file" "devops" {
filename = "/home/ubuntu/terraform-course/terraform-variables/devops.txt"
content = "Here we are learning terraform"
}
Terraform init
→ plan
→ apply
But suppose if you want to change the location or the content of the file then you have to change it in main.tf
file. This is not a good approach as per the industry standards, always change the configurations of the file which is being stored in a variable folder.
Let’s make a variable folder
# vi variables.tf
variable "filename" {
default = "/home/ubuntu/terraform-course/terraform-variables/devops_automated.txt"
}
variable "content" {
default = "This text is generated by variables"
}
Now implement this in main.tf
# main.tf
resource "local_file" "devops" {
filename = "/home/ubuntu/terraform-course/terraform-variables/devops.txt"
content = "Here we are learning terraform"
}
resource "local_file" "devops_auto" {
filename = var.filename
content = var.content
}
Terraform plan
Terraform apply
Let’s cross check also in the instance
Environment Variables
As a fallback for the other ways of defining variables, Terraform searches the environment of its own process for environment variables named TF_VAR_
followed by the name of a declared variable.
# variables.tf
variable "filename" {
default = "/home/ubuntu/terraform-course/terraform-variables/devops_automated.txt"
}
variable "content" {
default = "This text is generated by variables"
}
variable "myname" {} # declaritive variable without initialization
Changes in main.tf
# main.tf
resource "local_file" "devops" {
filename = "/home/ubuntu/terraform-course/terraform-variables/devops.txt"
content = "Here we are learning terraform"
}
resource "local_file" "devops_auto" {
filename = var.filename
content = var.content
}
output "myname" { # output for the variable which is taken from environment
value = var.myname
}
Run the command to enter the value of myname
variable in environment
export TF_VAR_myname=Harshit
Terraform plan
Terraform apply
Let check by changing the value in environment
export TF_VAR_myname=Harshit_Sahu
terraform apply --auto-approve
Data types in variables
Type = MAP
→ It is like dictionary in python in which we have to put data in form of key and value.
# variables.tf
variable "filename" {
default = "/home/ubuntu/terraform-course/terraform-variables/devops_automated.txt"
}
variable "content" {
default = "This text is generated by variables"
}
variable "myname" {} # declaritive variable without initialization
variable "content_map"{
type = map
default = {
"content1" = "This blog is good"
"content2" = "This blog is great"
}
}
# main.tf
resource "local_file" "devops" {
filename = "/home/ubuntu/terraform-course/terraform-variables/devops.txt"
content = var.content_map["content1"] # Here we use content1
}
resource "local_file" "devops_auto" {
filename = var.filename
content = var.content_map["content2"] # Here we use content2
}
output "myname" {
value = var.myname
}
Terraform apply
You can be noticed from logs that terraform destroys the initial configuration and then put the new configuration in the process of replacement.
Cross-Check also
ls
cat devops.txt
cat devops_automated.txt
Type = LIST
→ This is similar to python’s list in which same types of data are being stored in a box called list.
# variables
variable "filename" {
default = "/home/ubuntu/terraform-course/terraform-variables/devops_automated.txt"
}
variable "content" {
default = "This text is generated by variables"
}
variable "myname" {} # declaritive variable without initialization
variable "content_map"{
type = map
default = {
"content1" = "This blog is good"
"content2" = "This blog is great"
}
}
variable "file_list" {
type = list
default = ["/home/ubuntu/terraform-course/terraform-variables/first.txt","/home/ubuntu/terraform-course/terraform-variables/second.txt"]
}
# main.tf
resource "local_file" "devops" {
filename = var.file_list[0] # Here we are accessing list 1st item through its index 0
content = var.content_map["content1"]
}
resource "local_file" "devops_auto" {
filename = var.file_list[1] # Here we are accessing list 2nd item through its index 1
content = var.content_map["content2"]
}
output "myname" {
value = var.myname
}
Terraform apply
Check by ls
Type = OBJECT
→ It is the multi type user-defined data type which is used as storing multiple data types in map.
# variables.tf
variable "filename" {
default = "/home/ubuntu/terraform-course/terraform-variables/devops_automated.txt"
}
variable "content" {
default = "This text is generated by variables"
}
variable "myname" {} # declaritive variable without initialization
variable "content_map"{
type = map
default = {
"content1" = "This blog is good"
"content2" = "This blog is great"
}
}
variable "file_list" {
type = list
default = ["/home/ubuntu/terraform-course/terraform-variables/first.txt","/home/ubuntu/terraform-course/terraform-variables/second.txt"]
}
variable "aws_ec2_object" { # object type variables
type = object({ # Defining the object
name = string
instances = number
keys = list(string)
ami = string
})
default = { # Declaring its default values
name = "test-instance"
instances = 4
keys = ["key1.pem","key2.pem"]
ami = "ubuntu-fa87fafh89a"
}
}
# main.tf
resource "local_file" "devops" {
filename = var.file_list[0]
content = var.content_map["content1"]
}
resource "local_file" "devops_auto" {
filename = var.file_list[1]
content = var.content_map["content2"]
}
output "myname" {
value = var.myname
}
output "aws_ec2_instances" {
value = var.aws_ec2_object.instances
}
Terraform apply
If you want to see whole object:
# main.tf
output "aws_ec2_instances" {
value = var.aws_ec2_object
}
Variable Definitions (.tfvars
) Files
To set lots of variables, it is more convenient to specify their values in a variable definitions file (with a filename ending in either .tfvars
or .tfvars.json
) and then specify that file on the command line with -var-file
:
terraform apply -var-file="testing.tfvars"
Implementation
Make a variable in variable.tf
# variable.tf
variable "Linkedin" {}
variable "Hashnode" {}
Make a file prod.tfvars.json
vim prod.tfvars.json
# Content
{
"Linkedin": 4300, # it is written in json form
"Hashnode": 1300
}
Make an output block in main.tf
# main.tf
resource "local_file" "devops" {
filename = var.file_list[0]
content = var.content_map["content1"]
}
resource "local_file" "devops_auto" {
filename = var.file_list[1]
content = var.content_map["content2"]
}
output "myname" {
value = var.myname
}
output "aws_ec2_instances" {
value = var.aws_ec2_object.instances
}
output "tf_linkedin_followers" {
value = var.Linkedin
}
Run the command to apply changes
terraform apply -var-file=prod.tfvars.json
Terraform Refresh
Use Terraform refresh to refresh the state by your configuration file, reloads the variables.
Terraform State
Whenever we do terraform init, the plugins are installed.
Whenever we do terraform plan, the execution plan is generated.
Whenever we do terraform apply, the execution is done and state is maintained.
If we don’t have state we can still run the above commands, but state is useful to keep a record of why and how infrastructure was created at the first place. State is like a blueprint of the Real world infrastructure with some unique ids and attributes.
Used to improve performance, dependency management, etc.
Terraform state basically store metadata of the infrastructure which it further utilizes to check the current state before applying the code to ignore redundancy and also ensures specific modules, packages, providers being installed or not.
Remove State
State is a necessary requirement for Terraform to function. It is often asked if it is possible for Terraform to work without state, or for Terraform to not use state and just inspect real world resources on every run.
The main.tf
exists so you can create the whole infrastructure again, so if terraform.tfstate
get deleted also main base file has still existed which can make your infrastructure.
More Terraform commands:
terraform fmt
terraform validate
terraform show
terraform state list
Subscribe to my newsletter
Read articles from Harshit Sahu directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Harshit Sahu
Harshit Sahu
Enthusiastic about DevOps tools like Docker, Kubernetes, Maven, Nagios, Chef, and Ansible and currently learning and gaining experience by doing some hands-on projects on these tools. Also, started learning about AWS and GCP (Cloud Computing Platforms).