Terraform is an open source tool from Hashicorp, used for Infrastructure As Code (IAC). It works with almost each of the Cloud service providers i.e
- AWS
- GCP
- Azure
- Digital Ocean
- Heroku
etc. It use its custom syntax with file extension of .tf. You define your cloud service provider, what resources you want to create, how all of these resources inter connected, what attributes should come from variables and what should be the desired infrastructure after execution.
main.tf
Cloud Provider
provider "aws" {
region = "us-east-1"
}
Define you resources on AWS
resource "aws_instance" "my_web" {
ami = "ami-xxxx"
instance_type = "t2.micro"
availability_zone = "us-east-1"
vpc_security_group_ids = [aws_security_group.my_sg.id]
key_name = "mykey.pem"
associate_public_ip_address = true
}resource "aws_security_group" "my_sg" {
name = "my-web-sg"
ingress {
description = "Allow traffic on port 80"
from_port = 80
to_port = 80
protocol = "tcp"
}
}
With these few lines of code, you can up your EC2 instance on AWS with port 80 enabled on EC2 instance public IP.
Next you have to run few terraform commands to get things ready.
Terraform doesn’t come with providers in hands instead it does it once it see what providers do you need i.e first piece of code define the cloud provider.
provider "aws" {
region = "us-east-1"
}
To download the respective plugin for the AWS provider you have to run the command
terraform init
which will download the AWS provider plugin code into .terraform
folder inside your project root dir.
Now everything is ready to ship BUT wait… you should make sure what will be executed by terraform using this command
terraform plan
This will give you the whole picture of what resources will be created on your cloud by terraform. This is just a plan and not the actual result.
To execute the plan you saw above, run the next command
terraform apply
This command should execute the plan and show you the detailed progress of what is being creating and created.
If you want to delete all of the created resources back, just run
terraform destroy
Terraform State Backend
Terraform keeps the latest state of your infrastructure in a local file terraform.tfstate
. This state file is used each time you run a terraform plan
, apply
or destroy
command to make sure your terraform code is synced with your cloud actual infrastructure.
BUT… you should never push this state file into your code repository as it may have sensitive data related to your resources.
Wait.. what if multiple team members work on the same terraform project? How i should share this state file with others members then?
Terraform provides state backends where you could store your infrastructure state i.e S3
, Google Cloud Storage
, Consul
, Azurerm
etc.
terraform {
backend "s3" {
bucket = "mybucket"
key = "path/to/my/key"
region = "us-east-1"
}
}
Now other team members should have access to this S3
bucket and run this terraform command to get the updated infrastructure state from S3
before adding more resources.
terraform init
Variables
You can define variables and use them in resources instead of static data from this resource definition
resource "aws_instance" "my_web" {
ami = var.ec2_ami
instance_type = var.ec2_instance_type
availability_zone = var.region
vpc_security_group_ids = [aws_security_group.my_sg.id]
key_name = "mykey.pem"
associate_public_ip_address = true
}
Just create a file called variables.tf
with your desired variables
variable "ec2_ami" {
type = string
default = "ami-xxxx"
}variable "ec2_instance_type" {
type = string
default = "t2.micro"
}variable "region" {
type = string
default = "us-east-1"
}
Terraform supports
- string
- int
- bool
- list
- set
- map
- tuple
- object
as variable data types.
variable "my_list"{
type = list
default = [1, 2, 3]
}variable "assign_public_ip"{
type = bool
default = true
}variable "my_config"{
type = map
default = {
debug = true
database_url = "https://postgres......"
}
}
You can validate variable values as well inside variable definition.
variable "iam_role_name" {
description = "(required) iam role"
type = string
validation {
condition = length(var.iam_role_name) > 2
error_message = "Role name must contain more than 2 characters."
}
}
If you don’t want to define default values here, you can set all these in a separate file by keeping the file extension to .auto.tfvars
i.e variables.auto.tfvars
ec2_ami = "ami-xxxx"
ec2_instance_type = "t2.micro"
assign_public_ip = true
...
...
So at the end, you should have this directory structure
You can define your variables as env vars by prepending TF_VAR
i.e
export TF_VAR_ec2_instance_type
OR by passing as command line args when running terraform plan
or terraform apply
command
terraform plan -var=”ec2_ami=ami-xxxx” -var “region=us-east-1”
Or if you want to load variable values form another file, you can pass variables file as command line args
terraform plan -var-file="myvariables.tfvars"
Other useful commands
validate your terraform scripts
terraform validate
format and indent your terraform scripts
terraform fmt
show what is being created after the terraform apply command
terraform show
Thank you for making it till the end 🎉
If this article helped you, make sure to: