Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .github/workflows/infrastructure_deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Deploy Infrastructure

on:
workflow_dispatch:

env:
TF_WORKING_DIR: 'Devops/terraform'

jobs:
deploy:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Terraform
uses: hashicorp/setup-terraform@v3

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ vars.AWS_REGION }}

- name: Terraform Init
working-directory: ${{ env.TF_WORKING_DIR }}
run: terraform init

- name: Terraform Validate
working-directory: ${{ env.TF_WORKING_DIR }}
run: terraform validate

- name: Terraform Plan
working-directory: ${{ env.TF_WORKING_DIR }}
run: terraform plan -var="aws_region=${{ vars.AWS_REGION }}" -var="backend_port=${{ vars.BACKEND_PORT || 8000 }}"

- name: Terraform Apply
working-directory: ${{ env.TF_WORKING_DIR }}
run: terraform apply -auto-approve
env:
TF_VAR_aws_region: ${{ vars.AWS_REGION }}
TF_VAR_backend_instance_count: ${{ vars.BACKEND_INSTANCE_COUNT || 2 }}
TF_VAR_ssh_access_cidr: ${{ vars.SSH_ACCESS_CIDR || '0.0.0.0/0' }}
TF_VAR_backend_port: ${{ vars.BACKEND_PORT || 8000 }}
102 changes: 102 additions & 0 deletions .github/workflows/infrastructure_destroy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
name: Destroy Infrastructure

on:
workflow_dispatch:
inputs:
confirm_destroy:
description: 'Type "destroy" to confirm'
required: true
default: 'cancel'

jobs:
destroy:
if: inputs.confirm_destroy == 'destroy'
runs-on: ubuntu-latest

steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ vars.AWS_REGION }}

- name: Destroy Instances
run: |
# Terminate all instances with Elegance-* name tag
INSTANCE_IDS=$(aws ec2 describe-instances \
--filters "Name=tag:Name,Values=Elegance-*" \
--query "Reservations[].Instances[].InstanceId" \
--output text)

if [ -n "$INSTANCE_IDS" ]; then
echo "Terminating instances: $INSTANCE_IDS"
aws ec2 terminate-instances --instance-ids $INSTANCE_IDS

# Wait for instances to terminate
echo "Waiting for instances to terminate..."
aws ec2 wait instance-terminated --instance-ids $INSTANCE_IDS
else
echo "No instances found to terminate"
fi

- name: Destroy VPC Components
run: |
# Get VPC ID
VPC_ID=$(aws ec2 describe-vpcs --filters "Name=tag:Name,Values=Elegance-VPC" --query "Vpcs[0].VpcId" --output text)

if [ -z "$VPC_ID" ] || [ "$VPC_ID" == "None" ]; then
echo "No VPC found to delete"
exit 0
fi

echo "Processing VPC: $VPC_ID"

# Delete Internet Gateway if exists
IGW_ID=$(aws ec2 describe-internet-gateways \
--filters "Name=attachment.vpc-id,Values=$VPC_ID" \
--query "InternetGateways[0].InternetGatewayId" \
--output text)

if [ -n "$IGW_ID" ] && [ "$IGW_ID" != "None" ]; then
echo "Detaching and deleting IGW: $IGW_ID"
aws ec2 detach-internet-gateway --internet-gateway-id $IGW_ID --vpc-id $VPC_ID || true
aws ec2 delete-internet-gateway --internet-gateway-id $IGW_ID || true
else
echo "No IGW found to delete"
fi

# Delete Subnets
SUBNET_IDS=$(aws ec2 describe-subnets \
--filters "Name=vpc-id,Values=$VPC_ID" \
--query "Subnets[].SubnetId" \
--output text)

if [ -n "$SUBNET_IDS" ]; then
echo "Deleting subnets: $SUBNET_IDS"
for SUBNET_ID in $SUBNET_IDS; do
aws ec2 delete-subnet --subnet-id $SUBNET_ID || true
done
else
echo "No subnets found to delete"
fi

# Delete Security Groups (except default)
SG_IDS=$(aws ec2 describe-security-groups \
--filters "Name=vpc-id,Values=$VPC_ID" \
--query "SecurityGroups[?GroupName!='default'].GroupId" \
--output text)

