New to Kestra?
Use blueprints to kickstart your first workflows.
Automated data lakehouse schema guard workflow using DuckDB parquet_schema to detect dropped columns and data type shifts, alerting Slack.
Diagram unavailable
We could not build the topology for this blueprint. The flow itself is valid, use the YAML on the left to run it.
In modern cloud data lakehouses (built on S3, Google Cloud Storage, or Azure Blob Storage), upstream services continuously land daily or hourly Parquet partitions. Unannounced schema changes made by application developers—such as renaming a column, altering an integer field to a string, or dropping a required dimension—silently break downstream analytics engines, BI dashboards, and dbt models.
Because Parquet embeds metadata in each file's footer, inspecting schema drift without loading multi-gigabyte datasets into memory is challenging.
This blueprint implements an automated lakehouse schema contract gate using in-memory DuckDB. Executing daily or upon partition landing, it calls the native parquet_schema() table function across target and baseline partitions, performs a full outer join on column metadata, and categorizes differences as DROPPED_COLUMN, NEW_COLUMN, or DATA_TYPE_MUTATION. If breaking changes are found, it dispatches an immediate alert to Slack.
daily_schema_audit trigger (io.kestra.plugin.core.trigger.Schedule) executes daily at 07:00 UTC or on-demand via the Kestra UI.audit_parquet_schema_drift task (io.kestra.plugin.jdbc.duckdb.Query) loads the parquet and httpfs extensions, reads file footers via parquet_schema(), and joins column metadata to classify structural changes.evaluate_schema_breaking_changes flowable task (io.kestra.plugin.core.flow.If) evaluates whether any breaking column deviations exist.notify_data_engineering_slack (io.kestra.plugin.slack.notifications.SlackIncomingWebhook) posts an alert with column names, expected vs. actual types, and remediation guidance.log_compliant_schema records verification in execution logs.export_schema_manifest task records contract verification metadata for pipeline lineage records.fail_on_new_columns.Validating Parquet schemas across cloud object storage typically requires heavy Spark jobs or custom Python scripts. Kestra combines serverless workflow orchestration with DuckDB's in-process analytical power: it inspects remote Parquet files over HTTP/S3, executes fast metadata queries, branches conditionally, and dispatches structured alerts with minimal compute overhead.
| Name | Type | Default | Description |
|---|---|---|---|
target_parquet_uri |
STRING | https://huggingface.co/datasets/... |
URI or path to the freshly landed daily Parquet partition. |
baseline_parquet_uri |
STRING | https://huggingface.co/datasets/... |
URI or path to the validated baseline Parquet file. |
fail_on_new_columns |
BOOLEAN | false |
If false, new columns are permitted; if true, any additive column triggers an alert. |
slack_channel |
STRING | #data-governance |
Slack channel destination for schema drift alerts. |
{{ outputs.audit_parquet_schema_drift.rows }}: Array of drifting column records containing column_name, expected_type, actual_type, and drift_status.{{ outputs.audit_parquet_schema_drift.size }}: Total number of schema breaking changes detected.{{ outputs.evaluate_schema_breaking_changes }}: Result of conditional branch evaluation.{{ outputs.export_schema_manifest.value }}: Structured JSON audit manifest recording verification timestamp and contract status.AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) in DuckDB secrets.SLACK_WEBHOOK_URL: Slack Incoming Webhook endpoint URL used for sending alert notifications.SLACK_WEBHOOK_URL in your Kestra namespace secrets.httpfs extension to read remote URLs over HTTPS or S3. The query automatically includes INSTALL httpfs; LOAD httpfs;.INT64 with logical timestamp). DuckDB exposes the unified SQL type representation for clean comparisons.SET s3_region = '...'; SET s3_access_key_id = '...'; commands to the query preamble.io.kestra.plugin.aws.s3.List to automatically discover the latest partition file in an S3 prefix and compare it against the preceding partition.