Skip to content

proposal: support blue/green deployments #33

Description

@atkrad

Problem

Rolling updates mix old and new pods under one Service. For risky releases, teams want a full new version (green) beside the live one (blue), smoke-test it, then flip traffic atomically, with instant abort by flipping back.

Deployah cannot express that today (one Deployment + RollingUpdate). Related: #19 (rolling knobs; blue/green explicitly out of scope there), #29 (Helm revision rollback, different mechanism).

Goals

  • Spec can select blue/green for a component (at least role: service).
  • v1: native Service-slot blue/green (two workloads + stable active Service + optional preview); no extra cluster controllers.
  • CLI for deploy inactive slot, promote, and abort.
  • Optional preview hostname for green before cutover.
  • Plan shows slots and which is active.
  • Document ~2x capacity during the window and backward-compatible data/migrations.

Non-goals

Proposed design

v1 — native Service slots (no controllers)

components:
  api:
    image: ghcr.io/acme/api:${TAG}
    role: service
    expose: true
    release:
      strategy: blueGreen          # rolling (default) | blueGreen
      # preview: true
      # autoPromote: false
deployah deploy production              # update inactive slot (green); wait ready
deployah release status production      # live slot + green readiness
deployah release promote production     # flip active Service to green
deployah release abort production       # keep/restore blue; drop or idle green
Object Role
Deployments (blue + green, or two named slots) Workload slots
Service …-active Selector = live slot; expose / Ingress targets this
Service …-preview (optional) Points at green for smoke tests
Public FQDN Stays on active Service (hostname guard unchanged)

Flow: deploy → ready green (blue still live) → promote (selector flip, optional scale-down delay) or abort.

Phase 2 — Argo Rollouts / Flagger (optional)

# deployah.platform.yaml
environments:
  production:
    progressiveDelivery:
      provider: argoRollouts    # none | argoRollouts | flagger

Emit Rollout/Flagger objects only when CRDs exist (capability check). Local kind keeps provider: none / native slots. Shared with canary (#34) progressiveDelivery design.

Interactions

Concern Behavior
#19 rolling knobs Reject or ignore when strategy: blueGreen
#29 Helm rollback Still available; document abort vs revision rollback
#25 HPA/KEDA Define attachment to live vs both slots
Mesh #23/#24 v1 stays Service/Ingress flip
Promote scope v1: per-component

Failure modes

  • Promote while green not ready → error.
  • Overlapping dirty slots → error or --force.
  • Insufficient capacity for 2x → scheduling failure; document.

Alternatives considered

  1. Rolling + proposal: support deployah rollback #29 only — no preview / instant traffic flip.
  2. Argo-only v1 — breaks zero-install local story.
  3. Hand-built via extras / proposal: Kustomize post-renderer for generated manifests #31 — not Spec-to-Release.
  4. Two Helm releases — doubles ownership complexity.

Compatibility and migration

Test plan

  • Generator: two slots + active/preview Services
  • Scenario goldens
  • Manual: preview → promote → abort on kind
  • Docs: rolling vs blue/green; capacity and migrations

Checklist

  • I searched existing issues and discussions
  • This includes enough design detail for implementation (not only a wish)

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/deployDeploy and plan session flowarea/helmChart render, release, post-renderarea/specdeployah.yaml schema or loadingkind/proposalDesign discussion before or during implementationneeds-triageNew, not yet categorized

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions