Terraform is an open-source Infrastructure as Code (IaC) software tool created by HashiCorp. It allows to build, update and delete infrastructure safely, efficiently, and in a repeatable manner. With Terraform, we can define resource configurations in the file(s), which we can version, reuse and share with others.

Using Terraform, we can define resources and infrastructure in human-readable, declarative configuration files and manage the infrastructure’s lifecycle.

Example Terraform file for provisioning an EC2 instance in AWS in the us-east-1 region.

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.16"
    }
  }
}
provider "aws" {
  region  = "us-east-1"
}
resource "aws_instance" "test_server" {
  ami           = "ami-0022f774911c1d690"
  instance_type = "t2.micro"
tags = {
    Name = "TestInstance"
  }
}

 

Terraform has several advantages over manually deploying and managing infrastructure.

  • The human-readable configuration language is easy to learn.
  • The declarative configuration language helps you write infrastructure code quickly.
  • Terraform’s state allows you to track changes made to resources and safely update the cloud resources.
  • You can commit your configurations to version control and collaborate with others on infrastructure deployments.
  • Terraform can manage infrastructure on multiple cloud platforms. It supports all major cloud platforms e.g. AWS, GCP, and Azure.
DevOps — Infrastructure Provisioning Automation using Terraform

 

Now let’s dive into actual code and infrastructure deployment using Terraform.

First thing first, let’s install Terraform.

Install Terraform

I am a big fan of Linux. So I am using Amazon Linux 2 image for my EC2 instance. Let’s see the Terraform installation on Amazon Linux 2.

Install yum-config-manager to manage your repositories.
[ec2-user@~]$ sudo yum install -y yum-utils
Use yum-config-manager to add the official HashiCorp Linux repository.
[ec2-user@~]$ sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
Now install Terraform
[ec2-user@~]$ sudo yum -y install terraform
Now let's verify installation
[ec2-user@~]$ terraform -help
Usage: terraform [global options] <subcommand> [args]
The available commands for execution are listed below.
The primary workflow commands are given first, followed by
less common or more advanced commands.
Main commands:
  init          Prepare your working directory for other commands
  validate      Check whether the configuration is valid
  plan          Show changes required by the current configuration
  apply         Create or update infrastructure
  destroy       Destroy previously-created infrastructure
...

 

Now we have a successful installation of Terraform. Let’s build and deploy the infrastructure.

For installation on other OSes, you find the procedure here

https://learn.hashicorp.com/tutorials/terraform/install-cli?in=terraform/aws-get-started

Deploy Infrastructure

Now, let’s build and deploy something on the AWS cloud. I will provision an EC2 instance on Amazon Web Services (AWS). EC2 instance (virtual machines) is a compute component of AWS.

Prerequisites

To use your IAM credentials to authenticate the Terraform AWS provider, set the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEYenvironment variables.

$ export AWS_ACCESS_KEY_ID=<AWS_ACCESS_KEY_ID>
$ export AWS_SECRET_ACCESS_KEY=<AWS_SECRET_ACCESS_KEY>

 

The set of files used to describe infrastructure in Terraform is known as a Terraform configuration. I will write our first configuration file to define a single AWS EC2 instance. Each Terraform configuration must be in its working directory. Create a directory for your configuration.

First create a directory
$ mkdir provision-aws-instance
$ cd provision-aws-instance
Create a file to define your infrastructure.
$ touch main.tf

 

Open main.tf in VI or any other text editor, paste the lines below, and save the file.

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.16"
    }
  }
}
provider "aws" {
  region  = "us-east-1"
}
resource "aws_instance" "test_server" {
  ami           = "ami-0022f774911c1d690"
  instance_type = "t2.micro"
tags = {
    Name = "TestInstance"
  }
}

 

It is our first Terraform configuration file. 🙂

Initialize the directory

The next step is we have to initialize the directory. When we create a new configuration file or check out an existing configuration from version control, we have to initialize the directory with terraform init.

Terraform init downloads and installs the providers defined in the configuration, which in this case is the aws provider.

$ terraform init
Initializing the backend...
Initializing provider plugins...
- Finding hashicorp/aws versions matching "~> 4.16"...
- Installing hashicorp/aws v4.18.0...
- Installed hashicorp/aws v4.18.0 (signed by HashiCorp)
Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

 

