Adds initial files]
This commit is contained in:
249
infra/ecs_alb/main.tf
Normal file
249
infra/ecs_alb/main.tf
Normal file
@@ -0,0 +1,249 @@
|
||||
terraform {
|
||||
required_providers {
|
||||
aws = {
|
||||
source = "hashicorp/aws"
|
||||
version = "~> 6.27"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "aws" {
|
||||
region = var.aws_region
|
||||
}
|
||||
|
||||
# Get current AWS account
|
||||
data "aws_caller_identity" "current" {}
|
||||
|
||||
# Reference existing VPC
|
||||
data "aws_vpc" "existing" {
|
||||
id = var.vpc_id
|
||||
}
|
||||
|
||||
# Reference existing public subnets
|
||||
data "aws_subnet" "public" {
|
||||
count = length(var.public_subnet_ids)
|
||||
id = var.public_subnet_ids[count.index]
|
||||
}
|
||||
|
||||
# Reference existing private subnets (for ECS tasks)
|
||||
data "aws_subnet" "private" {
|
||||
count = length(var.private_subnet_ids)
|
||||
id = var.private_subnet_ids[count.index]
|
||||
}
|
||||
|
||||
# Security Group for ALB (in public subnets)
|
||||
resource "aws_security_group" "alb" {
|
||||
name = "${var.app_name}-alb-sg"
|
||||
description = "Allow inbound traffic to ALB"
|
||||
vpc_id = data.aws_vpc.existing.id
|
||||
|
||||
ingress {
|
||||
from_port = 80
|
||||
to_port = 80
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["3.14.44.224/32"]
|
||||
description = "Allow HTTP from internet"
|
||||
}
|
||||
|
||||
egress {
|
||||
from_port = 0
|
||||
to_port = 0
|
||||
protocol = "-1"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
description = "Allow all outbound"
|
||||
}
|
||||
|
||||
tags = {
|
||||
Name = "${var.app_name}-alb-sg"
|
||||
}
|
||||
}
|
||||
|
||||
# Security Group for ECS Tasks (in private subnets)
|
||||
resource "aws_security_group" "ecs_tasks" {
|
||||
name = "${var.app_name}-ecs-tasks-sg"
|
||||
description = "Allow inbound traffic from ALB"
|
||||
vpc_id = data.aws_vpc.existing.id
|
||||
|
||||
ingress {
|
||||
from_port = 8000
|
||||
to_port = 8000
|
||||
protocol = "tcp"
|
||||
security_groups = [aws_security_group.alb.id]
|
||||
description = "Allow traffic from ALB"
|
||||
}
|
||||
|
||||
egress {
|
||||
from_port = 0
|
||||
to_port = 0
|
||||
protocol = "-1"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
description = "Allow all outbound"
|
||||
}
|
||||
|
||||
tags = {
|
||||
Name = "${var.app_name}-ecs-tasks-sg"
|
||||
}
|
||||
}
|
||||
|
||||
# Application Load Balancer (in public subnets)
|
||||
resource "aws_lb" "main" {
|
||||
name = "${var.app_name}-alb"
|
||||
internal = false
|
||||
load_balancer_type = "application"
|
||||
security_groups = [aws_security_group.alb.id]
|
||||
subnets = var.public_subnet_ids
|
||||
|
||||
enable_deletion_protection = false
|
||||
|
||||
tags = {
|
||||
Name = "${var.app_name}-alb"
|
||||
}
|
||||
}
|
||||
|
||||
# Target Group
|
||||
resource "aws_lb_target_group" "app" {
|
||||
name = "${var.app_name}-tg"
|
||||
port = 8000
|
||||
protocol = "HTTP"
|
||||
vpc_id = data.aws_vpc.existing.id
|
||||
target_type = "ip"
|
||||
|
||||
health_check {
|
||||
enabled = true
|
||||
healthy_threshold = 2
|
||||
interval = 30
|
||||
matcher = "200"
|
||||
path = "/health"
|
||||
port = "traffic-port"
|
||||
protocol = "HTTP"
|
||||
timeout = 5
|
||||
unhealthy_threshold = 3
|
||||
}
|
||||
|
||||
deregistration_delay = 30
|
||||
|
||||
tags = {
|
||||
Name = "${var.app_name}-tg"
|
||||
}
|
||||
}
|
||||
|
||||
# ALB Listener
|
||||
resource "aws_lb_listener" "app" {
|
||||
load_balancer_arn = aws_lb.main.arn
|
||||
port = "80"
|
||||
protocol = "HTTP"
|
||||
|
||||
default_action {
|
||||
type = "forward"
|
||||
target_group_arn = aws_lb_target_group.app.arn
|
||||
}
|
||||
}
|
||||
|
||||
# ECS Cluster
|
||||
resource "aws_ecs_cluster" "main" {
|
||||
name = "${var.app_name}-cluster"
|
||||
|
||||
tags = {
|
||||
Name = "${var.app_name}-cluster"
|
||||
}
|
||||
}
|
||||
|
||||
# CloudWatch Log Group
|
||||
resource "aws_cloudwatch_log_group" "app" {
|
||||
name = "/ecs/${var.app_name}"
|
||||
retention_in_days = 7
|
||||
|
||||
tags = {
|
||||
Name = "${var.app_name}-logs"
|
||||
}
|
||||
}
|
||||
|
||||
# ECS Task Execution Role
|
||||
resource "aws_iam_role" "ecs_task_execution_role" {
|
||||
name = "${var.app_name}-ecs-task-execution-role"
|
||||
|
||||
assume_role_policy = jsonencode({
|
||||
Version = "2012-10-17"
|
||||
Statement = [{
|
||||
Action = "sts:AssumeRole"
|
||||
Effect = "Allow"
|
||||
Principal = {
|
||||
Service = "ecs-tasks.amazonaws.com"
|
||||
}
|
||||
}]
|
||||
})
|
||||
}
|
||||
|
||||
resource "aws_iam_role_policy_attachment" "ecs_task_execution_role_policy" {
|
||||
role = aws_iam_role.ecs_task_execution_role.name
|
||||
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
|
||||
}
|
||||
|
||||
# ECS Task Definition
|
||||
resource "aws_ecs_task_definition" "app" {
|
||||
family = var.app_name
|
||||
network_mode = "awsvpc"
|
||||
requires_compatibilities = ["FARGATE"]
|
||||
cpu = var.fargate_cpu
|
||||
memory = var.fargate_memory
|
||||
execution_role_arn = aws_iam_role.ecs_task_execution_role.arn
|
||||
|
||||
container_definitions = jsonencode([{
|
||||
name = var.app_name
|
||||
image = "${data.aws_caller_identity.current.account_id}.dkr.ecr.${var.aws_region}.amazonaws.com/${var.ecr_repository_name}:${var.image_tag}"
|
||||
|
||||
portMappings = [{
|
||||
containerPort = 8000
|
||||
hostPort = 8000
|
||||
protocol = "tcp"
|
||||
}]
|
||||
|
||||
logConfiguration = {
|
||||
logDriver = "awslogs"
|
||||
options = {
|
||||
"awslogs-group" = aws_cloudwatch_log_group.app.name
|
||||
"awslogs-region" = var.aws_region
|
||||
"awslogs-stream-prefix" = "ecs"
|
||||
}
|
||||
}
|
||||
|
||||
healthCheck = {
|
||||
command = ["CMD-SHELL", "curl -f http://localhost:8000/health || exit 1"]
|
||||
interval = 30
|
||||
timeout = 5
|
||||
retries = 3
|
||||
startPeriod = 60
|
||||
}
|
||||
}])
|
||||
|
||||
tags = {
|
||||
Name = "${var.app_name}-task"
|
||||
}
|
||||
}
|
||||
|
||||
# ECS Service (tasks in private subnets)
|
||||
resource "aws_ecs_service" "app" {
|
||||
name = "${var.app_name}-service"
|
||||
cluster = aws_ecs_cluster.main.id
|
||||
task_definition = aws_ecs_task_definition.app.arn
|
||||
desired_count = var.app_count
|
||||
launch_type = "FARGATE"
|
||||
|
||||
network_configuration {
|
||||
security_groups = [aws_security_group.ecs_tasks.id]
|
||||
subnets = var.private_subnet_ids # ECS tasks in private subnets
|
||||
assign_public_ip = false # No public IP needed with NAT gateway
|
||||
}
|
||||
|
||||
load_balancer {
|
||||
target_group_arn = aws_lb_target_group.app.arn
|
||||
container_name = var.app_name
|
||||
container_port = 8000
|
||||
}
|
||||
|
||||
depends_on = [aws_lb_listener.app]
|
||||
|
||||
tags = {
|
||||
Name = "${var.app_name}-service"
|
||||
}
|
||||
}
|
||||
23
infra/ecs_alb/terraform.tfvars
Normal file
23
infra/ecs_alb/terraform.tfvars
Normal file
@@ -0,0 +1,23 @@
|
||||
aws_region = "us-east-2"
|
||||
app_name = "upflux-doc-analyser"
|
||||
|
||||
# Replace these with your actual IDs
|
||||
vpc_id = "vpc-0270f02aee3bf1b8d"
|
||||
|
||||
# Your public subnets (where ALB will be)
|
||||
public_subnet_ids = [
|
||||
"subnet-088bc49c54ec8f028", # Public subnet 1
|
||||
"subnet-003f1693910a99afb" # Public subnet 2
|
||||
]
|
||||
|
||||
# Your private subnets (where ECS tasks will run)
|
||||
private_subnet_ids = [
|
||||
"subnet-045f73d784beed091", # Private subnet 1
|
||||
"subnet-06e660f44bf141442" # Private subnet 2
|
||||
]
|
||||
|
||||
ecr_repository_name = "upflux-doc-analyser"
|
||||
image_tag = "latest"
|
||||
fargate_cpu = "256"
|
||||
fargate_memory = "512"
|
||||
app_count = 1
|
||||
56
infra/ecs_alb/variables.tf
Normal file
56
infra/ecs_alb/variables.tf
Normal file
@@ -0,0 +1,56 @@
|
||||
variable "aws_region" {
|
||||
description = "AWS region"
|
||||
type = string
|
||||
default = "us-east-1"
|
||||
}
|
||||
|
||||
variable "app_name" {
|
||||
description = "Application name"
|
||||
type = string
|
||||
default = "fastapi-app"
|
||||
}
|
||||
|
||||
variable "vpc_id" {
|
||||
description = "Existing VPC ID"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "public_subnet_ids" {
|
||||
description = "List of existing public subnet IDs (for ALB)"
|
||||
type = list(string)
|
||||
}
|
||||
|
||||
variable "private_subnet_ids" {
|
||||
description = "List of existing private subnet IDs (for ECS tasks)"
|
||||
type = list(string)
|
||||
}
|
||||
|
||||
variable "ecr_repository_name" {
|
||||
description = "ECR repository name"
|
||||
type = string
|
||||
default = "fastapi-app"
|
||||
}
|
||||
|
||||
variable "image_tag" {
|
||||
description = "Docker image tag"
|
||||
type = string
|
||||
default = "latest"
|
||||
}
|
||||
|
||||
variable "fargate_cpu" {
|
||||
description = "Fargate CPU units"
|
||||
type = string
|
||||
default = "256"
|
||||
}
|
||||
|
||||
variable "fargate_memory" {
|
||||
description = "Fargate memory in MB"
|
||||
type = string
|
||||
default = "512"
|
||||
}
|
||||
|
||||
variable "app_count" {
|
||||
description = "Number of tasks to run"
|
||||
type = number
|
||||
default = 1
|
||||
}
|
||||
Reference in New Issue
Block a user