Building AWS Infrastructure Using Infrastructure as Code (IaC)

Building AWS Infrastructure Using Infrastructure as Code (IaC)

Day 66 of 90daysofdevops

ยท

6 min read

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 like VPC, Subnet, Internet gateway and host a website using EC2 instance.

Project File Structure

๐Ÿ“ terraform/terraform-aws 
    --๐Ÿ“„ terraform.tf 
    --๐Ÿ“„ provider.tf 
    --๐Ÿ“„ vpc.tf
    --๐Ÿ“„ subnet.tf 
    --๐Ÿ“„ internetgateway.tf 
    --๐Ÿ“„ routetable.tf 
    --๐Ÿ“„ securitygroup.tf
    --๐Ÿ“„ ec2.tf
    --๐Ÿ“„ eip.tf

Step 1: Create a VPC (Virtual Private Cloud)

  • Create a terraform.tf where you have to pass on AWS provider details.

      terraform {
        required_providers {
          aws = {
            source  = "hashicorp/aws"
            version = "~> 4.0"
          }
        }
      }
    
  • Add a provider.tf and add details about AWS Region that you are using.

      provider "aws" {
        region = "us-east-1"
      }
    
  • Add the following code to create a VPC vpc.tf

      resource "aws_vpc" "main" {
        cidr_block       = "10.0.0.0/16"
        tags = {
          Name = "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 your AWS account.

  • Check whether the vpc is created in the AWS VPC.

Step 2: Create a public subnet

  • Now create a public subnet named as subnet.tf with CIDR block 10.0.1.0/24 in the VPC with ID aws_vpc.main.id, and tags it with the name "public", you can take reference of vpc resource that has been created before.

      resource "aws_subnet" "public" {
        vpc_id     = aws_vpc.main.id
        cidr_block = "10.0.16.0/20"
        availability_zone = "us-east-1a"
        tags = {
          Name = "public"
        }
      }
    
  • Run terraform apply to create a public subnet in your AWS account.

  • Go to VPC console then go to Subnets. Check Public Subnet is created successfully.

Step 3: Create a private subnet

  • Same as the public subnet, creates a private subnet with CIDR block 10.0.2.0/24 in the VPC with ID aws_vpc.main.id, and tags it with the name "private".

      resource "aws_subnet" "private" {
        vpc_id     = aws_vpc.main.id
        cidr_block = "10.0.32.0/20"
        availability_zone = "us-east-1a"
        tags = {
          Name = "private"
        }
      }
    
  • Now execute the terraform apply the command to create a private subnet.

  • A private Subnet is successfully created using Terraform, you can verify this in the VPC Tab of the Subnet console.

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

  • Create a internetgateway.tf file write the following code which will creates an internet gateway in the VPC with ID aws_vpc.main.id, and tags it with the name "igw".

      resource "aws_internet_gateway" "gw" {
        vpc_id = aws_vpc.main.id
        tags = {
          Name = "internet-getway"
        }
      }
    
  • Execute the terraform apply command for the creation of Internet Gateway.

  • Go to VPC then go to Internet gateways, and check whether a new Internet gateway is created with the name 'internet-getway'.

  • VPC is attached to the internet gateway.

Step 5: Create a Route Table

  • Now create a route table named routetable.tf for use with a public subnet specified by the subnet_id attribute.

      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
      }
    
  • In Route tables, a new route table is successfully created using terraform apply

    command, Now route table routes with an internet gateway.

  • The route table is associated with a public subnet using Terraform.

Step 6: Create a Security Group

  • To connect our EC2 instance, create a securitygroup.tf file where use the aws_security_group block creates a new security group that allows inbound traffic on ports 22 (SSH) and 80 (HTTP) from any source (0.0.0.0/0).

resource "aws_security_group" "web_server" {
  name_prefix = "web-server-sg"
  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"]
  }
   ingress { 
     from_port   = 443 
     to_port     = 443 
     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"] 
   }
}

  • A security group is created with SSH(Port 22) and HTTP(Port 80) and HTTPS(Port 443) access.


Step 7: Create an Elastic IP and associate it with the EC2 instance.

  • Create a file named elasticip.tf where the aws_eip block creates a new Elastic IP address and associates it with the instance created in the first block by specifying the instance ID in the instance attribute.

      resource "aws_eip" "eip" {
        instance = aws_instance.web_server.id
    
        tags = {
          Name = "test-eip"
        }
      }
    
  • Elastic IP is successfully created using terraform apply command.

  • Now we can check that our Elastic IP has been created.

Step 8: Create User data to install Apache

  • The user_data attribute specifies the script to run when the instance is launched. This script updates the package manager, installs the Apache web server, creates a basic HTML file, and restarts Apache.

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

Step 9: Launch an EC2 instance in the public subnet

  • Create a new ec2.tf file where add the details of our EC2 instance like AMI ID, instance type, key name, public subnet, security group and User Data to install Apache in our EC2 instance server.

      resource "aws_instance" "example" {
        ami           = "ami-053b0d53c279acc90"
        instance_type = "t2.micro"
        key_name      = "Terraform-Key"
        subnet_id     = aws_subnet.public.id
    
        associate_public_ip_address = true
        security_groups = [
          aws_security_group.web_server.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
           sudo systemctl restart apache2
           sudo chmod 766 /var/www/html/index.html
           sudo echo "<html><body><h1>Welcome to my website.</h1></body></html>" >/var/www/html/index.html    
        EOF
        tags = {
          Name = "Terraform-Infra"
        }
      }
    
  • Run terraform apply to create an EC2 instance in your AWS account named "Terraform-Infra".

  • A New instance is created (Terraform-Infra) using Terraform.

  • Using the Public IPv4 address, open the URL in a browser to verify that the website is hosted successfully.


Thank You,

I want to express my deepest gratitude to each and every one of you who has taken the time to read, engage, and support my journey.

Feel free to reach out to me if any corrections or add-ons are required on blogs. Your feedback is always welcome & appreciated.

~ Abhisek Moharana ๐Ÿ™‚

ย