Terraform downloads the AWS provider and installs it in a hidden subdirectory of our current working directory, named .terraform. The terraform init command prints out which version of the provider was installed. Terraform also creates a lock file named .terraform.lock.hcl which specifies the exact provider versions used, so that you can control when you want to update the providers used for your project.

Create Infrastructure

The terraform plan command creates an execution plan, which allows previewing of the changes that Terraform plans to make to the infrastructure. It is always a good idea to preview the changes Terraform will make to the infrastructure to avoid unnecessary changes to the infrastructure.

$ terraform plan
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create
Terraform will perform the following actions:
# aws_instance.test_server will be created
  + resource "aws_instance" "test_server" {
      + ami                                  = "ami-0022f774911c1d690"
      + arn                                  = (known after apply)
      + associate_public_ip_address          = (known after apply)
      + availability_zone                    = (known after apply)
...

 

Now let’s apply the configuration with the terraform apply command. The terraform apply command creates resources defined in the configuration file.

$ terraform apply
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create
Terraform will perform the following actions:
# aws_instance.test_server will be created
  + resource "aws_instance" "test_server" {
      + ami                                  = "ami-0022f774911c1d690"
      + arn                                  = (known after apply)
      + associate_public_ip_address          = (known after apply)
      + availability_zone                    = (known after apply)
      + cpu_core_count                       = (known after apply)
...
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.
Enter a value:

 

Type “yes” to approve the changes. Terraform starts provisioning EC2 instance(s). Once provisioning is complete, it will display how many resources were added, changed, or destroyed. In my case output was

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

 

That’s easy. We have created our first resource using Terraform. Hurray!

Update Infrastructure

Now, let’s modify the resource. Update the configuration file and modify the resource. It’s quite easy with Terraform :).

Edit main.tf file and modify instance tag. I changed the tag from “TestInstance” to “DemoInstance”.

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.16"
    }
  }
}
provider "aws" {
  region  = "us-east-1"
}
resource "aws_instance" "test_server" {
  ami           = "ami-0022f774911c1d690"
  instance_type = "t2.micro"
tags = {
    Name = "DemoInstance"
  }
}

 

Now execute terraform plan command and preview the changes. If you are okay with changes, execute terraform apply to update the tag.

$ terraform plan
aws_instance.test_server: Refreshing state... [id=i-0bc2db1c793e3ce2c]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place
Terraform will perform the following actions:
# aws_instance.test_server will be updated in-place
...
Plan: 0 to add, 1 to change, 0 to destroy.
$ terraform apply

 

Now we can log in to our AWS account and verify if the tag is modified. That’s great!

Destroy Infrastructure

Now let’s see how to remove/delete the resources. Use “terraform destroy” command and Terraform will take care of deleting all the resources defined in the configuration file.

$ terraform destroy
aws_instance.test_server: Refreshing state... [id=i-0bc2db1c793e3ce2c]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  - destroy
Terraform will perform the following actions:
# aws_instance.test_server will be destroyed
  - resource "aws_instance" "test_server" {
      - ami                                  = "ami-0022f774911c1d690" -> null
      - arn                                  = "arn:aws:ec2:us-east-1:297823336606:instance/i-0bc2db1c793e3ce2c" -> null
...
Plan: 0 to add, 0 to change, 1 to destroy.
Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.
Enter a value: yes
aws_instance.test_server: Destroying... [id=i-0bc2db1c793e3ce2c]
aws_instance.test_server: Still destroying... [id=i-0bc2db1c793e3ce2c, 10s elapsed]
aws_instance.test_server: Still destroying... [id=i-0bc2db1c793e3ce2c, 20s elapsed]
aws_instance.test_server: Destruction complete after 29s
Destroy complete! Resources: 1 destroyed.

 

Happy Blogging and Happy Learning!

Raj Shivage

Raj Shivage

DevSecOps Engineer. Cloud Infrastructure Architect. |Passionate about Cloud and DevOps technologies. |Writing: DevOps, Cloud, Automation. |Core skills: AWS, DevOps, Kubernetes, Python, Ansible, Terraform, Linux. |Certifications: AWS Certified Solutions Architect - Professional, AWS Certified DevOps Engineer - Professional, Certified Kubernetes Administrator. |Constantly Learning

Leave a Reply

START A CONVERSATION

Share your requirements and we'll get back to you with how we can help