Every deployment strategy in this domain eventually asks the same question: a new version is misbehaving in production — now what? Rollback speed usually matters more than rollback elegance, and the fastest rollback is one that was designed in before the deploy, not improvised during an incident.
4 min read
When production is broken, there are two ways out. Rollback reverts to the previous known-good version — fast, but it can't fix a problem that's already caused bad data (a buggy migration that corrupted rows won't be undone by reverting the app code). Roll-forward ships a fix on top of the broken version — slower (a new change has to be written, tested, and deployed under pressure), but it's the only option once bad data already exists, or when the "previous version" itself has a problem the new version was specifically fixing.
The practical default: rollback first if it's available and the damage is reversible, because "go back to the version that was working five minutes ago" is almost always faster than "carefully write and ship a fix while production is on fire." Roll-forward is the fallback for the cases rollback can't cover.
A rollback is only fast if the previous version is still readily deployable — which is exactly what the earlier lessons in this domain set up:
A team that skips these and rebuilds from source, doesn't keep a previous environment warm, and runs migrations that break backward compatibility, doesn't have a rollback plan — it has a rollback hope, discovered to not work at the worst possible time.
The canary lesson's auto_rollback_configuration is the general pattern: tie a deployment's progression (or reversal) directly to real metrics, not to a human watching a dashboard and deciding to act.
resource "aws_cloudwatch_metric_alarm" "error_rate" {
alarm_name = "deploy-error-rate-spike"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = 2
metric_name = "5xxErrorRate"
namespace = "AWS/ApplicationELB"
period = 60
statistic = "Average"
threshold = 5.0 # rollback if error rate exceeds 5%
}
resource "aws_codedeploy_deployment_group" "app" {
auto_rollback_configuration {
enabled = true
events = ["DEPLOYMENT_FAILURE", "DEPLOYMENT_STOP_ON_ALARM"]
}
alarm_configuration {
alarms = [aws_cloudwatch_metric_alarm.error_rate.alarm_name]
enabled = true
}
}The advantage over a human-watched rollout: a metric threshold breach at 3am triggers rollback in seconds, before an on-call engineer has even opened a laptop. The trade-off is real too — a threshold set too sensitively rolls back on noise (a brief, self-resolving blip), and a threshold set too loosely lets real damage accumulate before it fires; getting this calibration right takes iteration and isn't free.
"Just redeploy the old version" assumes the old version is genuinely compatible with everything else that's currently true in production — and that assumption breaks in a few predictable ways:
The common thread: rollback is safe exactly to the extent that every change shipped alongside the deploy was actually independently reversible — which is the same backward-compatibility discipline this whole domain has been building toward, applied in reverse.
Check your understanding
A quick comprehension check — not tracked, not graded, just for you.
1. When is rolling forward the better choice instead of rolling back?
2. Which practice from earlier in this domain makes a rollback fast specifically because a redeploy doesn't require rebuilding from source?
3. What is the trade-off of an automated rollback tied to a CloudWatch alarm threshold?
4. Why can 'redeploy the previous version' fail to be a fully clean rollback?
CI/CD & Deployment Pipelines