Day 66 - Terraform Hands-on Project EC2-VPC-SUBNET-SG

Day 66 - Terraform Hands-on Project EC2-VPC-SUBNET-SG

Welcome back to your Terraform journey.

In the previous tasks, you have learned about the basics of Terraform, its configuration file, and creating an EC2 instance using Terraform. Today, we will explore more about Terraform and create multiple resources.

Create a VPC (Virtual Private Cloud) with CIDR block 10.0.0.0/16

terrraform.tf

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"
    }
  }
}

provider.tf

provider "aws" {
  region = "us-east-1"
}

main.tf

resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"

  tags = {
    Name = "myvpc"
  }
}

Save the file and execute terraform init and terraform apply in the project directory to create the VPC. Once the command execution completes, you can check the AWS Management Console for the newly created VPC named "myvpc".

Create a public subnet within the above VPC.

Similarly, let's create a public subnet within our VPC. Open the main.tf file and add the following code:

resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"
  tags = {
    Name = "myvpc"
  }
}
resource "aws_subnet" "public" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "10.0.1.0/24"
  tags = {
    Name = "publicsubnet"
  }
}

Save the file and execute terraform apply to create the public subnet. Verify the subnet creation in the AWS Management Console.

Create a private subnet within the above VPC.

Similarly, let's create a private subnet within our VPC. Open the main.tf file and add the following code:

resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"
  tags = {
    Name = "myvpc"
  }
}
resource "aws_subnet" "private" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "10.0.1.0/24"
  tags = {
    Name = "privatesubnet"
  }
}

Save the file and execute terraform apply to create the public subnet. Verify the subnet creation in the AWS Management Console.

Create an Internet Gateway (IGW) and attach it to the VPC.

To provide internet access to our VPC, we need to create an Internet Gateway (IGW). Create a new file named internetgateway.tf and add the following code:

resource "aws_internet_gateway" "gw" {
  vpc_id = aws_vpc.main.id
  tags = {
    Name = "internet-gateway"
  }
}

Save the file and execute terraform apply to create the Internet Gateway. Verify the Internet Gateway creation in the AWS Management Console.

Create a route table for the public subnet and associate it with the public subnet. This route table should have a route to the Internet Gateway.

Now, let's create a route table for our public subnet and associate it with the subnet. Open a new file named routetable.tf and add the following code

resource "aws_route_table" "public" {
  vpc_id = aws_vpc.main.id
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.gw.id
  }
  tags = {
    Name = "public"
  }
}
resource "aws_route_table_association" "public_subnet_association" {
  subnet_id      = aws_subnet.public.id
  route_table_id = aws_route_table.public.id
}

Save the file and execute terraform apply to create the routeing table and associate it with the public subnet. Verify the routeing table and subnet association in the AWS Management Console

Create a Security Group

For our EC2 instance, we need to create a security group that allows SSH access and HTTP access from anywhere. Create a new file named securitygroup.tf and add the following code:

resource "aws_security_group" "web_server" {
  name        = "web-server-sg"
  description = "Allow SSH and HTTP access from anywhere"
  vpc_id = aws_vpc.main.id
  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
  ingress {
    from_port   = 80
    to_port     = 80
    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"]
  }
}

Save the file and execute terraform apply to create the security group. Verify the security group and its rules in the AWS Management Console

Create User Data to Install Apache

To host a simple website on our EC2 instance, we need to install Apache. We can use user data in Terraform to run a shell script during instance launch. Create a new file named userdata.sh and add the following code:

#!/bin/bash
sudo apt-get update -y
sudo apt-get install -y apache2
sudo systemctl start apache2
sudo systemctl enable apache2
echo "<!DOCTYPE html>
<html>
<head>
    <title>Introduction</title>
    <style>
        body {
            background-color: #d8e2dc;
            font-family: Arial, sans-serif;
            color: #3c415e;
            text-align: center;
            padding: 50px;
        }
        h1 {
            font-size: 3em;
            margin-bottom: 20px;
            text-shadow: 0 2px 2px rgba(0,0,0,0.1);
        }
        p {
            font-size: 1.5em;
            line-height: 1.5;
            margin-bottom: 30px;
        }
    </style>
</head>
<body>
    <h1>Welcome to terraform</h1>
    <p>Learn DevOps like a Pro</p>
</body>
</html>" > /var/www/html/index.html
sudo systemctl restart apache2

Save the file and make sure it is in the same directory as your Terraform configuration files.

Launch an EC2 instance in the public subnet with the following details

Finally, let's create our EC2 instance in the public subnet with the required configurations. Open the ec2.tf file and add the following code

resource "aws_instance" "example" {
  ami           = "ami-0557a15b87f6559cf"
  instance_type = "t2.micro"
  key_name      = "rjthapaa"
  subnet_id     = aws_subnet.public.id
  associate_public_ip_address = true
  security_groups = [
    aws_security_group.web_server.id
  ]
  user_data = filebase64("userdata.sh")
  tags = {
    Name = "EC2web-server"
  }
}

Create an Elastic IP

To associate a static IP with our EC2 instance, we need to create an Elastic IP. Create a new file named elasticip.tf and add the following code:

resource "aws_eip" "ip" {
  instance = aws_instance.example.id
  vpc      = true
  tags = {
    Name = "elastic-ip"
  }
}

Happy Terraforming:)

For Terraform Code @sampleproject https://github.com/rjthapaa/Terraform.tf.git