Files
aitbc/infra/terraform/ecs.tf
aitbc b3293527b8
Some checks failed
Cross-Node Transaction Testing / transaction-test (push) Has been cancelled
Deploy to Testnet / deploy-testnet (push) Has been cancelled
Multi-Node Stress Testing / stress-test (push) Has been cancelled
Node Failover Simulation / failover-test (push) Has been cancelled
infra: add Terraform infrastructure as code for AWS deployment
- Create main.tf with VPC, security groups, ECS, ALB, RDS, Redis, S3
- Add provider.tf with AWS provider configuration
- Create variables.tf for infrastructure configuration
- Add outputs.tf for infrastructure outputs
- Implement ecs.tf with ECS task definitions and services
- Add ecs_variables.tf for ECS-specific variables
- Create comprehensive README.md with usage instructions
- Implement state management with S3 backend and DynamoDB locking
- Add security best practices (private subnets, encryption, secrets manager)
2026-05-09 12:36:08 +02:00

210 lines
5.2 KiB
HCL

# ECS task definition for AITBC API service
resource "aws_ecs_task_definition" "api" {
family = "${var.project_name}-${var.environment}-api"
network_mode = "awsvpc"
requires_compatibilities = ["FARGATE"]
cpu = var.api_cpu
memory = var.api_memory
execution_role_arn = aws_iam_role.ecs_execution_role.arn
task_role_arn = aws_iam_role.ecs_task_role.arn
container_definitions = jsonencode([
{
name = "api"
image = "${var.api_image}:${var.api_image_tag}"
cpu = var.api_cpu
memory = var.api_memory
essential = true
portMappings = [
{
containerPort = 8000
protocol = "tcp"
}
]
environment = [
{
name = "ENVIRONMENT"
value = var.environment
},
{
name = "LOG_LEVEL"
value = var.log_level
}
]
secrets = [
{
name = "DATABASE_URL"
valueFrom = aws_secretsmanager_secret.database_url.arn
},
{
name = "REDIS_URL"
valueFrom = aws_secretsmanager_secret.redis_url.arn
},
{
name = "JWT_SECRET"
valueFrom = aws_secretsmanager_secret.jwt_secret.arn
}
]
logConfiguration = {
logDriver = "awslogs"
options = {
"awslogs-group" = aws_cloudwatch_log_group.api.name
"awslogs-region" = var.aws_region
"awslogs-stream-prefix" = "api"
}
}
healthCheck = {
command = ["CMD-SHELL", "curl -f http://localhost:8000/health || exit 1"]
interval = 30
timeout = 5
retries = 3
startPeriod = 60
}
}
])
tags = {
Name = "${var.project_name}-${var.environment}-api"
}
}
# ECS service for API
resource "aws_ecs_service" "api" {
name = "${var.project_name}-${var.environment}-api"
cluster = aws_ecs_cluster.this.id
task_definition = aws_ecs_task_definition.api.arn
desired_count = var.api_desired_count
launch_type = "FARGATE"
network_configuration {
subnets = module.vpc.private_subnets
security_groups = [aws_security_group.api_gateway.id]
assign_public_ip = false
}
load_balancer {
target_group_arn = aws_lb_target_group.api.arn
container_name = "api"
container_port = 8000
}
depends_on = [aws_lb_listener.https]
tags = {
Name = "${var.project_name}-${var.environment}-api"
}
}
# IAM roles
resource "aws_iam_role" "ecs_execution_role" {
name = "${var.project_name}-${var.environment}-ecs-execution-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "ecs-tasks.amazonaws.com"
}
}
]
})
tags = {
Name = "${var.project_name}-${var.environment}-ecs-execution-role"
}
}
resource "aws_iam_role_policy_attachment" "ecs_execution_role_policy" {
role = aws_iam_role.ecs_execution_role.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
}
resource "aws_iam_role" "ecs_task_role" {
name = "${var.project_name}-${var.environment}-ecs-task-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "ecs-tasks.amazonaws.com"
}
}
]
})
tags = {
Name = "${var.project_name}-${var.environment}-ecs-task-role"
}
}
resource "aws_iam_role_policy" "ecs_task_policy" {
name = "${var.project_name}-${var.environment}-ecs-task-policy"
role = aws_iam_role.ecs_task_role.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
]
Resource = "${aws_s3_bucket.data.arn}/*"
},
{
Effect = "Allow"
Action = [
"secretsmanager:GetSecretValue"
]
Resource = [
aws_secretsmanager_secret.database_url.arn,
aws_secretsmanager_secret.redis_url.arn,
aws_secretsmanager_secret.jwt_secret.arn
]
}
]
})
}
# Secrets Manager
resource "aws_secretsmanager_secret" "database_url" {
name = "${var.project_name}/${var.environment}/database/url"
}
resource "aws_secretsmanager_secret_version" "database_url" {
secret_id = aws_secretsmanager_secret.database_url.id
secret_string = var.database_url
}
resource "aws_secretsmanager_secret" "redis_url" {
name = "${var.project_name}/${var.environment}/redis/url"
}
resource "aws_secretsmanager_secret_version" "redis_url" {
secret_id = aws_secretsmanager_secret.redis.id
secret_string = var.redis_url
}
resource "aws_secretsmanager_secret" "jwt_secret" {
name = "${var.project_name}/${var.environment}/jwt/secret"
}
resource "aws_secretsmanager_secret_version" "jwt_secret" {
secret_id = aws_secretsmanager_secret.jwt_secret.id
secret_string = var.jwt_secret
}