Module 7: Gitops Beyond Terraform

5. Application deployment strategies, named

Description

Every time apply.yml ran in this guide, the result was simple to reason about: infrastructure moved from one state to a new one, all at once, with no "two versions" of the andes-cargo-shipment-docs bucket ever running in parallel while someone decided which one stays. That problem —temporarily having two versions of something running at the same time, and deciding how and when to move real user traffic from one to the other with no downtime— is a problem Terraform, in this guide, never had. It is, instead, the central problem of deploying an application: a container, an API, a frontend, something with replicas running and real users connected at the exact moment of deployment. This lesson names the three standard strategies that solve that problem —blue/green, canary, rolling— with their real syntax, without building any of them.

Connection to the module

This lesson marks the point where the module moves furthest from ground you already know. Lessons 2 through 4 compared tools and mechanisms that, one way or another, kept solving the same underlying problem (applying a declared infrastructure change). This lesson enters a problem that doesn't exist in Andes Cargo's pipeline, because terraform apply doesn't deploy "replicas" of anything — it applies a new, complete state, all at once. Lesson 6 systematizes this difference with an explicit contrast table between application and infrastructure CI/CD; this lesson is the concrete piece that table needs so it doesn't stay abstract.


Why this guide never had this problem

Think about it with a concrete example from this guide. When Module 3 added the Compliance tag to the andes-cargo-shipment-docs bucket, terraform apply didn't leave "two buckets" running while someone decided which to use — it modified the existing bucket, in place, all at once. The same happens with the Shipments table, the IAM roles, the Lambda function: each one of those resources has one state at any given moment, and apply moves it from one state to the next, with no intermediate phase where both versions coexist serving real traffic.

An application with running replicas is different. Imagine process-shipment-manifest (Andes Cargo's Lambda function) were, instead, an API running in three containers behind a load balancer, receiving real users' requests right now. If you replace all three containers' code at once, there's an instant —however short— where no container can respond to requests: that's downtime. If the new code has a bug you didn't catch in testing, every user suffers it at the same time, because there's no earlier version running in parallel to compare against or to fall back to quickly. This lesson's three strategies are, each one, a different answer to this exact problem.


Analogy: two theater stages

Imagine a theater with two identical stages, side by side, but only one lit at a time — the audience always watches whichever stage has its lights on. While the audience watches the show on Stage A (lit), the cast can rehearse the new version of the show, with changes, on Stage B (dark, no audience watching). When the new version is ready and tested on B, the lighting technician simply turns off A and turns on B — the change in "what the audience sees" is instant, with no moment of an empty stage in between. If something goes wrong with the new version, the fix is just as instant: turn off B, turn A back on, the old show continues exactly where it was, because it was never dismantled.

That's, precisely, blue/green: two complete environments ("blue" and "green," the colors are just a naming convention, with no special technical meaning) running in parallel, one serving real traffic ("lit") and the other ready but inactive. The "lighting change" is, technically, redirecting traffic —from a load balancer, a DNS, a router— from the old environment to the new one, all at once.


The three strategies, with technical precision

Rolling deployment (gradual replacement)

It's Kubernetes's default strategy for a Deployment: instead of replacing all replicas at once, it replaces them a little at a time, one portion at a time, with the old and new versions briefly coexisting during the transition.

spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1

maxSurge controls how many extra replicas (above the desired count) Kubernetes can temporarily create to speed up the replacement; maxUnavailable controls how many replicas it can have out of service at the same time during the transition. Both accept an absolute number or a percentage. It's the simplest of the three strategies —it needs no extra infrastructure, it already ships with Kubernetes's Deployment controller by default—, but also the most limited: during the transition, there are real users being served by the old version and real users being served by the new version, at the same time, with no fine control over which ones.

Blue/green (two complete environments, instant switch)

Per AWS documentation: "the blue/green deployment strategy is a type of immutable deployment which also requires creation of another environment. Once the new environment is up and passed all tests, traffic is shifted to this new deployment" — the old environment ("blue") stays inactive, it's not destroyed, specifically so you can switch back immediately (Switch back to old environment is, literally, the documented rollback process for this strategy) if something goes wrong.

The key difference from rolling: at no point is there a partial traffic mix between the two versions — it's old or new, never "70% old, 30% new" at the same time. The cost is real: while both environments exist, you're paying for double the infrastructure running — the same kind of cost decision you already saw with LocalStack, now in an application context, not a lab one.

Canary deployment (a small portion, first)

The name comes from a real mining practice, from long before computing: miners carried a canary in a cage into underground tunnels because the bird, being more sensitive to toxic gases than a human, would show symptoms —or die— before the gas became dangerous for people, giving an early warning. A canary deployment applies the same logic: the new version first gets sent to a very small portion of real traffic (5%, 1%, sometimes less), while the vast majority of users stay on the stable version. If that small portion's metrics stay healthy —error rate, latency—, the percentage gradually increases up to 100%. If something degrades, that small portion gets reverted before the problem affects most users.

Plain Kubernetes doesn't include canary as a native Deployment strategy —unlike rolling, which does come by default—; in practice it gets implemented with additional tools, like Argo Rollouts (from the same CNCF project as ArgoCD, this module's lesson 3), which per its own documentation "provide[s] advanced deployment capabilities such as blue-green, canary, canary analysis, experimentation, and progressive delivery features to Kubernetes" — the same family of GitOps tools you already named, extended to also solve this problem. A simplified example, named, not executed:

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: andes-cargo-shipment-api
spec:
  strategy:
    canary:
      steps:
        - setWeight: 5
        - pause: { duration: 10m }
        - setWeight: 25
        - pause: { duration: 10m }
        - setWeight: 100

