Skip to main content

Command Palette

Search for a command to run...

Day 66 - Terraform Hands-on Project - Build Your Own AWS Infrastructure with Ease using Infrastructure as Code (Jan 31, 2024)

Updated
5 min read
Day 66 - Terraform Hands-on Project - Build Your Own AWS Infrastructure with Ease using Infrastructure as Code (Jan 31, 2024)

🙏 Introduction:

In this blog, 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.

🎯Task: 1

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

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

tags = {
    Name = "main"
  }
}
  • This will create a new VPC in your AWS account with the specified CIDR block and a name tag of main.

  • Run the terraform init command to initialize the working directory and download the required providers. After that, run terraform apply to create the VPC in our AWS account

  • VPC has been created successfully

Create a public subnet with CIDR block 10.0.1.0/24 in the above VPC

resource "aws_subnet" "public_subnet" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "10.0.1.0/24"

  tags = {
    Name = "Public Subnet"
  }
}

  • Run the terraform init command to initialize the working directory and download the required providers. After that, run terraform apply to create the public subnet in our AWS account

  • Public Subnet is created

Create a private subnet with CIDR block 10.0.2.0/24 in the above VPC

resource "aws_subnet" "private_subnet" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "10.0.2.0/24"


  tags = {
    Name = "Private Subnet"
  }
}

  • Run the terraform init command to initialize the working directory and download the required providers. After that, run terraform apply to create the private subnet in our AWS account

  • Private Subnet is created

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

resource "aws_internet_gateway" "gw" {
  vpc_id = aws_vpc.main.id

  tags = {
    Name = "igw"
  }
}

  • Run the terraform init command to initialize the working directory and download the required providers. After that, run terraform apply to create the Internet Gateway in our AWS account

  • Internet gateway is created

  • Internet Gateway (IGW) is attach it to the VPC

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

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 = "route-table"
  }
}

resource "aws_route_table_association" "public" {
  subnet_id      = aws_subnet.public_subnet.id
  route_table_id = aws_route_table.public.id
}
  • First we create a route table for public subnet.

  • aws_route_table block creates a new route table in the VPC specified by vpc_id attribute. It also defines a route that sends all traffic with destination CIDR 0.0.0.0/0 to the internet gateway specified by gateway_id attribute. The tags attribute sets a name for the route table for easy identification.

  • Then associate route table with public subnet.

  • aws_route_table_association block associates the newly created route table with a public subnet specified by the subnet_id attribute. The route_table_id attribute refers to the ID of the route table created in the previous block.

  • Run the terraform init command to initialize the working directory and download the required providers. After that, run terraform apply to create the route table in our AWS account

  • Route table is successfully created

  • Route table is associate with public subnet

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

  • AMI: ami-008fe2fc65df48dac

  • Instance type: t2.micro

  • Security group: Allow SSH access from anywhere

  • User data: Use a shell script to install Apache and host a simple website

  • Create an Elastic IP and associate it with the EC2 instance

resource "aws_instance" "web_server" {
  ami           = "ami-008fe2fc65df48dac"
  instance_type = "t2.micro"
  key_name      = "terra_key"
  subnet_id     = aws_subnet.public_subnet.id

  vpc_security_group_ids = [
      aws_security_group.ssh_access.id
  ]
}
resource "aws_security_group" "ssh_access" {
  name_prefix = "ssh_access"
  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"]
  }
}

User data: Use a shell script to install Apache and host a simple website

 user_data = <<-EOF
        #!/bin/bash
        sudo apt-get update -y
        sudo apt-get install apache2 -y
        sudo systemctl start apache2
        sudo systemctl enable apache2
        echo "<html><body><h1>Welcome to my website!</h1></body></html>" > /var/www/html/index.html
        sudo systemctl restart apache2
  EOF

Create an Elastic IP and associate it with the EC2 instance

resource "aws_eip" "eip" {
  instance = aws_instance.web_server.id


  tags = {
    Name = "test-eip"
  }
}

Final main.tf file

terraform {
 required_providers {
        aws = {
        source  = "hashicorp/aws"
        version = "~> 4.16"
        }
    }
        required_version = ">= 1.2.0"
}

provider "aws" {
region = "us-west-2"
}

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

tags = {
    Name = "main"
  }
}

resource "aws_subnet" "public_subnet" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "10.0.1.0/24"

  tags = {
    Name = "Public Subnet"
  }
}

resource "aws_subnet" "private_subnet" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "10.0.2.0/24"


  tags = {
    Name = "Private Subnet"
  }
}

resource "aws_internet_gateway" "gw" {
  vpc_id = aws_vpc.main.id

  tags = {
    Name = "igw"
  }
}

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 = "route-table"
  }
}

resource "aws_route_table_association" "public" {
  subnet_id      = aws_subnet.public_subnet.id
  route_table_id = aws_route_table.public.id
}

resource "aws_instance" "web_server" {
  ami           = "ami-008fe2fc65df48dac"
  instance_type = "t2.micro"
  key_name      = "terra_key"
  subnet_id     = aws_subnet.public_subnet.id

  vpc_security_group_ids = [
      aws_security_group.ssh_access.id
  ]

  user_data = <<-EOF
        #!/bin/bash
        sudo apt-get update -y
        sudo apt-get install apache2 -y
        sudo systemctl start apache2
        sudo systemctl enable apache2
        echo "<html><body><h1>Welcome to my website!</h1></body></html>" > /var/www/html/index.html
        sudo systemctl restart apache2
  EOF

    tags = {
    Name = "terraform-instance"
  } 
}
resource "aws_security_group" "ssh_access" {
  name_prefix = "ssh_access"
  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"]
  }
}

resource "aws_eip" "eip" {
  instance = aws_instance.web_server.id


  tags = {
    Name = "test-eip"
  }
}
  • New instance is created with the desired details configuration

  • Elastic IP created

Open the website URL in a browser to verify that the website is hosted successfully

More from this blog

DevOps Journey with M Hassan

174 posts

I am writing these blogs because I recently completed a comprehensive DevOps course where I gained in-depth knowledge of the topics mentioned. As I progressed through the course, I realized the importance of having a concise and accessible resource to revise and reinforce my understanding of each topic. Therefore, I decided to create cheat sheets in the form of blog posts. These cheat sheets will not only serve as a handy reference for myself but also benefit others who are also interested in mastering DevOps concepts. By documenting each topic and providing concise explanations, I aim to create a valuable resource that simplifies complex concepts and facilitates hands-on practice. This way, I can solidify my own understanding while helping others on their DevOps journey.