Day-24-Aws
Automating AWS Infrastructure with Terraform: A Comprehensive Guide
TLDR: This blog post provides a detailed walkthrough of using Terraform to automate the creation of AWS infrastructure, including VPCs, subnets, EC2 instances, and load balancers. It emphasizes the importance of understanding AWS concepts and Terraform syntax, and offers practical tips for beginners.
In this blog post, we will explore how to use Terraform to automate the creation of infrastructure on AWS. This guide is based on Day 24 of the AWS DevOps Zero to Hero series, where we dive into a real-time Terraform project. If you have previously created infrastructure using the AWS console or CloudFormation templates, transitioning to Terraform will be straightforward, especially if you have a solid understanding of AWS fundamentals.
What is Terraform?
Terraform is an Infrastructure as Code (IaC) tool that allows you to define and provision data center infrastructure using a declarative configuration language. It enables you to manage your infrastructure through code, making it easier to automate and replicate environments.
Getting Started with Terraform
Before we begin, ensure you have the following prerequisites:
An AWS account
Terraform installed on your machine
Setting Up AWS Credentials
To use Terraform with AWS, you need to configure your AWS credentials. This involves creating an IAM user with the necessary permissions and generating access keys. Here’s how:
Log in to your AWS Management Console.
Navigate to the IAM service and create a new user with programmatic access.
Attach the necessary policies (e.g., AdministratorAccess) to the user.
Generate access keys and store them securely.
Once you have your access keys, configure them in your terminal using the AWS CLI:
aws configure
Initializing Terraform
Create a new directory for your Terraform project and navigate into it. Initialize Terraform by running:
tf init
This command prepares your working directory for other Terraform commands.
Defining Your Infrastructure
Provider Configuration
The first step in your Terraform configuration is to define the provider. Since we are using AWS, add the following to your main.tf
file:
provider "aws" {
region = "us-east-1"
}
Creating a VPC
Next, we will create a Virtual Private Cloud (VPC). Add the following resource definition:
resource "aws_vpc" "my_vpc" {
cidr_block = "10.0.0.0/16"
enable_dns_support = true
enable_dns_hostnames = true
tags = {
Name = "MyVPC"
}
}
Creating Subnets
We will create two subnets within the VPC:
resource "aws_subnet" "subnet1" {
vpc_id = aws_vpc.my_vpc.id
cidr_block = "10.0.1.0/24"
availability_zone = "us-east-1a"
map_public_ip_on_launch = true
tags = {
Name = "Subnet1"
}
}
resource "aws_subnet" "subnet2" {
vpc_id = aws_vpc.my_vpc.id
cidr_block = "10.0.2.0/24"
availability_zone = "us-east-1b"
map_public_ip_on_launch = true
tags = {
Name = "Subnet2"
}
}
Creating an Internet Gateway
To allow internet access to our VPC, we need to create an Internet Gateway:
resource "aws_internet_gateway" "my_igw" {
vpc_id = aws_vpc.my_vpc.id
tags = {
Name = "MyIGW"
}
}
Creating a Route Table
Next, we will create a route table and associate it with our subnets:
resource "aws_route_table" "my_route_table" {
vpc_id = aws_vpc.my_vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.my_igw.id
}
tags = {
Name = "MyRouteTable"
}
}
resource "aws_route_table_association" "subnet1_association" {
subnet_id = aws_subnet.subnet1.id
route_table_id = aws_route_table.my_route_table.id
}
resource "aws_route_table_association" "subnet2_association" {
subnet_id = aws_subnet.subnet2.id
route_table_id = aws_route_table.my_route_table.id
}
Creating Security Groups
Security groups act as virtual firewalls for your instances. Define a security group for your EC2 instances:
resource "aws_security_group" "web_sg" {
vpc_id = aws_vpc.my_vpc.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
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 = "WebSG"
}
}
Creating EC2 Instances
Now, we will create two EC2 instances:
resource "aws_instance" "web_server1" {
ami = "ami-0c55b159cbfafe1f0" # Replace with your AMI ID
instance_type = "t2.micro"
subnet_id = aws_subnet.subnet1.id
security_groups = [aws_security_group.web_sg.name]
user_data = <<-EOF
#!/bin/bash
echo "Welcome to Abhishek's channel" > index.html
nohup python -m SimpleHTTPServer 80 &
EOF
}
resource "aws_instance" "web_server2" {
ami = "ami-0c55b159cbfafe1f0" # Replace with your AMI ID
instance_type = "t2.micro"
subnet_id = aws_subnet.subnet2.id
security_groups = [aws_security_group.web_sg.name]
user_data = <<-EOF
#!/bin/bash
echo "Welcome to Cloud Champ" > index.html
nohup python -m SimpleHTTPServer 80 &
EOF
}
Creating a Load Balancer
Finally, we will create an Application Load Balancer to distribute traffic between the two EC2 instances:
resource "aws_lb" "my_lb" {
name = "my-load-balancer"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.web_sg.id]
subnets = [aws_subnet.subnet1.id, aws_subnet.subnet2.id]
}
resource "aws_lb_target_group" "my_tg" {
name = "my-target-group"
port = 80
protocol = "HTTP"
vpc_id = aws_vpc.my_vpc.id
}
resource "aws_lb_listener" "front_end" {
load_balancer_arn = aws_lb.my_lb.arn
port = "80"
protocol = "HTTP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.my_tg.arn
}
}
Applying Your Configuration
After defining all the resources, run the following commands to apply your configuration:
tf plan
This command shows you what will be created. If everything looks good, run:
tf apply
This command will create all the resources defined in your configuration.
Conclusion
In this blog post, we covered how to use Terraform to automate the creation of AWS infrastructure, including VPCs, subnets, EC2 instances, and load balancers. Understanding the underlying AWS concepts is crucial for effectively using Terraform. With practice, you will find that Terraform simplifies the management of your infrastructure, making it easier to deploy and maintain applications in the cloud.
Don't forget to experiment with the code and try creating your own configurations. Happy coding!