Terraform: Provision AWS Infrastructure

Rohit Raut
6 min readMay 8, 2021

Terraform is an open-source infrastructure as code tool that enabled you to safely and predictably create, change, and improve infrastructure. Terraform generates an execution plan that describes the desired state. As Terraform code executes, it automatically determines what changes need to be done.

In this article, we will launch amazon ami, block storage, and attach block storage to the instance.

Prerequisites:

Step1: Configure AWS CLI

After Installing the AWS CLI program, we need to configure the CLI tool

aws configure

aws credentials always store in the profile. The profile is used when you want to work with different credentials might have different permission. by default it has profile name is “default”.

You can see this profile in this file.

~/.aws/credentials

Follow the steps and give your access key, secret key, and region from where you want to use resources.

Step2: Create a Directory for Each Infrastructure as code.

A good practice is to create a new folder for each IAC.

mkdir terraform-aws-ec2-storage

Change Directory

cd terraform-aws-ec2-storage

Create a file for code

# End with .tf
vim aws-ec2-storage.tf

Paste the below code in this file.

provider "aws" {
region = "ap-south-1"
profile = "default"
}
resource "aws_instance" "dev" {
ami = "ami-010aff33ed5991201"
instance_type = "t2.micro"
tags = {
Name = "dev"
}
}
output "dev-server" {
value = aws_instance.dev.availability_zone
}resource "aws_ebs_volume" "volume1" {
availability_zone = aws_instance.dev.availability_zone
size = 10
tags = {
Name = "ebs-for-dev-webservermount"
}
}
resource "aws_volume_attachment" "volume_attachment" {
device_name = "/dev/xvdh"
instance_id = aws_instance.dev.id
volume_id = aws_ebs_volume.volume1.id
}

Provider

The first block is provider , This block tells who is responsible to create the resource. here in our case is AWS. Profile is an attribute that gives credentials need to interact with AWS. We store our credentials in default the profile when we run aws configure the command. Instead of giving credentials directly here, we give credentials from the profile. When terraform execute code they first retrieve this credentials from ~/.aws/credentials the file.

resource

Resource block has two things 1. actual resource name 2. variable/reference of that resource for further use in code. All the information about the resource is stored in the 2nd string.

Output

It will print the value of variable in the terminal

Initializing the Directory

Terraform works with plugins-based architecture when we initialize the directory it downloads plugins that are required.

To initialize the directory

terraform init

Output:

Initializing the backend...Initializing provider plugins...
- Reusing previous version of hashicorp/aws from the dependency lock file
- Using previously-installed hashicorp/aws v3.39.0
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.

Format terraform file

There is one more important command terraform fmt (format). This command automatically formats the terraform files present in the directory for more readability.

Check for syntax error

To check syntax error terraform provides a command

terraform validate

Create infrastructure

Before we apply the infrastructure to check the changes

terraform plan

This will show the execution 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_ebs_volume.volume1 will be created
+ resource "aws_ebs_volume" "volume1" {
+ arn = (known after apply)
+ availability_zone = (known after apply)
+ encrypted = (known after apply)
+ id = (known after apply)
+ iops = (known after apply)
+ kms_key_id = (known after apply)
+ size = 10
+ snapshot_id = (known after apply)
+ tags = {
+ "Name" = "ebs-for-dev-webservermount"
}
+ tags_all = {
+ "Name" = "ebs-for-dev-webservermount"
}
+ throughput = (known after apply)
+ type = (known after apply)
}
#....output omitted....#
Plan: 3 to add, 0 to change, 0 to destroy.Changes to Outputs:
+ dev-server = (known after apply)

The Last command is to execute the file

terraform apply

output:

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_ebs_volume.volume1 will be created
+ resource "aws_ebs_volume" "volume1" {
+ arn = (known after apply)
+ availability_zone = (known after apply)
+ encrypted = (known after apply)
+ id = (known after apply)
+ iops = (known after apply)
+ kms_key_id = (known after apply)
+ size = 10
+ snapshot_id = (known after apply)
+ tags
#...output omitted...#

before it applies the changes terraform ask for approval before proceedings

Plan: 3 to add, 0 to change, 0 to destroy.Changes to Outputs:
+ dev-server = (known after apply)
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yesaws_instance.dev: Creating...
aws_instance.dev: Still creating... [10s elapsed]
aws_instance.dev: Still creating... [20s elapsed]
aws_instance.dev: Still creating... [30s elapsed]
aws_instance.dev: Creation complete after 36s [id=i-0c54f1bbed56cfd53]
aws_ebs_volume.volume1: Creating...
aws_ebs_volume.volume1: Still creating... [11s elapsed]
aws_ebs_volume.volume1: Creation complete after 12s [id=vol-0b6ca4f5648343d6d]
aws_volume_attachment.volume_attachment: Creating...
aws_volume_attachment.volume_attachment: Still creating... [10s elapsed]
aws_volume_attachment.volume_attachment: Still creating... [20s elapsed]
aws_volume_attachment.volume_attachment: Still creating... [30s elapsed]
aws_volume_attachment.volume_attachment: Creation complete after 35s [id=vai-4057363535]
Apply complete! Resources: 3 added, 0 changed, 0 destroyed.Outputs:dev-server = "ap-south-1a"
terraform destroy

Terraform destroy command is used to destroy all the infrastructure created.

terraform is so intelligent they automatically come to know in which order they have to destroy the infrastructure.

# aws_volume_attachment.volume_attachment will be destroyed
- resource "aws_volume_attachment" "volume_attachment" {
- device_name = "/dev/xvdh" -> null
- id = "vai-4057363535" -> null
- instance_id = "i-0c54f1bbed56cfd53" -> null
- volume_id = "vol-0b6ca4f5648343d6d" -> null
}
Plan: 0 to add, 0 to change, 3 to destroy.Changes to Outputs:
- dev-server = "ap-south-1a" -> null
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: yesaws_volume_attachment.volume_attachment: Destroying... [id=vai-4057363535]
aws_volume_attachment.volume_attachment: Still destroying... [id=vai-4057363535, 10s elapsed]
aws_volume_attachment.volume_attachment: Destruction complete after 11s
aws_ebs_volume.volume1: Destroying... [id=vol-0b6ca4f5648343d6d]
aws_ebs_volume.volume1: Destruction complete after 1s
aws_instance.dev: Destroying... [id=i-0c54f1bbed56cfd53]
aws_instance.dev: Still destroying... [id=i-0c54f1bbed56cfd53, 10s elapsed]
aws_instance.dev: Still destroying... [id=i-0c54f1bbed56cfd53, 20s elapsed]
aws_instance.dev: Still destroying... [id=i-0c54f1bbed56cfd53, 30s elapsed]
aws_instance.dev: Still destroying... [id=i-0c54f1bbed56cfd53, 40s elapsed]
aws_instance.dev: Destruction complete after 42s
Destroy complete! Resources: 3 destroyed.

That all for this article. follow me for more interesting articles.

Thank you for reading…

--

--