Subflow icon
Return icon
SlackIncomingWebhook icon

Staged Patch Orchestration from UAT to Production

Orchestrate staged VM patching with Kestra. UAT is patched and validated first; production proceeds only on success, with rollback and Slack reporting.

Categories
Infrastructure

Never let a patch reach production before UAT proves it. This orchestrator calls a patching subflow against the UAT VM, where the patch is applied over SSH, a human validates it, and a rejection or failure triggers automatic rollback. Only when UAT reports actionPerformed: PATCH with actionState: SUCCESS does the same subflow run against the production VM. The final Return task assembles a per-stage summary (applied or not, and why) that is posted to Slack and exposed as a flow output.

How it works

  1. The patchId input is a SELECT whose options come from a KV-stored list via expression: {{ kv('approvedPatches') }}, so operators can only pick patches your team has pre-approved.
  2. The processUatVM task (io.kestra.plugin.core.flow.Subflow with wait: true and transmitFailed: true) runs the companion ssh-patch-vm-approval-rollback flow against the UAT VM. That subflow patches, pauses for validation, and rolls back on rejection.
  3. The processProdVM task uses runIf on the UAT subflow's outputs: production is patched only when UAT performed a patch (not a rollback) and its state is SUCCESS.
  4. The logResult task (io.kestra.plugin.core.debug.Return) renders the two-stage summary with a Pebble {% if %} block that marks production as "Stage Skipped" when UAT did not validate.
  5. The notifyResult task (io.kestra.plugin.notifications.slack.SlackIncomingWebhook) posts the summary, and the result flow output returns it to any caller.

What you get

  • A hard promotion gate between UAT and production patching.
  • Human validation and automatic rollback inherited from the patching subflow.
  • A curated patch list managed in the KV store, not free-text input.
  • A single summary artifact per rollout in Slack and in flow outputs.

Who it's for

  • IT operations teams enforcing staged change management for OS patches.
  • SREs who want the UAT verdict, not optimism, to decide production changes.
  • Teams composing reusable patching logic across many environments.

Why orchestrate this with Kestra

Staged rollouts require carrying state across environments: what was applied, whether a human validated it, and what happened on rollback. Kestra subflows return typed outputs that the orchestrator consumes in runIf conditions, giving you promotion logic as declarative YAML instead of brittle glue scripts. Every stage is a separate execution with its own logs, retries, and approval trail.

Prerequisites

  • The companion blueprint ssh-patch-vm-approval-rollback deployed in the same namespace (adjust flowId if renamed).
  • SSH access to the UAT and production VMs (the subflow uses SSH_VM_USER and SSH_VM_PASSWORD secrets).
  • A KV entry approvedPatches containing the list of patch identifier strings.

Secrets

  • SLACK_WEBHOOK_URL: Slack incoming webhook for the rollout summary (the subflow also uses it for approval notifications).

Quick start

  1. Deploy the patching subflow blueprint, then this orchestrator, in the same namespace.
  2. Store your approved patch strings in the KV store under approvedPatches.
  3. Execute with your UAT and production VM names and a selected patch.
  4. Validate UAT when the subflow pauses; watch production proceed or stay skipped.

How to extend

  • Add more stages (dev, staging, canary pools) as additional Subflow calls with chained runIf conditions.
  • Fan production out across a fleet with io.kestra.plugin.core.flow.ForEach around the prod subflow.
  • Record each rollout summary to a database for patch compliance reporting.
  • Schedule monthly patch windows with a io.kestra.plugin.core.trigger.Schedule trigger.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.