Skip to content
← Back to Case Studies
CLOUD INFRASTRUCTURE8-min deploys, down from 2 hours

From Manual Deployments to Infrastructure-as-Code on AWS

How a 4-person engineering team eliminated deployment risk by migrating from manual AWS console clicks to Terraform + GitHub Actions with zero-downtime releases.

TerraformAWS ECSAWS AuroraGitHub ActionsDockerCloudWatch

Representative project based on real engagements. Client details anonymized.

The situation

A B2B SaaS company with a 4-person backend team was deploying by clicking through the AWS console. Each release took 2-3 hours: manually pushing Docker images to ECR, updating ECS task definitions, running database migrations by hand, and praying nothing broke. There was no staging environment that matched production. Rollbacks meant re-deploying the previous image manually.

The team shipped once every 2 weeks because deployments were stressful and risky. Features sat in branches for days waiting for a deployment window.

What we built

Terraform modules (week 1-2): We wrote reusable Terraform modules for VPC, ECS Fargate, Aurora PostgreSQL, IAM roles, and CloudWatch alarms. State lives in S3 with DynamoDB locking. Every infrastructure change goes through a pull request with terraform plan output in the PR comment, so the team can review changes before applying.

CI/CD pipeline (week 2-3): GitHub Actions handles the full pipeline: lint → test → build Docker image → push to ECR → deploy to staging → run smoke tests → promote to production. Blue-green deployments on ECS mean the new version runs alongside the old one. If health checks fail, traffic stays on the old version.

Database migrations (week 3): Schema migrations run automatically as part of the deployment pipeline using Prisma Migrate. A pre-deploy step checks for destructive migrations and requires manual approval for anything that drops columns or tables.

Monitoring (week 4): CloudWatch dashboards for ECS service health, Aurora connection pool usage, and API latency. Alarms trigger Slack notifications when error rates spike or latency exceeds thresholds.

The numbers

MetricBeforeAfter
Deploy time2-3 hours8 minutes
Deploy frequencyEvery 2 weeksMultiple times per week
Rollback time30+ minutes (manual)2 minutes (ECS task definition revert)
Staging parityNoneIdentical to production
Deployment riskHigh (manual steps)Low (automated, auditable)

What we learned

The hardest part was not Terraform or GitHub Actions — it was convincing the team to stop using the AWS console for manual changes. We enforced this with a Terraform drift detection job that runs nightly and alerts if anyone makes manual changes to managed resources. Within 3 weeks, the team stopped clicking around in the console entirely.

Have a similar problem?

Book a short conversation with a senior engineer and we will tell you honestly whether we can help.