if [ -n "$SG_IDS" ]; then
echo "Deleting security groups: $SG_IDS"
for SG_ID in $SG_IDS; do
aws ec2 delete-security-group --group-id $SG_ID || true
done
else
echo "No security groups found to delete"
fi

# Finally delete VPC
echo "Deleting VPC: $VPC_ID"
aws ec2 delete-vpc --vpc-id $VPC_ID || true
echo "VPC deletion initiated"
124 changes: 124 additions & 0 deletions Devops/terraform/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
provider "aws" {
region = var.aws_region
}

data "aws_ami" "ubuntu" {
most_recent = true
owners = ["099720109477"] # Canonical

filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"] # LTS release
}
}

resource "aws_vpc" "elegance_vpc" {
cidr_block = var.vpc_cidr
enable_dns_support = true
enable_dns_hostnames = true

tags = {
Name = "Elegance-VPC"
}
}

resource "aws_subnet" "elegance_public_subnet" {
vpc_id = aws_vpc.elegance_vpc.id
cidr_block = var.public_subnet_cidr
availability_zone = "${var.aws_region}a"
map_public_ip_on_launch = true

tags = {
Name = "Elegance-Public-Subnet"
}
}

resource "aws_internet_gateway" "elegance_gw" {
vpc_id = aws_vpc.elegance_vpc.id

tags = {
Name = "Elegance-IGW"
}
}

resource "aws_route_table" "elegance_rt" {
vpc_id = aws_vpc.elegance_vpc.id

route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.elegance_gw.id
}

tags = {
Name = "Elegance-Route-Table"
}
}

resource "aws_route_table_association" "elegance_rta" {
subnet_id = aws_subnet.elegance_public_subnet.id
route_table_id = aws_route_table.elegance_rt.id
}

resource "aws_security_group" "elegance_sg" {
name = "elegance-sg"
description = "Allow HTTP, API, and restricted SSH"
vpc_id = aws_vpc.elegance_vpc.id

ingress {
description = "SSH"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = [var.ssh_access_cidr]
}

ingress {
description = "HTTP"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}

ingress {
description = "API"
from_port = var.backend_port
to_port = var.backend_port
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 = "Elegance-Security-Group"
}
}

resource "aws_instance" "elegance_backend" {
count = var.backend_instance_count
ami = data.aws_ami.ubuntu.id
instance_type = var.instance_type
subnet_id = aws_subnet.elegance_public_subnet.id
vpc_security_group_ids = [aws_security_group.elegance_sg.id]

tags = {
Name = "Elegance-Backend-${count.index + 1}"
}
}

resource "aws_instance" "elegance_frontend" {
ami = data.aws_ami.ubuntu.id
instance_type = var.instance_type
subnet_id = aws_subnet.elegance_public_subnet.id
vpc_security_group_ids = [aws_security_group.elegance_sg.id]

tags = {
Name = "Elegance-Frontend"
}
}
21 changes: 21 additions & 0 deletions Devops/terraform/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
output "backend_instances" {
description = "Backend instance details"
value = {
ips = aws_instance.elegance_backend[*].public_ip
count = length(aws_instance.elegance_backend)
instance_ids = aws_instance.elegance_backend[*].id
}
}

output "frontend_instance" {
description = "Frontend instance details"
value = {
ip = aws_instance.elegance_frontend.public_ip
instance_id = aws_instance.elegance_frontend.id
}
}

output "security_group_id" {
description = "Security group ID"
value = aws_security_group.elegance_sg.id
}
40 changes: 40 additions & 0 deletions Devops/terraform/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
variable "aws_region" {
description = "AWS region to deploy resources"
type = string
}

variable "vpc_cidr" {
description = "CIDR block for VPC"
type = string
default = "10.0.0.0/16"
}

variable "public_subnet_cidr" {
description = "CIDR block for public subnet"
type = string
default = "10.0.1.0/24"
}

variable "instance_type" {
description = "EC2 instance type"
type = string
default = "t2.micro"
}

variable "backend_instance_count" {
description = "Number of backend instances to launch"
type = number
default = 2
}

variable "ssh_access_cidr" {
description = "CIDR block allowed to SSH access"
type = string
default = "0.0.0.0/0"
}

variable "backend_port" {
description = "Port for backend API access"
type = number
default = 8000
}