AWS Infrastructure with Terraform
This Terraform configuration sets up a complete AWS infrastructure including VPC, subnets, security groups, EC2 instances, and IAM roles.
Provider Configuration
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "us-west-2"
}
VPC and Networking
# VPC
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "main-vpc"
}
}
# Public Subnet
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
availability_zone = "us-west-2a"
map_public_ip_on_launch = true
tags = {
Name = "public-subnet"
}
}
# Private Subnet
resource "aws_subnet" "private" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.2.0/24"
availability_zone = "us-west-2b"
tags = {
Name = "private-subnet"
}
}
# Internet Gateway
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
tags = {
Name = "main-igw"
}
}
# Route Table for Public Subnet
resource "aws_route_table" "public" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.main.id
}
tags = {
Name = "public-rt"
}
}
# Route Table Association
resource "aws_route_table_association" "public" {
subnet_id = aws_subnet.public.id
route_table_id = aws_route_table.public.id
}
Security Groups
# Security Group for EC2
resource "aws_security_group" "ec2_sg" {
name = "ec2-security-group"
description = "Security group for EC2 instances"
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"]
}
tags = {
Name = "ec2-security-group"
}
}
IAM Configuration
# IAM Role
resource "aws_iam_role" "ec2_role" {
name = "ec2_role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "ec2.amazonaws.com"
}
}
]
})
}
# IAM Instance Profile
resource "aws_iam_instance_profile" "ec2_profile" {
name = "ec2_profile"
role = aws_iam_role.ec2_role.name
}
# IAM Role Policy
resource "aws_iam_role_policy" "ec2_policy" {
name = "ec2_policy"
role = aws_iam_role.ec2_role.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"s3:GetObject",
"s3:ListBucket"
]
Resource = [
"arn:aws:s3:::*"
]
}
]
})
}
EC2 Instance
# EC2 Instance
resource "aws_instance" "web_server" {
ami = "ami-0735c191cf914754d" # Amazon Linux 2 AMI (adjust for your region)
instance_type = "t2.micro"
subnet_id = aws_subnet.public.id
vpc_security_group_ids = [aws_security_group.ec2_sg.id]
associate_public_ip_address = true
iam_instance_profile = aws_iam_instance_profile.ec2_profile.name
user_data = <<-EOF
#!/bin/bash
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
EOF
tags = {
Name = "web-server"
}
}
Outputs
output "vpc_id" {
value = aws_vpc.main.id
}
output "public_subnet_id" {
value = aws_subnet.public.id
}
output "private_subnet_id" {
value = aws_subnet.private.id
}
output "instance_public_ip" {
value = aws_instance.web_server.public_ip
}
Usage
- Initialize Terraform:
terraform init
- Review the planned changes:
terraform plan
- Apply the configuration:
terraform apply
- To destroy the infrastructure:
terraform destroy