When I joined the team, shipping a release was a two-hour ritual: SSH in, pull, run migrations by hand, restart services one at a time, and pray nothing drifted between staging and production. We got it down to fifteen minutes — and made it boring.
The first win was deleting tribal knowledge. Everything that lived in someone's head or a wiki page became Terraform. If it isn't in the repo, it doesn't exist.
resource "aws_ecs_service" "api" {
name = "api"
cluster = aws_ecs_cluster.main.id
task_definition = aws_ecs_task_definition.api.arn
desired_count = 3
deployment_circuit_breaker {
enable = true
rollback = true
}
}
GitHub Actions builds the image, runs the test suite, applies migrations inside a one-off task, and rolls the service forward. The circuit breaker handles the unhappy path: a bad deploy rolls itself back before anyone notices.
A deploy you're afraid of is a deploy you do rarely. A deploy you're bored by is one you do ten times a day.
Two hours became fifteen minutes, releases went from weekly to on-demand, and uptime held at 99.5% across 20+ containers. The real prize wasn't the speed — it was that nobody dreads Fridays anymore.