Diff icon
Script icon
Process icon
If icon
DiscordIncomingWebhook icon
Schedule icon

Nightly Schema Drift Detection with Liquibase Diff

Detect schema drift nightly with the Kestra Liquibase Diff task. Compare live and reference databases, capture a diff changelog, and alert Discord on drift.

Categories
DataInfrastructure

Schema drift is the gap between the database you think you have and the one production is actually running, a hotfix column added by hand, an index dropped during an incident, a migration applied to staging but never to production. This blueprint makes drift measurable: every night io.kestra.plugin.liquibase.Diff compares the live database against a reference database, writes the differences as a Liquibase changelog artifact, and a small Python step reduces that artifact to a drift boolean that gates a Discord alert. No drift, no noise.

How it works

  1. diff_schemas (io.kestra.plugin.liquibase.Diff) connects to the live database through url and to the baseline through referenceUrl, with all credentials pulled from Kestra secrets. Because changelogFile is set, the task runs diff-changelog and writes every difference as a change set in drift.xml, which outputFiles uploads to internal storage.
  2. detect_drift (io.kestra.plugin.scripts.python.Script on the Process runner) pulls drift.xml in through inputFiles, counts the changeSet entries, and emits drift and changes as task outputs through Kestra's output protocol.
  3. alert_on_drift (io.kestra.plugin.core.flow.If) posts to Discord only when drift is true, including the change count and a pointer to the generated changelog.
  4. The errors block sends a distinct alert when the comparison itself fails, so a broken connection is never mistaken for a clean diff.
  5. A disabled-by-default Schedule trigger runs the check nightly at 02:00.

What you get

  • A nightly, auditable answer to the question every incident review asks: does production still match the schema we designed.
  • The drift itself as a ready-to-review Liquibase changelog artifact, not just a yes or no.
  • A drift boolean and change count as flow outputs, ready to gate deployments or feed dashboards.
  • Alerts only on divergence, so the channel stays readable.

Who it's for

  • Database administrators who suspect hand-applied hotfixes are accumulating in production.
  • Platform teams keeping staging, production, and disaster recovery databases structurally identical.
  • Anyone adopting Liquibase on an existing database who wants to know when reality diverges from the changelog.

Why orchestrate this with Kestra

Liquibase can compute a diff, but drift detection is only useful as a routine: run every night, keep every artifact, alert only when something changed, and page someone when the check itself breaks. Kestra provides the schedule, the internal storage that preserves each night's diff for later review, the conditional alerting, and the error handling, all declared in one flow instead of a cron entry plus three shell scripts.

Prerequisites

  • Two databases reachable from the Kestra worker: the live target and the reference baseline. For a zero-dependency demo, set both URL secrets to H2 file databases such as jdbc:h2:file:./live-db and jdbc:h2:file:./reference-db with username sa and an empty password. For production, use your real JDBC URLs, for example jdbc:postgresql://prod-host:5432/app against jdbc:postgresql://staging-host:5432/app.
  • Python available on the worker for the Process-runner script, or switch its taskRunner to Docker.
  • A Discord incoming webhook for alerts.

Secrets

  • DB_URL, DB_USERNAME, DB_PASSWORD: connection for the live database.
  • REFERENCE_DB_URL, REFERENCE_DB_USERNAME, REFERENCE_DB_PASSWORD: connection for the reference database.
  • DISCORD_WEBHOOK_URL: Discord incoming webhook URL.

Quick start

  1. Add the seven secrets to your Kestra namespace, using the H2 URLs above if you just want to see it run.
  2. Execute the flow; with two empty H2 databases the diff is clean and Discord stays silent.
  3. Point the secrets at your real databases, review one generated drift.xml, and enable the nightly trigger.

How to extend

  • Feed the generated changelog into a remediation flow that applies it to the drifted database after human approval.
  • Store the nightly change count in a warehouse table to chart drift over time.
  • Compare production against the changelog-defined schema by pointing referenceUrl at a database freshly built by liquibase update, as in the changelog CI validation blueprint.
  • Fail the execution on drift with io.kestra.plugin.core.execution.Fail if you want drift to block a deployment pipeline.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.