Adds initial files]

This commit is contained in:
2026-01-20 13:48:13 -03:00
parent 12176c50c1
commit 6026870c5c
16 changed files with 1316 additions and 0 deletions

25
infra/.terraform.lock.hcl generated Normal file
View File

@@ -0,0 +1,25 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/hashicorp/aws" {
version = "6.27.0"
constraints = "~> 6.27"
hashes = [
"h1:bixp2PSsP5ZGBczGCxcbSDn6lF5QFlUXlNroq9cdab4=",
"zh:177a24b806c72e8484b5cabc93b2b38e3d770ae6f745a998b54d6619fd0e8129",
"zh:4ac4a85c14fb868a3306b542e6a56c10bd6c6d5a67bc0c9b8f6a9060cf5f3be7",
"zh:552652185bc85c8ba1da1d65dea47c454728a5c6839c458b6dcd3ce71c19ccfc",
"zh:60284b8172d09aee91eae0856f09855eaf040ce3a58d6933602ae17c53f8ed04",
"zh:6be38d156756ca61fb8e7c752cc5d769cd709686700ac4b230f40a6e95b5dbc9",
"zh:7a409138fae4ef42e3a637e37cb9efedf96459e28a3c764fc4e855e8db9a7485",
"zh:8070cf5224ed1ed3a3e9a59f7c30ff88bf071c7567165275d477c1738a56c064",
"zh:894439ef340a9a79f69cd759e27ad11c7826adeca27be1b1ca82b3c9702fa300",
"zh:89d035eebf08a97c89374ff06040955ddc09f275ecca609d0c9d58d149bef5cf",
"zh:985b1145d724fc1f38369099e4a5087141885740fd6c0b1dbc492171e73c2e49",
"zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425",
"zh:a80b47ae8d1475201c86bd94a5dcb9dd4da5e8b73102a90820b68b66b76d50fd",
"zh:d3395be1556210f82199b9166a6b2e677cee9c4b67e96e63f6c3a98325ad7ab0",
"zh:db0b869d09657f6f1e4110b56093c5fcdf9dbdd97c020db1e577b239c0adcbce",
"zh:ffc72e680370ae7c21f9bd3082c6317730df805c6797427839a6b6b7e9a26a01",
]
}

32
infra/ecr/main.tf Normal file
View File

@@ -0,0 +1,32 @@
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 6.27"
}
}
}
provider "aws" {
region = var.aws_region
}
resource "aws_ecr_repository" "app" {
name = var.repository_name
image_tag_mutability = "MUTABLE" # or "IMMUTABLE"
image_scanning_configuration {
scan_on_push = true
}
encryption_configuration {
encryption_type = "AES256" # or "KMS" for customer managed keys
}
tags = {
Name = var.repository_name
Environment = var.environment
ManagedBy = "Terraform"
}
}

14
infra/ecr/outputs.tf Normal file
View File

@@ -0,0 +1,14 @@
output "repository_url" {
description = "ECR repository URL"
value = aws_ecr_repository.app.repository_url
}
output "repository_arn" {
description = "ECR repository ARN"
value = aws_ecr_repository.app.arn
}
output "repository_name" {
description = "ECR repository name"
value = aws_ecr_repository.app.name
}

View File

@@ -0,0 +1,75 @@
{
"version": 4,
"terraform_version": "1.14.3",
"serial": 6,
"lineage": "b2b2331d-cf66-169e-d25b-38e0528505fc",
"outputs": {
"repository_arn": {
"value": "arn:aws:ecr:us-east-2:232048051668:repository/upflux-doc-analyser",
"type": "string"
},
"repository_name": {
"value": "upflux-doc-analyser",
"type": "string"
},
"repository_url": {
"value": "232048051668.dkr.ecr.us-east-2.amazonaws.com/upflux-doc-analyser",
"type": "string"
}
},
"resources": [
{
"mode": "managed",
"type": "aws_ecr_repository",
"name": "app",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"arn": "arn:aws:ecr:us-east-2:232048051668:repository/upflux-doc-analyser",
"encryption_configuration": [
{
"encryption_type": "AES256",
"kms_key": ""
}
],
"force_delete": null,
"id": "upflux-doc-analyser",
"image_scanning_configuration": [
{
"scan_on_push": true
}
],
"image_tag_mutability": "MUTABLE",
"image_tag_mutability_exclusion_filter": [],
"name": "upflux-doc-analyser",
"region": "us-east-2",
"registry_id": "232048051668",
"repository_url": "232048051668.dkr.ecr.us-east-2.amazonaws.com/upflux-doc-analyser",
"tags": {
"Environment": "dev",
"ManagedBy": "Terraform",
"Name": "upflux-doc-analyser"
},
"tags_all": {
"Environment": "dev",
"ManagedBy": "Terraform",
"Name": "upflux-doc-analyser"
},
"timeouts": null
},
"sensitive_attributes": [],
"identity_schema_version": 0,
"identity": {
"account_id": "232048051668",
"name": "upflux-doc-analyser",
"region": "us-east-2"
},
"private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiZGVsZXRlIjoxMjAwMDAwMDAwMDAwfX0="
}
]
}
],
"check_results": null
}

View File

@@ -0,0 +1,3 @@
aws_region = "us-east-2"
repository_name = "upflux-doc-analyser"
environment = "dev"

16
infra/ecr/variable.tf Normal file
View File

@@ -0,0 +1,16 @@
variable "aws_region" {
description = "AWS region"
type = string
default = "us-east-1"
}
variable "repository_name" {
description = "Name of the ECR repository"
type = string
}
variable "environment" {
description = "Environment name"
type = string
default = "dev"
}

249
infra/ecs_alb/main.tf Normal file
View 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"
}
}

View 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

View 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
}

3
infra/terraform.tfvars Normal file
View File

@@ -0,0 +1,3 @@
aws_region = "us-east-2"
repository_name = "upflux-doc-analyser"
environment = "dev"