Progressive delivery see history edit this page

Talks about: , , , , and

StageSet integrates with both progressive-delivery controllers: Flagger and Argo Rollouts. The controller exposes a read-only gate endpoint and a readiness gauge so either one can hold a promotion until a StageSet stage is healthy; ready checks let a stage wait on a Rollout in return. Pick the section for your controller below — see also StageSet vs Argo Rollouts.

The gate contract

The gate endpoint backs the Flagger integration and the Argo Rollouts JSON-metric option.

GET /gate/{namespace}/{stageset}/{stage}
  200  — the stage is Ready at the currently pinned revision
  403  — the stage is not Ready (or not found / not gateable)

It is served on --gate-bind-address (default :8082) and exposed by the chart’s stageset-controller-gate Service (gate.enabled, on by default). The endpoint is unauthenticated and read-only, so fence it with a NetworkPolicy (production) to admit only your delivery controller.

Flagger

Add a confirm-promotion (or confirm-rollout) webhook to a Flagger Canary pointing at the gate. Flagger blocks the promotion until the gate returns 200:

apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
  name: web
  namespace: apps
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web
  analysis:
    interval: 1m
    threshold: 5
    stepWeight: 10
    maxWeight: 50
    webhooks:
      - name: stageset-stage-ready
        type: confirm-promotion
        # gate this canary's promotion on a StageSet stage being Ready
        url: http://stageset-controller-gate.stageset-system:8082/gate/apps/web/web

This is independent of the Flagger strategy: the same webhook gates a weighted canary, an A/B test (header/cookie routing), or a blue-green promotion — the gate only answers “is this stage Ready,” and Flagger decides what to do with that answer.

This coordinates two moving parts: Flagger shifts traffic to a new version only once a StageSet stage that applied the supporting config (a CRD, a migration, a sibling component) reports Ready.

Argo Rollouts

Argo Rollouts gates on analysis metrics (a query that returns a value to compare) rather than a webhook’s HTTP status, so the controller meets it on its own terms in two ways.

The controller exports stageset_stage_ready{namespace,stageset,stage} (1 when the stage is Ready, 0 otherwise). Argo’s Prometheus metric provider gates on it directly — no gate endpoint, no Job:

apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
  name: stageset-stage-ready
  namespace: apps
spec:
  metrics:
    - name: stage-ready
      successCondition: result == 1
      provider:
        prometheus:
          address: http://prometheus.monitoring:9090
          query: max(stageset_stage_ready{namespace="apps",stageset="web",stage="web"})

Gate on the JSON endpoint

The same gate endpoint also answers JSON when asked (Accept: application/json), returning {"ready": true, …} with a 200 so Argo’s web metric can parse it (Argo treats a non-2xx as an error, so readiness has to live in the body):

spec:
  metrics:
    - name: stage-ready
      successCondition: "result.ready == true"
      provider:
        web:
          url: http://stageset-controller-gate.stageset-system:8082/gate/apps/web/web
          headers:
            - key: Accept
              value: application/json
          jsonPath: "{$}"

A Job-based metric (curl -fsS … against the gate, succeeding only on 200) is the fallback when the analysis has no Prometheus or web access.

The reverse direction: gate a StageSet on a Rollout

The coordination also works the other way. Because ready checks accept CEL, a StageSet stage can wait on an Argo Rollout finishing its own progressive rollout before the next stage runs:

readyChecks:
  exprs:
    - apiVersion: argoproj.io/v1alpha1
      kind: Rollout
      current: "status.phase == 'Healthy'"
      inProgress: "status.phase in ['Progressing', 'Paused']"
      failed: "status.phase == 'Degraded'"

So StageSet can gate Argo (via the gauge/gate) and Argo’s outcome can gate StageSet (via ready checks) — pick whichever direction your release needs.