Terraform: Provision AWS Infrastructure
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:
- An AWS account:
- AWS CLI Tool:
- AWS Credentials, For this, the below article will help you.
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.0Terraform 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:
+ createTerraform 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:
+ createTerraform 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" -> nullDo 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 42sDestroy complete! Resources: 3 destroyed.
That all for this article. follow me for more interesting articles.