CLI icon
If icon
SlackIncomingWebhook icon
Fail icon
Log icon

Pre-Deploy Gate with Liquibase Validate and Status

Gate deployments with Liquibase validate and status in Kestra. Capture exit codes, block the release on broken or unapplied changelogs, and alert Slack.

Categories
DataInfrastructure

Deploying application code on top of a broken or half-applied database migration is how ordinary releases become incidents. This blueprint puts a gate in front of the deploy: io.kestra.plugin.liquibase.CLI runs liquibase validate to prove the changelog is well formed and liquibase status --verbose to check whether unapplied change sets remain, converts both results into task outputs, and fails the execution with a Slack alert when either check is unhealthy. A pipeline that waits on this flow gets a hard stop instead of a hopeful green light.

How it works

  1. check_migrations (io.kestra.plugin.liquibase.CLI) receives the changelog through inputFiles and connects using the standard Liquibase environment variables filled from Kestra secrets.
  2. liquibase validate runs first with its exit code captured through a shell || fallback, so a broken changelog is recorded rather than aborting the script. liquibase status --verbose then writes the pending-changes report, and a grep for the up-to-date marker turns it into a numeric flag.
  3. Both values are emitted through Kestra's output protocol, becoming {{ outputs.check_migrations.vars.validate_exit }} and {{ outputs.check_migrations.vars.pending }}.
  4. gate (io.kestra.plugin.core.flow.If) checks both outputs. On failure it posts the reason to Slack, then io.kestra.plugin.core.execution.Fail fails the execution. On success, a Log task records the green light.
  5. The errors block alerts separately when the gate itself cannot run, because an unverifiable migration state should also block the deploy.

What you get

  • A deployment gate that distinguishes three states: valid and applied, broken, and not yet applied.
  • Exit codes and pending-changes flags as first-class flow outputs, usable by any downstream task or pipeline.
  • A Slack message that states why a deploy was blocked, with the numbers to prove it.
  • Full validate and status logs preserved in the execution for debugging.

Who it's for

  • Release engineers who have shipped code against a database that was one migration behind.
  • Database administrators enforcing that changelogs are validated before anyone touches production.
  • Teams wiring Kestra flows into CI pipelines that need a binary deploy or do-not-deploy answer.

Why orchestrate this with Kestra

The Liquibase commands are one-liners, but a gate is more than commands: exit codes must survive the shell, the pass and fail paths must diverge, someone must be told why a deploy stopped, and the whole decision must be auditable later. Kestra's output protocol carries the shell results into flow logic, the If and Fail tasks make the decision explicit, and every gate decision lives in the execution history next to the release it protected.

Prerequisites

  • A database reachable from the Kestra worker. For a zero-dependency demo, set the DB_URL secret to jdbc:h2:file:./demo-db with username sa and an empty password. Note that a fresh H2 file starts empty, so the demo shows the gate blocking on pending changes, which is the interesting path. For production, use your real JDBC URL, such as jdbc:postgresql://db-host:5432/app.
  • A Slack incoming webhook for gate decisions and alerts.

Secrets

  • DB_URL: JDBC URL of the target database.
  • DB_USERNAME: database username.
  • DB_PASSWORD: database password.
  • SLACK_WEBHOOK_URL: Slack incoming webhook URL.

Quick start

  1. Add the four secrets to your Kestra namespace, using the H2 URL above if you just want to see it run.
  2. Execute the flow; on an empty database the gate blocks with a pending-changes flag of 1 and Slack explains why.
  3. Apply the changelog with the migrate-on-release blueprint, re-run this flow, and watch the gate pass.

How to extend

  • Call this flow from your CI pipeline before the deploy step and treat a failed execution as a blocked release.
  • Chain it with io.kestra.plugin.core.flow.Subflow so the gate, the migration, and the deploy live in one parent flow.
  • Relax the gate to warn-only for pending changes by moving the pending check into a Slack-only branch.
  • Swap the inline changelog for namespaceFiles synced from Git so the gate always validates the changelog that will actually ship.

Links

Orchestrate with Kestra
Orchestrate Slack with Kestra
Share this Blueprint
See How

New to Kestra?

Use blueprints to kickstart your first workflows.