Create AWS Infrastructure Using Terraform

Ranjit Jadhav
4 min readJan 14, 2022

--

What is IaC?

To get started with the Terraform and AWS, You should know about IaC(Infrastructure as Code).

IaC is the process of provisioning and managing of IT infrastructure using the configuration files. There are lots of IaC tools available, but I have used Terraform to manage infrastructure.

Prerequisites to Manage AWS infrastructure using Terraform.

AWS Account (https://aws.amazon.com/).

Terraform installed (https://learn.hashicorp.com/tutorials/terraform/install-cli)

Basic Knowledge of Terraform configuration language. (https://www.terraform.io/)

Declaring an input variable

Created Variable file (variable.tf ).

variable "aws_access_key" {}variable "aws_secret_key" {}variable "region" {}variable "ami_id" {}variable "subnet_id" {}variable "instance_type" {}variable "server_name" {}variable "key_name" {}variable "vpc_id" {}

aws_access_key: aws_access_key.

aws_secret_key: aws_secret_key.

region: Available region (e.g us-east-1).

ami_id: ami_id of Amazon machine image (i.e. Ubuntu, window etc).

subnet_id: available subnet_id.

instance_type: t2.micro, t2.medium etc.

key_name: private key file name.

server_name: Name of the ec2 instance.

vpc_id: Available VPC.

Implement Configuration file Logic.

Created a configuration file (main.tf).

There are a lot of providers available in terraform, but for AWS provisioning, I have taken aws providers in terraform configuration language.

Access input variable as a var.variable_name in the configuration file.

provider "aws" {   access_key = var.aws_access_key   secret_key = var.aws_secret_key   region = var.region}

Create a private key pair file using the RSA algorithm and store it into one folder.

I have created a private key file with a name as a key_name (var.key_name).

And stored it into (/home/ubuntu/pem_files/) location for later use.

resource "tls_private_key" "pk" {    algorithm = "RSA"    rsa_bits  = 4096}resource "aws_key_pair" "kp" {    key_name   = var.key_name    public_key = tls_private_key.pk.public_key_openssh    provisioner "local-exec" {           command = "echo '${tls_private_key.pk.private_key_pem}'        > /home/ubuntu/pem_files/'${var.key_name}'.pem"    }}

Added security groups to the VPC and opened the inbound rule of 80 ports to all.

resource "aws_security_group" "web_server" {    description = "Allow TLS inbound traffic"     vpc_id      = var.vpc_id

ingress {
description = "TLS from VPC" from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] }
}

Created Configuration for EC2 instance with provided input variable. And added root level EBS volume to the instance (in root_block_device block).

resource "aws_instance" "web_server" {       ami = var.ami_id       subnet_id = var.subnet_id       instance_type = var.instance_type       key_name = aws_key_pair.kp.key_name       security_groups = [aws_security_group.web_server.id]

root_block_device {
delete_on_termination = true volume_size = 16 volume_type = "gp2" } tags = { Name = var.server_name }}

Complete configuration file with provider and resources (main.tf).

provider "aws" {     access_key = var.aws_access_key     secret_key = var.aws_secret_key     region = var.region}resource "tls_private_key" "pk" {    algorithm = "RSA"    rsa_bits  = 4096}resource "aws_key_pair" "kp" {    key_name   = var.key_name    public_key = tls_private_key.pk.public_key_openssh    provisioner "local-exec" {        command = "echo '${tls_private_key.pk.private_key_pem}' > /home/ubuntu/pem_files/'${var.key_name}'.pem"    }}resource "aws_security_group" "web_server" {    description = "Allow TLS inbound traffic"    vpc_id      = var.vpc_id    ingress {       description      = "TLS from VPC"       from_port        = 80       to_port          = 80       protocol         = "tcp"       cidr_blocks      = ["0.0.0.0/0"]    }}resource "aws_instance" "web_server" {    ami = var.ami_id    subnet_id = var.subnet_id    instance_type = var.instance_type    key_name = aws_key_pair.kp.key_name    security_groups = [aws_security_group.web_server.id]

root_block_device {
delete_on_termination = true volume_size = 16 volume_type = "gp2" } tags = { Name = var.server_name }}

I have taken instance_id, instance_public_ip, and key_name as an output.

Declaring an output variable.

Created output file (output.tf).

Access output value with resource(aws_instance), its name (web_server) and property name(id).

e.g. I have taken ID of the ec2 instance in output i.e. aws_instance.web_server.id

output "instance_id" {  description = "ID of the EC2 instance"  value       = aws_instance.web_server.id}output "instance_public_ip" {  description = "Public IP address of the EC2 instance"  value       = aws_instance.web_server.public_ip}output "key_name" {  description = "private key name"  value       = aws_instance.web_server.key_name}

Run Terraform script using the following steps.

I have created one directory with the name aws_terraform and put all files into the folder (variable.tf, main.tf, output.tf).

Step 1: Go into the directory.

Step 2: Prepare your working directory.

terraform init.

Step 3: Show changes required by the current configuration.

terraform plan -var=aws_access_key=****** -var=aws_secret_key=****** -var=region=us-east-1 -var=ami_id=ami-0747bdcabd34c712a -var=subnet_id=******* -var=instance_type=t2.micro -var=server_name=aws_server_demo -var=key_name=aws_server_demo -var=vpc_id=******

Step 4: Create Infrastructure.

terraform apply -var=aws_access_key=****** -var=aws_secret_key=****** -var=region=us-east-1 -var=ami_id=ami-0747bdcabd34c712a -var=subnet_id=******* -var=instance_type=t2.micro -var=server_name=aws_server_demo -var=key_name=aws_server_demo -var=vpc_id=******

After completion of the apply command, one state file is created with the name terraform.tfstate. This file contains metadata about configuration.

Step 5: Show Infrastructure output.

terraform output

Step 6: Login into the AWS console and check Infrastructure. An EC2 instance has been created successfully with the same output as terraform output.

Conclusion:

This blog is for the people who want to increase infrastructure productivity using automation and minimizing human errors, hope this will help you.

--

--

Ranjit Jadhav

Consultant: Microservices @Iauro System Private Limited