πWorkflow
1οΈβ£ π Structure
2οΈβ£ π± Root module
3οΈβ£ π» EC2 module
4οΈβ£ π‘οΈ Security Group module
πLink to project
1οΈβ£ π Structure
βββ dev.tfvars
βββ main.tf
βββ provider.tf
βββ modules
β βββ ec2
β β βββ install_docker.sh
β β βββ main.tf
β β βββ output.tf
β β βββ variables.tf
β βββ security_group
β βββ igw.tf
β βββ output.tf
β βββ rt.tf
β βββ sg.tf
β βββ subnet.tf
β βββ vpc.tf
Why it's important to split terraform into modules?
- π Code reuse
- π Improved scalability
- 𧩠Modularity and abstraction
- π₯ Clear separation of responsibilities.
- π οΈ Simplified maintenance
- π Improved readability
- π Efficient version control
2οΈβ£ π± Root module
# main.tf
variable "ami" {}
variable "instance_type" {}
variable "key_name" {}
#Replace the resource with a module
module "ec2_instance" {
#References file location of new module
source = "./modules/ec2"
ami = var.ami
instance_type = var.instance_type
key_name = var.key_name
subnet_id = module.security_group.subnet_id # Call the name of variable output
sg_id = module.security_group.sg_id
}
# Specify the name for the security group
module "security_group" {
source = "./modules/security_group"
}
#provider.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.52.0"
}
}
}
provider "aws" {
region = "us-east-2"
}
# dev.tfvars
ami = "ami-0b4624933067d393a" # each ami is region specific
instance_type = "t2.micro"
key_name = "ec2_key"
3οΈβ£ π» EC2 module
# modules/ec2/main.tf
variable "ami" {}
variable "instance_type" {}
variable "key_name" {}
resource "aws_instance" "ec2" {
ami = var.ami
instance_type = var.instance_type
key_name = var.key_name
vpc_security_group_ids = [var.sg_id]
subnet_id = var.subnet_id
user_data = "${file("./modules/ec2/install_docker.sh")}"
tags = {
Name = "traefik-demo"
}
}
# modules/ec2/variables.tf
variable "sg_id" {
description = "Security Group ID"
type = string
}
variable "subnet_id" {
description = "Subnet ID"
type = string
}
π Key points.
The EC2 module requires two essential fields:
- π‘οΈ Security Group ID.
- π Subnet ID
# modules/ec2/output.tf
output "instance_id" {
value = aws_instance.ec2.id
}
output "public_ip" {
value = aws_instance.ec2.public_ip
}
#!/bin/bash
# Update and install Docker
sudo yum update -y
sudo yum install -y jq docker
# Enable Docker service
sudo service docker start
sudo usermod -a -G docker ec2-user
# Get the latest version of Docker Compose
DOCKER_COMPOSE_VERSION=$(curl -s https://api.github.com/repos/docker/compose/releases/latest | jq -r .tag_name)
# Install Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
4οΈβ£ π‘οΈ Security Group module
vpc.tf
#modules/security_group/vpc.tf
resource "aws_vpc" "traefik_vpc" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "main-vpc"
}
}
#modules/security_group/subnet.tf
resource "aws_subnet" "traefik_subnet" {
vpc_id = aws_vpc.traefik_vpc.id
cidr_block = "10.0.1.0/24"
map_public_ip_on_launch = true
tags = {
Name = "example-subnet"
}
}
#modules/security_group/sg.tf
resource "aws_security_group" "traefik_sg" {
name = "traefik-security-group"
vpc_id = aws_vpc.traefik_vpc.id
description = "Allow HTTP and HTTPS traffic"
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"]
}
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"] # Allow ssh from internet
}
egress {
from_port = 0
to_port = 0
protocol = "-1" # Allow all traffic
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "traefik_sg"
}
}
#modules/security_group/rt.tf
resource "aws_route_table" "traefik_route_table" {
vpc_id = aws_vpc.traefik_vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.traefik_igw.id
}
tags = {
Name = "route_table"
}
}
resource "aws_route_table_association" "a" {
subnet_id = aws_subnet.traefik_subnet.id
route_table_id = aws_route_table.traefik_route_table.id
}
#modules/security_group/igw.tf
resource "aws_internet_gateway" "traefik_igw" {
vpc_id = aws_vpc.traefik_vpc.id
tags = {
Name = "traefik_IGW"
}
}
#modules/security_group/output.tf
output "subnet_id" {
value = aws_subnet.traefik_subnet.id
}
output "sg_id" {
value = aws_security_group.traefik_sg.id
}
ποΈ Terraform deploy
terraform init
terraform validate --var-file=dev.tfvars
terraform plan --var-file=dev.tfvars
terraform apply --var-file=dev.tfvars -auto-approve
Top comments (0)