setWeight: 5 sends 5% of real traffic to the new version; pause: { duration: 10m } stops the automatic progression for ten minutes —time for a monitoring system (outside this guide's scope, sre-and-incident-response-guide's territory) to confirm the metrics stay healthy before bumping the percentage further.


The three, in direct contrast

RollingBlue/greenCanary
How many complete environments?One, in gradual transitionTwo, complete, in parallelOne, with a separate traffic portion
Traffic mix between versions?Yes, with no fine controlNo — never mixes, it's an instant switchYes, with fine, gradual control (setWeight)
Rollback speedMedium (has to revert the in-progress transition)Instant (point back to the old environment)Fast (drop the new portion's setWeight to 0%)
Extra infrastructure costLow (temporary maxSurge)High (double environment for the duration)Low-medium (only the small extra portion)
Native Kubernetes supportYes (Deployment by default)No — requires an additional tool (Argo Rollouts, Flagger, or others)No — requires an additional tool

No strategy "wins" in the abstract — the choice depends on how much downtime is tolerable, how much extra budget exists for duplicated infrastructure, and how much fine control over traffic the team needs. A team with a tight budget and low-risk changes can live well with rolling; a team deploying a high-risk change to a critical API probably prefers canary, accepting the extra complexity in exchange for catching a problem with 5% of its users, not 100%.


This lesson's boundary, precisely

None of the above ran in this guide — there's no Kubernetes Deployment, no Argo Rollouts installed, no load balancer with two environments configured. It's, deliberately, named syntax verified against official documentation, not an executed lab. Two ecosystem guides cover this in depth, each from its own angle:

  • kubernetes-and-eks-in-production-guide — where these three strategies really get implemented, with a real (or local) cluster, probably alongside the previous lesson's ArgoCD/Flux, forming the complete pull-based GitOps + application deployment picture this guide only names.
  • aws-serverless-and-containers-guide — where blue/green and canary's equivalent gets implemented with native AWS tools outside Kubernetes: Lambda aliases with weighted traffic shifting, or ECS/Fargate deployments with CodeDeploy, solving the same problem with a completely different stack.

Common mistakes

Confusing "application deployment strategy" with "infrastructure rollback strategy" (the most important one, crosses over with Module 6). What happens: someone, recalling Module 6's git revert (infrastructure rollback), assumes blue/green or canary are alternative ways of doing the same thing, just "more advanced." Why it happens: both use the word "rollback" at some point in their explanation. How to spot it: if you think you could replace git revert + apply.yml with "using blue/green" for Andes Cargo's HCL. How to fix it: they're two problems at different layers. Module 6's rollback reverts a declarative HCL commit — there's never "two versions of infrastructure running in parallel" at any point, the revert simply calculates a new plan. Blue/green solves, instead, how to move real traffic between two versions of an application artifact running simultaneously — a problem that only exists when there are active replicas serving users, something Terraform, in this guide, never had.

Believing Kubernetes "includes" blue/green and canary just like rolling (technical-expectation-based). What happens: someone, seeing Deployment has native strategy: RollingUpdate, assumes switching to strategy: BlueGreen would be just as direct. Why it happens: the three strategies get presented together in this lesson, as if they had the same level of support. How to spot it: if you look for a strategy: type: BlueGreen field in Kubernetes's Deployment documentation and don't find it. How to fix it: plain Kubernetes (the native Deployment resource) only includes rolling — blue/green and canary require an additional controller, like Argo Rollouts (which replaces Deployment with its own Rollout resource, the one you saw above) or Flagger, another tool with the same purpose. It's not a minor limitation: it's the reason these two strategies have their own tool ecosystem, instead of being a simple config change.

Thinking canary is always "better" than blue/green for being more gradual (value-judgment-based). What happens: someone concludes canary is, generally, the superior strategy because it reduces risk more finely than an instant switch. Why it happens: "gradual and finely controlled" sounds, intuitively, safer than "all or nothing." How to spot it: if your takeaway from this lesson is "always use canary." How to fix it: canary has a real cost blue/green doesn't — it needs time (the pause: duration between steps) and a reliable monitoring system to automatically decide whether the setWeight advances or reverts. For a very low-risk change, that cost might not be worth it against blue/green's, or even rolling's, simplicity. The right choice depends on the change's real risk, not a fixed hierarchy among the three.


Exercises

Exercise 1 — Explain why this guide never had this problem. Without looking at this lesson, explain in two or three sentences why terraform apply on andes-cargo-infra/ never needed a blue/green, canary, or rolling strategy.

See solution

A complete explanation sounds, roughly, like this: "These three strategies solve how to move real users' traffic between two versions of an application that are running simultaneously during the transition. terraform apply doesn't have that problem because it doesn't deploy an application's replicas — it modifies declared resources' state (a bucket, a table, an IAM role) all at once, with no intermediate phase where 'the bucket's old version' and 'the bucket's new version' coexist serving traffic in parallel. The problem these three strategies solve simply doesn't exist in Terraform's model as this guide used it."

Exercise 2 — Choose the right strategy for three scenarios. For each scenario, choose rolling, blue/green, or canary, and justify in one sentence: (a) a very low-risk configuration change on an internal service with no external users; (b) a large change to a critical application's payment system, with budget for duplicated infrastructure; (c) an experimental change to a recommendations algorithm, where the team wants to measure impact on a small group before deciding.

See solution

(a) Rolling — the risk is low, doesn't justify the extra cost of a second complete environment or canary's gradual monitoring complexity; the default gradual replacement is enough. (b) Blue/green — a critical payment system benefits from instant rollback (pointing back to the old environment, with no traffic mix at all during the transition) more than from any other property, and the scenario already assumes budget available for double the infrastructure. (c) Canary — the explicit goal is measuring impact on a small group before deciding, which is exactly what setWeight with incremental steps is designed to do; neither rolling nor blue/green offer that fine control of "how much traffic sees the new version, while I measure."

Exercise 3 — Locate a tool's technical name. What tool, named in this lesson, extends ArgoCD's GitOps capabilities specifically to support blue/green and canary on Kubernetes? Why does it make sense that it exists in the same family of projects as ArgoCD?

See solution

Argo Rollouts — a controller that replaces Kubernetes's native Deployment with its own Rollout resource, with explicit support for blue/green, canary, automatic metrics analysis, and progressive delivery. It makes sense that it lives in the same family of projects as ArgoCD (both under the CNCF's "Argo" umbrella) because they solve complementary problems in the same domain: ArgoCD syncs what manifests should exist in the cluster according to Git (pull-based GitOps, this module's lessons 3-4); Argo Rollouts controls how the transition happens when those manifests swap one application version for another (this lesson). They're commonly used together: ArgoCD detects the change in Git, and Argo Rollouts executes the gradual transition instead of a direct replacement.


Summary and next step

In this lesson you met, with verified syntax and without building anything, the three standard application deployment strategies: rolling (gradual replacement, native to Kubernetes), blue/green (two complete environments, instant traffic switch), and canary (a small traffic portion first, with gradual, measured increases). You understood why none of the three was ever needed in this guide —terraform apply doesn't deploy an application's replicas with real traffic in transit— and saw where they really get implemented: kubernetes-and-eks-in-production-guide for the Kubernetes world, aws-serverless-and-containers-guide for AWS's native serverless/container world.

Before moving on you should be able to: explain the central difference among the three strategies (traffic mix, rollback speed, cost); choose the right strategy for a given scenario with technical justification; and explain why Andes Cargo's pipeline never needed any of the three.

Lesson 6 takes a step back and systematizes, in a short, explicit table, the complete boundary between infrastructure CI/CD (what you built) and application code CI/CD (what this lesson and the previous one started to show) — the contrast lesson 7 makes tangible with a real, executed pipeline.

Resources

  1. Kubernetes Docs — Deployments, Rolling Update strategy — official documentation for RollingUpdate, maxSurge, and maxUnavailable, used in this lesson.
  2. Argo Rollouts — Documentation — official documentation for the tool that extends Kubernetes with blue/green and canary, the source for this lesson's Rollout YAML.
  3. AWS Whitepaper — Practicing Continuous Integration and Continuous Delivery on AWS, Deployment methods — the source for the blue/green definition quoted verbatim in this lesson.
  4. kubernetes-and-eks-in-production-guide (NIEVA) — where these three strategies really get implemented, alongside ArgoCD/Flux.
  5. aws-serverless-and-containers-guide (NIEVA) — these strategies' equivalent with native AWS tools (Lambda aliases, CodeDeploy) outside Kubernetes.