You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Blue-green deployments for Azure Container Apps, GCP Cloud Run and AWS ECS. strategy: blue-green stages a release on the side that carries no traffic, runs the smoke commands against it and switches in one write. The previous version keeps its label at 0% and that is the rollback target, but it is switched off once the new one serves: a Container Apps revision that is not deactivated holds on to its own scale rules, and there is no call that lowers the minReplicas of a running revision, so a side nobody uses would otherwise go on costing money between releases. strategy.keep_warm: true leaves it running instead, per file or per service, for the environment where a cold start is the more expensive half. evolve-deploy rollback <config> puts the environment back on its other side without having to name a label — it works out which side is not serving, refuses when the targets disagree about that or about the version behind it, and prints what it is trading for what; both it and traffic --to start the revision they are handing traffic to and wait for it, since the side being rolled back to is normally stopped, and both switch off what is no longer serving once it has moved — which is also how to clean up an app carrying old revisions with no label left on them, by pointing it at the side it is already on. The choreography is one piece of code on all three and the config is the same, but who owns the traffic is not, and that changes what a rollback is. On Cloud Run the tool owns the tagged traffic block just as it owns the Container Apps one, the staged address comes back from the API instead of being assembled, and a revision without traffic scales itself to zero — so keep_warm is refused there, because keeping one warm is scaling.min_instance_count on the template and Terraform owns that. ECS is the other family: it has a blue/green engine of its own, so the tool declares the rollout rather than driving it and answers the gate ECS offers — a PAUSE lifecycle hook at POST_TEST_TRAFFIC_SHIFT, test traffic fully on the new side and production traffic still on the old one, with no Lambda and no appspec. Because ECS owns both target groups and terminates the old tasks itself, test_url on the target is required (a listener rule is not an address), strategy.env per side is refused (per-side environment needs sides that alternate), keep_warm is refused in favour of strategy.bake_time (a window rather than a standing state, and setting both is a validation error), and traffic --to does not apply because there is no side to name. rollback does apply and takes the other shape there: for as long as the deployment has not finished the previous version is still running, so it asks ECS to put the traffic back — which covers the bake window after a switch and a release whose pipeline died at the smoke gate. Once ECS has finished the old tasks are gone and going back is a deploy, which the command says with the line to run rather than failing. So bake_time is also how long rollback keeps working. Terraform still owns the routing everywhere: on ECS the tool reads the alternate target group, both listener rules and the role off the service and refuses when any is missing. A release is one release: everything is staged first, then every smoke command runs, then all of the traffic moves — including services with nothing to change, staged at the version they already run, because the side belongs to the environment and a side missing an app is not a stack you can point a smoke test at. Nothing is staged when nothing changed, so a second apply is still a no-op. Active is the label with 100% of the traffic; a split, an environment whose apps disagree about which side is idle, and a depends_on between two blue-green services are all refused while planning. strategy.env.<label> gives each side the variables it needs to reach its own downstream — the router on green reading the green graph, the storefront on green calling the green router — additively, and excluded from the diff because those values differ by side by definition. Every blue-green target also gets EVOLVE_DEPLOY_SIDE. evolve-deploy traffic shows which side is serving and --to <label> puts it on a side by name, which is the way out of a split. Hooks get {{.label}} and {{.previous_label}}, smoke gates the release rather than a service, so it lives at file level, runs once, and names what it wants with {{url \"site\"}} because a release has no single address, --var name=value passes in what a deploy config cannot know, and hook lines are now rendered while planning so a mistyped variable fails the plan instead of an after hook on a release that already succeeded.