
Container Platform on AWS — Use Case
A production-style container platform on the AWS Free Tier: ECS on EC2 behind an ALB, images in ECR, deploys from GitHub Actions via OIDC, defined in Terraform, and secured with HTTPS (ACM).
Why I built This
I wanted a real-world container platform that felt like production (CI/CD, load balancing, observability, least-privileged IAM) but without burning morning while I iterate.
Solution
A Node/Express demo app that runs on ECS (EC2 launch type) behind an ALB. Pushing to main
triggers a GitHub Actions workflow that assumes an AWS role via OIDC, builds and pushes an image to ECR, registers a new task definition, and updates the ECS service. HTTPS is handled by ACM + ALB. Everything is defined in Terraform.
Public URL: app.gabrielejiro.tech (ALB → ECS task on port 3000)
Architecture
CI/CD Without Secrets
GitHub Actions uses OIDC to assume a deploy role in AWS with short-lived credentials (no static access keys). The pipeline builds, pushes to ECR, registers a task definition with the new image SHA, and updates the ECS service. A force-new-deployment can roll tasks instantly.
What actually went wrong (and how I fixed it)
- Terraform single-line blocks: converted to multiline blocks to satisfy HCL parser.
- OIDC provider already exists: switched to a data source referencing the existing provider instead of trying to recreate it.
- Git push rejected (685 MB binary): added proper
.gitignore
and usedgit filter-repo
to purge.terraform/
from history. - ALB 503 with healthy targets: pinned
containerPort:3000
tohostPort:3000
to avoid random host ports blocked by security groups. - HTTPS not reachable: attached the ACM cert to the 443 listener and opened port 443 on the ALB security group, with :80 → 301 to HTTPS.
Monitoring
CloudWatch Dashboard shows ECS CPU utilization, ALB request count, and target response time. Logs stream to /ecs/demo-web
and I use Logs Insights to spot-check the last lines. Quick test load:
for i in {1..50}; do curl -s https://app.gabrielejiro.tech/health > /dev/null; done
Then refresh the dashboard to see metrics move.
What I shipped
- ECS cluster (EC2) with one
t3.micro
host - ALB with HTTP→HTTPS redirect and ACM certificate
- ECR repository and CI/CD pipeline from GitHub Actions (OIDC)
- Terraform for VPC, ALB, ECS, ECR, IAM, CloudWatch
- CloudWatch dashboard + log insights
Lessons learned
- OIDC is the clean way to deploy from GitHub without long-lived AWS keys.
- ALB + ECS port mappings require matching security groups to avoid 503s.
- Keep providers/state out of Git, or GitHub will block large pushes.
- HTTPS on ALB demands the cert in the same region and SNI on the custom domain.
Outcome
A production-style container platform that’s automated, secure, and affordable to run on the Free Tier.