Day 66 - Building Amazon EC2 using Terraform

Day 66 - Building Amazon EC2 using Terraform

In the previous blogs on Terraform, we 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.

Get ready to build a VPC, Subnet, Internet Gateway, and even host a full-fledged website on an 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

1. Create a VPC (Virtual Private Cloud)

Step 1: Create a terraform.tf, where we have to pass on AWS provider details.

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

Step 2: Add a provider.tf and add details about AWS Region that you are using.

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

Step 3: Create a vpc.tf file to add the following details to create a VPC.

resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"
  tags = {
    Name = "main"
  }
}

Step 4: Run the terraform init command to initialize the working directory and download the required providers.

Step 5: Once you initialize all the plugins required for AWS, now execute the terraform plan which will create an execution plan by analyzing the changes required to achieve the desired state of your infrastructure.

Step 6: Finally, use the command terraform apply it will apply the changes to create or update resources as needed.

Step 7: Check whether the VPC is created in the AWS VPC.

2. Create a Public Subnet

Step 1: Now, Create a subnet.tf file to create a public subnet with the following details:-
1. cidr_block: 10.0.1.0/24
2. vpc_id: aws_vpc.main.id
3. availability_zone = us-east-1a
3. tag 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"
  }
}

Step 2: Run the terraform init command to initialize the working directory and download the required providers.

Step 3: Run terraform plan which will create an execution plan by analyzing the changes required to achieve the desired state of your infrastructure.

Step 4: Run terraform apply to create a public subnet in your AWS account.

Step 5: Go to VPC console then go to Subnets. Check Public Subnet is created successfully.

3. Create a private subnet

Step 1: Same as the public subnet, Creates a private subnet with following details in subnet.tf file: -
1. cidr_block: 10.0.2.0/24
2. vpc_id: aws_vpc.main.id
3. availability_zone: us-east-1a
4. tag 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"
  }
}

Step 2: Run the terraform init command to initialize the working directory and download the required providers.

Step 3: Run terraform plan which will create an execution plan by analyzing the changes required to achieve the desired state of your infrastructure.

Step 4: Run terraform apply to create a private subnet in your AWS account.

Step 5: Go to VPC console then go to Subnets. Check Private Subnet is created successfully.

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

Step 1: Create a internetgateway.tf file write the following code which will creates an internet gateway in the VPC: -
1. vpc_id: aws_vpc.main.id
2. tag it with the name: internet-gateway

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

Step 2: Run the terraform init command to initialize the working directory and download the required providers.

Step 3: Run terraform plan which will create an execution plan by analyzing the changes required to achieve the desired state of your infrastructure.

Step 4: Run the terraform apply command for the creation of Internet Gateway.

Step 5: Go to VPC then go to Internet gateways, and check whether a new Internet gateway is created with the name ‘internet-gateway’.

You can see a VPC is attached to the internet gateway.

5. Create a Route Table

Step 1: Now Create a routetable.tf file for creating a route table, use it 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
}

Step 2: Run the terraform init command to initialize the working directory and download the required providers.

Step 3: Run terraform plan which will create an execution plan by analyzing the changes required to achieve the desired state of your infrastructure.

Step 4: Run the terraform apply, you can see in Route tables: a new route table is successfully created, i.e., route table routes with an internet gateway.

Step 5: The route table is associated with a public subnet using Terraform.

6. Create a Security Group

Step 1: To connect our EC2 instance, create a securitygroup.tf file where use the aws_security_group block to create 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"] 
  }
}

Step 2: Run the terraform init command to initialize the working directory and download the required providers.

Step 3: Run terraform plan which will create an execution plan by analyzing the changes required to achieve the desired state of your infrastructure.

Step 4: Run the terraform apply, to create a new security group.

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

7. Create User data to install Apache

Step 1: 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

8. Launch an EC2 instance in the public subnet

Step 1: 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 add User Data to install Apache in our EC2 instance server.

resource "aws_instance" "example" {
  ami = "ami-0c7217cdde317cfec"
  instance_type = "t2.micro"
  key_name = "terraform"
  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"
  }
}

Step 2: Run the terraform init command to initialize the working directory and download the required providers.

Step 3: Run terraform plan which will create an execution plan by analyzing the changes required to achieve the desired state of your infrastructure.

Step 4: Run the terraform apply, to create an EC2 instance in your AWS account named "Terraform-Infra".

Step 5: A New instance is created (Terraform-Infra) using Terraform.

9. Create an Elastic IP and associate it with the EC2 instance.

Step 1: 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.example.id

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

Step 2: Run the terraform init command to initialize the working directory and download the required providers.

Step 3: Run terraform plan which will create an execution plan by analyzing the changes required to achieve the desired state of your infrastructure.

Step 4: Run the terraform apply, to create Elastic IP.

Step 5: Now we can check that our Elastic IP has been created.

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

Step 7: Once you are done with the newly created instance we can use terraform destroy command which will delete the complete infrastructure.

Conclusion

Implementing AWS EC2 infrastructure using Terraform offers significant advantages in terms of automation, scalability, and consistency. Terraform simplifies the provisioning and management of EC2 instances by allowing infrastructure as code (IaC) practices, enabling teams to define and version-control their infrastructure configurations. This approach enhances reproducibility, reduces manual errors, and facilitates collaboration among team members.

Hope you find it helpful🤞 So I encourage you to try this on your own and let me know in the comment section👇 about your learning experience.✨

👆The information presented above is based on my interpretation. Suggestions are always welcome.😊

~Smriti Sharma✌