Skip to content

Instantly share code, notes, and snippets.

@apotitech
Created March 30, 2024 23:12
Show Gist options
  • Save apotitech/bfb372e92d2b88fee935ee39a8f68ed7 to your computer and use it in GitHub Desktop.
Save apotitech/bfb372e92d2b88fee935ee39a8f68ed7 to your computer and use it in GitHub Desktop.
Deploying Django Application on AWS with Terraform ... ECS
# Production cluster
resource "aws_ecs_cluster" "prod" {
name = "prod"
}
# Backend web task definition and service
resource "aws_ecs_task_definition" "prod_backend_web" {
network_mode = "awsvpc"
requires_compatibilities = ["FARGATE"]
cpu = 256
memory = 512
family = "backend-web"
container_definitions = templatefile(
"templates/backend_container.json.tpl",
{
region = var.region
name = "prod-backend-web"
image = aws_ecr_repository.backend.repository_url
command = ["gunicorn", "-w", "3", "-b", ":8000", "django_aws.wsgi:application"]
log_group = aws_cloudwatch_log_group.prod_backend.name
log_stream = aws_cloudwatch_log_stream.prod_backend_web.name
},
)
execution_role_arn = aws_iam_role.ecs_task_execution.arn
task_role_arn = aws_iam_role.prod_backend_task.arn
}
resource "aws_ecs_service" "prod_backend_web" {
name = "prod-backend-web"
cluster = aws_ecs_cluster.prod.id
task_definition = aws_ecs_task_definition.prod_backend_web.arn
desired_count = 1
deployment_minimum_healthy_percent = 50
deployment_maximum_percent = 200
launch_type = "FARGATE"
scheduling_strategy = "REPLICA"
load_balancer {
target_group_arn = aws_lb_target_group.prod_backend.arn
container_name = "prod-backend-web"
container_port = 8000
}
network_configuration {
security_groups = [aws_security_group.prod_ecs_backend.id]
subnets = [aws_subnet.prod_private_1.id, aws_subnet.prod_private_2.id]
assign_public_ip = false
}
}
# Security Group
resource "aws_security_group" "prod_ecs_backend" {
name = "prod-ecs-backend"
vpc_id = aws_vpc.prod.id
ingress {
from_port = 0
to_port = 0
protocol = "-1"
security_groups = [aws_security_group.prod_lb.id]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
# IAM roles and policies
resource "aws_iam_role" "prod_backend_task" {
name = "prod-backend-task"
assume_role_policy = jsonencode({
Version = "2012-10-17",
Statement = [
{
Action = "sts:AssumeRole",
Principal = {
Service = "ecs-tasks.amazonaws.com"
},
Effect = "Allow",
Sid = ""
}
]
})
}
resource "aws_iam_role" "ecs_task_execution" {
name = "ecs-task-execution"
assume_role_policy = jsonencode(
{
Version = "2012-10-17",
Statement = [
{
Action = "sts:AssumeRole",
Principal = {
Service = "ecs-tasks.amazonaws.com"
},
Effect = "Allow",
Sid = ""
}
]
}
)
}
resource "aws_iam_role_policy_attachment" "ecs-task-execution-role-policy-attachment" {
role = aws_iam_role.ecs_task_execution.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
}
# Cloudwatch Logs
resource "aws_cloudwatch_log_group" "prod_backend" {
name = "prod-backend"
retention_in_days = var.ecs_prod_backend_retention_days
}
resource "aws_cloudwatch_log_stream" "prod_backend_web" {
name = "prod-backend-web"
log_group_name = aws_cloudwatch_log_group.prod_backend.name
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment