As Infrastructure as Code (IaC) takes center stage in the world of DevOps, Terraform has emerged as a frontrunner. For DevOps engineers keen on automating and codifying infrastructure components, mastering Terraform is imperative. If you're preparing for an interview, or just seeking to test your Terraform chops, this guide has you covered.
1) Create a VPC (Virtual Private Cloud) with CIDR block 10.0.0.0/16
Below is a step-by-step guide to set up a VPC with the specified CIDR block using Terraform:
Prerequisites:
Ensure you have Terraform installed on your local machine.
Have an AWS account and set up AWS CLI, ensure you have your AWS access keys configured in your machine.
Initialize a new directory for your Terraform configuration.
Steps:
Set Up Your Terraform Configuration Directory:
mkdir terraform cd terraform
Define AWS Provider and VPC Resource:
Create a new file named
main.tf
and add the following:#provider terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 5.0" } } } provider "aws" { region = "us-east-1" # You can change this to your preferred region } #Create VPC resource "aws_vpc" "my-vpc" { cidr_block = "10.0.0.0/16" tags = { Name = "my-vpc-terraform" } }
Initialize and Apply:
Run the following commands to download the necessary providers and apply your Terraform configuration:
terraform init #initialize terraform terraform validate #Validate your code to check syntax error if any terraform plan #Review what will get created with your configuration terraform apply #Create your infrastructure as per configuration
Review and Confirm:
Terraform will show you the changes it plans to make. If everything looks good, type
yes
when prompted to create the VPC.Check-in AWS Console:
After applying the configuration, you can log in to the AWS Management Console and navigate to the VPC dashboard to see your newly created VPC.
By using Terraform, you've programmatically created a VPC in AWS. This approach is scalable, repeatable, and can be version-controlled, showcasing the power of Infrastructure as Code. Ensure to keep exploring further functionalities like adding subnets, security groups, and more to your VPC using Terraform.
2) Create a public subnet with CIDR block 10.0.1.0/24 in the above VPC.
I have destroyed the previous configuration and now creating VPC and public subnet in one go!
Add Public Subnet Configuration:
In the same
main.tf
file, add the following configuration to create a public subnet:#provider terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 5.0" } } } provider "aws" { region = "us-east-1" # You can change this to your preferred region } #Create VPC resource "aws_vpc" "my-vpc" { cidr_block = "10.0.0.0/16" enable_dns_support = "true" #gives you an internal domain name enable_dns_hostnames = "true" #gives you an internal host name tags = { Name = "my-vpc" } } resource "aws_subnet" "my-public-subnet" { vpc_id = "${aws_vpc.my-vpc.id}" #refrence to VPC created already cidr_block = "10.0.1.0/24" map_public_ip_on_launch = "true" # This makes the subnet "public" availability_zone = "us-east-1a" tags = { Name = "my-public-subnet" } }
Here,
vpc_id
points to the VPC we created earlier. Themap_public_ip_on_launch = true
attribute ensures that any EC2 instance launched in this subnet will automatically receive a public IP.Apply the Configuration:
After adding the subnet configuration, apply your Terraform configuration:
terraform apply
Review and Confirm:
Terraform will provide a summary of the changes it plans to make. Ensure the subnet creation is listed, then type
yes
when prompted to create the subnet.Check in AWS Console:
Once the configuration is applied, you can log into the AWS Management Console, navigate to the VPC dashboard, and check under Subnets to see your newly created public subnet within your VPC.
Note: To make the subnet truly public, you'd typically need to configure a route in the subnet's route table pointing to the VPC's internet gateway. This example keeps it simple for clarity, but in a real-world scenario, ensure to have all the necessary configurations in place for network traffic to flow in and out of your public subnet.
3) Create a private subnet with CIDR block 10.0.2.0/24 in the above VPC.
Building upon the previous example where you've created a VPC, you can easily add a private subnet to the VPC using Terraform.
Steps:
Extend Your Terraform Configuration:
In your
main.tf
file, add the following configuration to create a private subnet within the VPC you previously set up:resource "aws_subnet" "my-private-subnet" { vpc_id = "${aws_vpc.my-vpc.id}" #refrence to VPC created already cidr_block = "10.0.2.0/24" map_public_ip_on_launch = "false" # This makes the subnet "private" availability_zone = "us-east-1a" tags = { Name = "my-private-subnet" } }
Ensure the
availability_zone
matches the region you've specified in the AWS provider block. You can adjust it to any valid availability zone within your selected region.Apply Your Terraform Configuration:
Execute the following commands:
terraform plan # This allows you to preview the changes terraform apply
After reviewing the changes Terraform plans to make, type
yes
when prompted to apply and create the private subnet.Review in AWS Console:
Once you've applied the configuration, you can head over to the AWS Management Console. In the VPC dashboard, under "Subnets", you should see your newly created private subnet within your VPC.
With Terraform, you've efficiently expanded your AWS infrastructure by adding a private subnet to your VPC. This approach showcases the modularity and extensibility of Infrastructure as Code. You can further explore adding more resources like route tables, internet gateways, or even instances within your subnet using Terraform.
4) Create an Internet Gateway (IGW) and attach it to the VPC.
Continuing from the previous setup where we created a VPC, let's add an Internet Gateway (IGW) and associate it with that VPC using Terraform.
Modify the Existing Terraform Configuration:
Update the
main.tf
to include the Internet Gateway and its association with the VPC:resource "aws_internet_gateway" "my-igw" { vpc_id = "${aws_vpc.my-vpc.id}" #refrence to VPC created already tags = { Name = "my-igw" } }
In this configuration:
The
aws_internet_gateway
resource creates the Internet Gateway.The
vpc_id
attribute inaws_internet_gateway
refers to the ID of the previously created VPC, establishing the link between the VPC and the IGW.
Apply the Configuration:
Run the following commands:
terraform plan terraform apply
After reviewing the planned changes, confirm with
yes
.\Verify in AWS Console:
Once the
apply
completes, you can log in to your AWS Management Console, navigate to the VPC dashboard, and you should see the Internet Gateway associated with your VPC.
You've now extended your Terraform configuration to include an Internet Gateway and associated it with your VPC. This foundational knowledge sets the stage for you to further expand, perhaps by adding subnets, route tables, and more, to build out a complete network infrastructure on AWS using Terraform.
5) 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.
creating a route table for a public subnet and associating it with an Internet Gateway is a common practice for setting up AWS VPCs with Terraform. Let's take this step-by-step:
Assuming you already have a VPC and an Internet Gateway (aws_internet_gateway
) created, let's set up a public subnet, create its associated route table, and add a route to the Internet Gateway:
Define AWS Provider:
VPC and Internet Gateway:
Public Subnet:
Route Table for Public Subnet:
resource "aws_route_table" "public-route-table" { vpc_id = "${aws_vpc.my-vpc.id}" #refrence to VPC created already route { cidr_block = "0.0.0.0/0" gateway_id = "${aws_internet_gateway.my-igw.id}" } tags = { Name = "public-route-table" } }
Associate the Route Table with the Public Subnet:
resource "aws_route_table_association" "public_subnet_association" { subnet_id = aws_subnet.my_public_subnet.id route_table_id = aws_route_table.public_route_table.id }
Initialize, Plan, and Apply:
Run the following commands:
terraform plan terraform apply
Review and Confirm: Terraform will show you the changes it plans to make. If everything looks good, type
yes
when prompted to create the resources.
After these steps, you will have a public subnet in your VPC that's associated with a route table. This route table will have a route to the Internet Gateway, allowing resources in the subnet to access the internet. Make sure you have appropriate security groups in place before deploying any services in this subnet.
Launch an EC2 instance in the public subnet with the following details:
**AMI: ami-**053b0d53c279acc90
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.
Open the website URL in a browser to verify that the website is hosted successfully.
To launch an EC2 instance in the public subnet with the specified details using Terraform, follow these steps:
Prerequisites:
You need to have already set up a VPC, Internet Gateway, Public Subnet, and a Public Route Table as mentioned in previous discussions.
Terraform must be installed and initialized.
AWS CLI or AWS credentials configured properly.
Steps:
Define AWS Provider
Create a Security Group for SSH Access:
resource "aws_security_group" "allow-ssh" {
name = "allow-ssh"
description = "Allow SSH inbound traffic"
vpc_id = aws_vpc.my-vpc.id
ingress {
description = "Access Website"
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"]
}
}
- Launch EC2 instance:
resource "aws_instance" "my-instance" {
ami = "ami-053b0d53c279acc90"
instance_type = "t2.micro"
subnet_id = "${aws_subnet.my-public-subnet.id}"
security_groups = [
aws_security_group.allow-ssh.name
]
#Add UserData to install apache server to host your website
user_data = <<-EOF
#!/bin/bash
sudo apt-get update -y
sudo apt-get install -y apache2
sudo systemctl start apache2
sudo systemctl enable apache2
echo "<header> <h1> Hello World! Welcome to <a href="https://kshitijaa.hashnode.dev/" target="_blank"> Kshitija-Bartakke-Malwade-Blogs! </h1> </header>" > var/www/html/index.html
EOF
tags = {
Name = "my-instance"
}
}
- Allocate and Associate an Elastic IP:
resource "aws_eip" "my-eip" {
instance = "${aws_instance.my-instance.id}
tags = {
Name = "my-eip"
}
}
- Initialize, Plan, and Apply:
terraform init
terraform plan
terraform apply
- Review and Confirm: Terraform will display the planned changes. If all looks good, type
yes
to proceed.
Once the EC2 instance is launched, grab the Elastic IP from the AWS Console. Open a browser and enter the IP address with port 80 <public_ip_affress:80
\>.
You should see the message: Welcome to Kshitija-Bartakke-Malwade-Blogs!
Note: Always ensure to clean up resources once you're done experimenting to avoid unnecessary AWS charges. Use terraform destroy
to delete all the resources you've created.
Done! Now your all created resources got destroyed/deleted!