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
- 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)
210 lines
5.2 KiB
HCL
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
|
|
}
|