The Architecture
The Laravel CMS runs as an ECS Fargate task. The database is RDS PostgreSQL in the same VPC. The connection is enforced at the network level — the RDS security group only accepts traffic from the ECS task's security group.
Terraform Security Group Rules
resource "aws_security_group_rule" "ecs_to_rds" {
type = "ingress"
from_port = 5432
to_port = 5432
protocol = "tcp"
security_group_id = aws_security_group.rds.id
source_security_group_id = aws_security_group.ecs_tasks.id
}
Environment Variables in the Task Definition
The RDS endpoint is injected into the container as environment variables. The hostname comes from Terraform's aws_db_instance output — the task definition references it via templatefile().
environment = [
{ name = "DB_HOST", value = aws_db_instance.main.address },
{ name = "DB_PORT", value = "5432" },
{ name = "DB_DATABASE", value = var.db_name },
{ name = "DB_USERNAME", value = var.db_user },
{ name = "DB_PASSWORD", value = var.db_password },
{ name = "FILESYSTEM_DISK", value = "s3" },
{ name = "AWS_BUCKET", value = aws_s3_bucket.cms.bucket },
]
Health Check Interval
The ECS service uses a 10-second health check interval. The ALB marks the task healthy after 2 consecutive successes — about 20 seconds after the container starts. The entrypoint runs migrations during this window.
health_check {
path = "/health"
interval = 10
healthy_threshold = 2
unhealthy_threshold = 3
timeout = 5
}
Tip: A 10-second interval with 2 healthy threshold means the service registers as healthy in 20s minimum. Longer intervals slow deployments significantly — for a small site, tight intervals are worth the minor extra ALB cost.