This article is useful for cloud enthusiasts, DevOps engineers, and developers. Let's outline a scenario-based guide to demonstrate how to use Terraform for setting up a basic AWS infrastructure.
Introduction
Infrastructure as Code (IaC) is a key practice in modern DevOps that allows teams to manage and provision infrastructure using code. Terraform, an open-source tool developed by HashiCorp, is widely used for this purpose due to its flexibility and support for multiple cloud providers, including AWS. In this guide, I will walk you through a real-world scenario of setting up AWS infrastructure using Terraform.
Scenario Overview
Imagine you are tasked with setting up a new environment on AWS for a web application. The requirements are:
VPC (Virtual Private Cloud): To isolate our resources.
Subnets: Public and private subnets to organize resources.
EC2 Instances: To run the web servers.
Security Groups: To control the traffic to and from the EC2 instances.
RDS Instance: For the backend database.
Set Up AWS Credentials Using the AWS CLI
The most common way to configure AWS credentials is by using the AWS CLI. Here’s how you can do it:
Install the AWS CLI: If you haven't already installed it, you can follow the AWS CLI installation guide.
Configure AWS CLI: Run the following command to configure the AWS CLI with your credentials:
aws configure
You will be prompted to enter your AWS Access Key ID, Secret Access Key, default region name, and default output format. These credentials will be saved in the
~/.aws/credentials
file on Unix/Linux/macOS or%USERPROFILE%\.aws\credentials
on Windows.
2. Set AWS Credentials in Environment Variables
Terraform also supports using environment variables for AWS credentials. You can set them like this:
Linux/macOS:
export AWS_ACCESS_KEY_ID="your_access_key" export AWS_SECRET_ACCESS_KEY="your_secret_key" export AWS_DEFAULT_REGION="us-east-1"
Windows (Command Prompt):
set AWS_ACCESS_KEY_ID=your_access_key set AWS_SECRET_ACCESS_KEY=your_secret_key set AWS_DEFAULT_REGION=us-east-1
Replace "your_access_key"
and "your_secret_key"
with your actual AWS access key ID and secret access key.
3. Using a Shared Credentials File
If you have multiple AWS profiles set up in a shared credentials file (e.g., ~/.aws/credentials
), you can specify which profile Terraform should use by adding the profile
argument to the AWS provider block:
provider "aws" {
region = "us-east-1"
profile = "your_profile_name"
}
Replace "your_profile_name"
with the name of the profile you want to use.
Prerequisites
Basic understanding of AWS services (VPC, EC2, RDS, etc.).
Terraform installed.
AWS CLI installed and configured with your credentials.
An AWS account with permissions to create the necessary resources.
Windows user should install (Git Bash and VS Code) to follow along
Step 1: Set Up Your Terraform Environment
First, create a new directory for your Terraform configuration files, by running the following commands. Please note I will be using Git Bash and VS Code in this project.
mkdir terraform-aws-setup
cd terraform-aws-setup
Step 2: Define Your AWS Provider
Create a file named main.tf
to define the AWS provider. This tells Terraform to use AWS as the target for resource provisioning.
Copy and paste this code below in your main.tf file, don't forget to save.
# main.tf
provider "aws" {
region = "us-east-1"
}
Step 3: Create a VPC
In the same main.tf
file, add the configuration to create a VPC.
# main.tf
resource "aws_vpc" "main_vpc" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "main_vpc"
}
}
Step 4: Create Subnets
Next, define public and private subnets within the VPC.
# main.tf
resource "aws_subnet" "public_subnet" {
vpc_id = aws_vpc.main_vpc.id
cidr_block = "10.0.1.0/24"
availability_zone = "us-east-1a"
map_public_ip_on_launch = true
tags = {
Name = "public_subnet"
}
}
resource "aws_subnet" "private_subnet" {
vpc_id = aws_vpc.main_vpc.id
cidr_block = "10.0.2.0/24"
availability_zone = "us-east-1b"
tags = {
Name = "private_subnet"
}
}
Step 5: Set Up Security Groups
Create a security group to allow HTTP and SSH access to the EC2 instances.
# main.tf
resource "aws_security_group" "web_sg" {
vpc_id = aws_vpc.main_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 = "web_sg"
}
}
Step 6: Launch EC2 Instances
Define the EC2 instances in the main.tf
file.
# web_server
resource "aws_instance" "web_server" {
ami = "ami-0c94855ba95c71c99" # Replace with your actual AMI ID
instance_type = "t2.micro"
subnet_id = aws_subnet.public_subnet.id # Ensure this is a valid subnet ID
vpc_security_group_ids = [aws_security_group.web_sg.id] # Use security group IDs
# Other necessary configurations
tags = {
Name = "web_server"
}
}
Step 7: Set Up RDS Instance
Add the configuration to create an RDS instance for the database.
# web_app_db
resource "aws_db_instance" "web_app_db" {
allocated_storage = 20
engine = "mysql"
instance_class = "db.t3.micro"
db_name = "mydb"
username = "admin"
password = "password"
parameter_group_name = "default.mysql8.0"
skip_final_snapshot = true
vpc_security_group_ids = [aws_security_group.web_sg.id]
db_subnet_group_name = aws_db_subnet_group.db_subnet_group.name
}
resource "aws_db_subnet_group" "db_subnet_group" {
name = "my-db-subnet-group"
subnet_ids = [
aws_subnet.private_subnet.id, # Subnet in AZ1
aws_subnet.public_subnet.id # Subnet in AZ2
]
tags = {
Name = "db_subnet_group"
}
}
Save your main.tf file
Step 8: Initialize Terraform
Run the "terraform init" command to initialize your Terraform workspace. This will download the necessary provider plugins.
terraform init
Step 9: Plan and Apply
Generate an execution plan with:
terraform plan
Apply the changes by running this command, "terraform apply":
terraform apply
Confirm the action, and Terraform will proceed to create your AWS infrastructure as defined.
Step 10: Verify the Setup
After the Terraform script completes, log in to the AWS Management Console and check:
The VPC and subnets are created.
Click the "VPC ID" to see the created subnet, then scroll down to the "Subnet" section.
EC2 instance is running with the correct security group settings. Search and select "EC2" in your AWS console.
Click on the Instance ID as shown above to verify the security group. Scroll down and select the "Security" tab.
RDS instance is up and connected to the private subnet. Search and select "RDS" in your AWS console. Click the "DB Instances" link to view details.
Click "DB identifier" to view more details as shown below.
Scroll down to "Connectivity & Security" to see the following information:
Step 11 : Clean up
Run this command "terraform destroy" and type "yes" when you are prompted to delete all the resources you created with "main.tf"
You should get a similar message like this:
Final Thought
Using Terraform to manage AWS infrastructure allows for consistent and repeatable deployments. By following this guide, you have automated the process of creating a VPC, subnets, EC2 instances, security groups, and an RDS instance, all with a few lines of code. This approach reduces the risk of manual errors and enhances collaboration through version-controlled infrastructure definitions.
Further Learning
Explore Terraform modules to reuse code.
Check out AWS Best Practices for designing robust infrastructure.
Try integrating Terraform with CI/CD pipelines for automated deployments.
Thanks
:Valentine Stephen