Terraform Tutorial


Setup

Windows

  1. https://www.terraform.io/downloads
  2. Set Env Path
    1. System Variables → Path
  1. Add path to environment

Mac via Homebrew

  1. https://brew.sh/
  2. Copy command
  3. Paste command in Terminal to install Homebrew
  4. Install terraform
brew install terraform

Test Terraform using cmd/terminal

terraform -v

Mac via binary download

  1. https://www.terraform.io/downloads
  2. Unzip file
  3. echo $PATH to see list of locations
  4. move terraform binary to one of the locations
    1. Generally use usr/local/bin

Tutorial

Terraform is declarative in nature and therefore we are configuring what we want to see in the cloud instead of how much we want to add/remove from the cloud.

Cloud Provider

  1. Select Cloud to configure (AWS)
  2. https://registry.terraform.io/providers/hashicorp/aws/latest/docs

Configure the Provider and Region

  1. Create a .tf file. E.g. main.tf
# Configure the AWS Provider
provider "aws" {
  region = "ap-southeast-1"
}

Setup Authentication

1. Get Access and Secret Key from Cloud Provider

  1. AWS
  2. Profile Name
  3. Security Credentials
  4. Access Key Tab
  1. Create New Access Key
  2. Show Access Key
    1. This will provide the value for access_key and secret_key
  3. Download Key File as secret_key will not be able to be found anymore after you close the tab
# Configure the AWS Provider
provider "aws" {
  region = "ap-southeast-1"
  access_key = "my-access-key"
  secret_key = "my-secret-key"
}

Create Resources

E.g. Resources includes EC2, etc.

Syntax for creating resources

resource "<provider>_<resource_type>" "<name>" {
  # config options in key value pairs
  key = "value"
  key2 = "value2"
}

Creating EC2 Instance

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance

  1. Obtain AMI from AWS to be used in the code
# Configure the AWS Provider
provider "aws" {
  region = "ap-southeast-1"
  access_key = "my-access-key"
  secret_key = "my-secret-key"
}

resource "aws_instance" "my-first-server" {
  ami           = "ami-055d15d9cfddf7bd3"
  instance_type = "t2.micro"

  tags = {
    Name = "ubuntu"
  }
}

Terraform Init

Looks at the config in .tf files and look for all the providers defined and will download all the plugins required.

  1. Navigate terminal to where the .tf file is
terraform init

Terraform Plan

Does a dry run of the code and show you all the changes that is going to be applied Delete/Create/Modify any instances.

terraform plan

Terraform Apply

Run the code to production.

terraform apply

Terraform Destroy

Delete the whole architecture. Usually will not do this and will instead make changes within the file and use terraform apply to add/remove instances from the architecture.

terraform destroy

Destroying specific resource

  1. See the resources that are tracked by terraform terraform state list
  2. Remove the states that you DO NOT want to destroyterraform state rm <resource1> <resource2> <resource3> ...
  3. terraform destroy to destroy the rest of the available states

Referencing Resources

You can reference other resources by pointing to the <provider>_<resource_type>.<name>.id

resource "aws_vpc" "first-vpc" {
  cidr_block       = "10.0.0.0/16"

  tags = {
    Name = "production"
  }

}

resource "aws_subnet" "subnet-1" {
 # this is taking from the resource name above. Every resource has id property to access
  vpc_id     = aws_vpc.first-vpc.id
  cidr_block = "10.0.1.0/24"

  tags = {
    Name = "prod-subnet"
  }
}

Terraform Files

terraform init creates a .terraform folder in the directory that contains the configs for the resources.

terraform.tfstate contains the state of terraform so that when we make any modifications/etc., it will be able to check the current status and compare against the code.

Terraform State List

This shows all the resources that was created along with the resource name

terraform state list

Terraform State Show

This shows the detailed output regarding the state which would normally be stored in the console.

# terraform state show <resource>.<resource_name>
terraform state show aws_eip.one

Terraform Output

This will print out the details and prints out in the console after terraform refresh. You can only have 1 value per output.

# output "<output_key_name>" {
#   value = <resource_type>.<resource_name>.<property>
# }

output "server_public_ip" {
  value = aws_eip.one.public_ip
}

💡 Be careful when you want to add new outputs and see the outputs. Not a good idea to use terraform apply as that might make changes on production side.

Target Resources

This will only apply/destroy changes to a specific resource instead of potentially changing everything in production (e.g. route table, subnet)

# terraform destroy -target <resource>.<resource_name>
# terraform apply -target <resource>.<resource_name>

terraform apply -target aws_eip.one

Variables

This will allow terraform file to reference a variable. Generally passed at runtime.

variable "variable_name" {
  description = ""
  default = "abcd"
  type = String
}

# To access the variable
var.variable_name

Method 1: Input value at Terraform Apply user prompt

If a value is not defined in the variable, at terraform apply/destroy, user will be prompted to submit a value

Method 2: Input value as part of command

Alternatively, we can use -var to specify the value of the variable during terraform apply

terraform apply -var "variable_name=abcd"

Method 3: Input value at .tfvars file

We can create a .tfvars file to store the values of the variables. E.g. example.tfvars

variable_name = "abcd"

Run the main.tf file referencing the file via -var-file

terraform apply -var-file example.tfvars



Enjoy Reading This Article?

Here are some more articles you might like to read next:

  • Chess DE Project
  • Full vs incremental load
  • Benchmarking OLTP vs OLAP
  • Github Actions Tutorial
  • Docker Tutorial