Battle-tested AWS ECS infrastructure: CloudMap service discovery for Fargate (Service Connect) and EC2 (DNS) clusters
This template helps set up Fargate and EC2-based ECS clusters using AWS CloudMap for communication.
⚠️ Example Project - Not Production ReadyThis is a demonstration project. Before using in production, address these security issues:
- Enable RDS encryption with KMS, IAM authentication, and CloudWatch logs
- Configure S3 state bucket encryption and add DynamoDB table for state locking
- Replace wildcard IAM permissions with least-privilege policies
- Add secrets rotation for database passwords
- Fargate: Uses AWS Service Connect, creating HTTP-only CloudMap services. Includes an automatic proxy container.
- EC2-based ECS: Uses DNS-based discovery.
- Creates HTTP-only CloudMap services (no DNS resolution)
- Requires an additional proxy container (managed by AWS)
- If containers use
bridgemode, createsSRVrecords instead ofArecords (Nginx free version cannot resolveSRVrecords) - To get
Arecords, useawsvpcmode
To avoid duplicating code, the same my-application folder is used for different environments.
However, it is necessary to re-initialize the local Terraform state from S3 every time the environment is switched.
To switch environments, follow these steps:
- Clear the local state, including the
.terraformfolder and.terraform.lock.hclfile. - Run
terraform initwith the appropriate environment variables.
It is crucial to clear the local state to avoid merging states from different environments.
Delete the local state, and terraform init will restore it from S3, which is always safe.
terraform/my-application/- AWS resources for the ECS clustersterraform/environments/- Environment-specific variablesterraform/modules/- Common Terraform codetests/features/- BDD tests for the Terraform configurationMakefile- Commands for Terraform and tests
To use AWS CLI:
- Create an IAM user and include it in the admin group.
- Attach
AutoScalingFullAccesspolicy. - Create Access Key credentials.
- Set credentials in environment variables or
~/.aws/credentials:
export AWS_ACCESS_KEY_ID=...
export AWS_SECRET_ACCESS_KEY=...Before running Terraform, update the VPC ID in your environment configuration file.
To find available VPCs in your AWS account:
# List all VPCs with their details
aws ec2 describe-vpcs --region eu-west-2 \
--query 'Vpcs[*].[VpcId,IsDefault,CidrBlock]' \
--output table
# Get just the default VPC ID
aws ec2 describe-vpcs --region eu-west-2 \
--filters "Name=isDefault,Values=true" \
--query 'Vpcs[0].VpcId' \
--output textUpdate the vpc_id value in terraform/environments/dev/tfvars.hcl (or the appropriate environment file) with your VPC ID.
In the configuration, the debug mode for ECS containers is enabled (marked with # ecs execute-command).
See details in AWS ECS EXEC.
You should locally install Session Manager.
A useful utility to check your system's readiness for ECS EXEC is Exec-checker.
You can connect to the container in ECS using:
aws ecs execute-command --cluster ec2 \
--task $(aws ecs list-tasks --cluster ec2 --query "taskArns" --output text) \
--container ec2 --interactive --command "/bin/sh"To inspect an active task:
aws ecs describe-tasks --cluster ec2 \
--tasks $(aws ecs list-tasks --cluster ec2 --query "taskArns" --output text)Install Terraform from the official website or via Homebrew (macOS).
brew install hashicorp/tap/terraformUse pre-commit hooks to validate the Terraform code quality:
pre-commit installbrew tap liamg/tfsec
brew install terraform-docs tflint tfsec checkov
brew install pre-commit gawk coreutilsThe BDD tests use terraform plan to validate your infrastructure configuration without creating any AWS resources. This means:
✅ Tests are completely free - No AWS resources are created or modified
✅ Safe to run - Only generates a plan, never applies changes
You have several options to configure AWS credentials:
Option 1: AWS Configure (Recommended for development)
aws configure
# Enter your AWS Access Key ID, Secret Access Key, and default regionOption 2: Environment Variables
export AWS_ACCESS_KEY_ID="your-access-key-id"
export AWS_SECRET_ACCESS_KEY="your-secret-access-key"
export AWS_DEFAULT_REGION="eu-west-2"Option 3: AWS SSO
aws sso login --profile your-profile
export AWS_PROFILE=your-profileOption 4: AWS Credentials File
Create or edit ~/.aws/credentials:
[default]
aws_access_key_id = your-access-key-id
aws_secret_access_key = your-secret-access-keyAnd ~/.aws/config:
[default]
region = eu-west-2For detailed instructions on creating IAM credentials, see the Usage section.
Install and/or activate Python virtual environment (you need uv installed):
. ./activate.shNote the spaces after the first dot.
For this to work, you need uv installed.
Initialize Terraform (requires active AWS credentials) with:
make initRun comprehensive infrastructure tests covering security, networking, IAM, and resource configuration:
make testTest Coverage:
- 52 test scenarios across 6 test suites
- Security: Encryption, IAM policies, network isolation
- Configuration: ECS, RDS, CloudMap, load balancers
- Integration: Service discovery, health checks, database setup
See tests/TEST_COVERAGE.md for detailed test documentation.
Visit terraform-compliance for more on writing tests.