Project: Create Infrastructure using Terraform

·

5 min read

So, basically in this project, we are going to use Terraform as Infrastructure as Code and write a Terraform file to build an entire Virtual Network on AWS. We can also do this using the AWS console, but for automation, we will use the AWS CLI and Terraform. Additionally, we will create two subnets, an Internet Gateway, security groups, and a Load Balancer, storing all the files in an S3 Bucket so that everyone in the organization can use the code for any changes.

Prerequisites:-

Text: AWS CLI: Since we are going to create the Virtual Network on the AWS platform, we will use the AWS CLI on our system. You can follow the official documentation for the installation of AWS CLI.

Terraform: As we are using Terraform for infrastructure as code, we need to install it on our local system so that we can use Terraform commands on it.

Use the following commands to install terraform in your local system:

sudo apt-get update
sudo apt-get install -y gnupg software-properties-common

Now, We will create a new folder in our local directory and we will write our terraform files in that directory only.

mkdir terraform-proj

cd terraform-proj

Now open this folder on your favourite code editor and create a new file provider.tf in that folder

So, the provider.tf file will be used to declare the provider we are using in our project, as there are different cloud providers like Azure, AWS, GCP, etc. In our project, we are going to use AWS, and we also need to declare the region, version, and some other parameters in the provider.tf file only.

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "5.11.0"
    }
  }
}

provider "aws" {
  # Configuration options
  region = "us-east-1"
}

Now we will create a new file main.tf in which we will write the actual that will be going to run when we give the command Terraform apply.

Firstly we will create AWS VPC on our main.tf file

resource "aws_vpc" "myvpc" {
  cidr_block = var.cidr
}

Here we have used a variable var.cidr which we have saved in our variable.tf file

variable "cidr" {
  default = "10.0.0.0/16"
}

After creating VPC we will create two subnets named as sub1 and sub2

resource "aws_subnet" "sub1" {
  vpc_id                  = aws_vpc.myvpc.id
  cidr_block              = "10.0.0.0/24"
  availability_zone       = "us-east-1a"
  map_public_ip_on_launch = true
}

resource "aws_subnet" "sub2" {
  vpc_id                  = aws_vpc.myvpc.id
  cidr_block              = "10.0.1.0/24"
  availability_zone       = "us-east-1b"
  map_public_ip_on_launch = true
}

In this we need to provide vpc_id, cidr_block, availability_zone and map_public_ip_on_launch.

Now we will create internet gateway:

resource "aws_internet_gateway" "igw" {
  vpc_id = aws_vpc.myvpc.id
}

Now we will create Route table:

resource "aws_route_table" "RT" {
  vpc_id = aws_vpc.myvpc.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.igw.id
  }
}

In this we have provided the route in route table only and connected it to the internet gateway.

Now we will connect the route to the subnets:

resource "aws_route_table_association" "rta1" {
  subnet_id      = aws_subnet.sub1.id
  route_table_id = aws_route_table.RT.id
}

resource "aws_route_table_association" "rta2" {
  subnet_id      = aws_subnet.sub2.id
  route_table_id = aws_route_table.RT.id
}

Create a new security which will give the security at the last point and we will also give the inbound and outbound rules so that we can allow some particular traffic to access our application

resource "aws_security_group" "webSg" {
  name   = "web"
  vpc_id = aws_vpc.myvpc.id

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

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "Web-sg"
  }
}

To store our terraform file and reuse it in future we will create a S3 bucket:

resource "aws_s3_bucket" "example" {
  bucket = "abhisheksterraform2023project"
}

Now its time to create EC2 instances in which our application will be actually deployed:

resource "aws_instance" "webserver1" {
  ami                    = "ami-0261755bbcb8c4a84"
  instance_type          = "t2.micro"
  vpc_security_group_ids = [aws_security_group.webSg.id]
  subnet_id              = aws_subnet.sub1.id
  user_data              = base64encode(file("userdata.sh"))
}

resource "aws_instance" "webserver2" {
  ami                    = "ami-0261755bbcb8c4a84"
  instance_type          = "t2.micro"
  vpc_security_group_ids = [aws_security_group.webSg.id]
  subnet_id              = aws_subnet.sub2.id
  user_data              = base64encode(file("userdata.sh"))
}

In this, we have used the userdata.sh file, which contains the tasks and frontend of our application. This will be displayed in your browser when you deploy your application on an EC2 instance.

#!/bin/bash
apt update
apt install -y apache2

# Get the instance ID using the instance metadata
INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)

# Install the AWS CLI
apt install -y awscli

# Download the images from S3 bucket
#aws s3 cp s3://myterraformprojectbucket2023/project.webp /var/www/html/project.png --acl public-read

# Create a simple HTML file with the portfolio content and display the images
cat <<EOF > /var/www/html/index.html
<!DOCTYPE html>
<html>
<head>
  <title>My Portfolio</title>
  <style>
    /* Add animation and styling for the text */
    @keyframes colorChange {
      0% { color: red; }
      50% { color: green; }
      100% { color: blue; }
    }
    h1 {
      animation: colorChange 2s infinite;
    }
  </style>
</head>
<body>
  <h1>Terraform Project Server 1</h1>
  <h2>Instance ID: <span style="color:green">$INSTANCE_ID</span></h2>
  <p>Welcome to KetanOps</p>

</body>
</html>
EOF

# Start Apache and enable it on boot
systemctl start apache2
systemctl enable apache2

At last we will create load balancer:

#create alb
resource "aws_lb" "myalb" {
  name               = "myalb"
  internal           = false
  load_balancer_type = "application"

  security_groups = [aws_security_group.webSg.id]
  subnets         = [aws_subnet.sub1.id, aws_subnet.sub2.id]

  tags = {
    Name = "web"
  }
}

resource "aws_lb_target_group" "tg" {
  name     = "myTG"
  port     = 80
  protocol = "HTTP"
  vpc_id   = aws_vpc.myvpc.id

  health_check {
    path = "/"
    port = "traffic-port"
  }
}

resource "aws_lb_target_group_attachment" "attach1" {
  target_group_arn = aws_lb_target_group.tg.arn
  target_id        = aws_instance.webserver1.id
  port             = 80
}

resource "aws_lb_target_group_attachment" "attach2" {
  target_group_arn = aws_lb_target_group.tg.arn
  target_id        = aws_instance.webserver2.id
  port             = 80
}

resource "aws_lb_listener" "listener" {
  load_balancer_arn = aws_lb.myalb.arn
  port              = 80
  protocol          = "HTTP"

  default_action {
    target_group_arn = aws_lb_target_group.tg.arn
    type             = "forward"
  }
}

output "loadbalancerdns" {
  value = aws_lb.myalb.dns_name
}

Now save all the files and after that use the command :

terraform init

This command is used to initialize terraform in your project and after you apply this command you will see some configure files in your directory.

now use the command:

terraform plan

This command is used to check if there is any error in your code.

Now at last we will use:

terraform apply

After this login to your AWS console you will see Vpc will be created in your AWS account.

That's a wrap..........