Schedule icon
Webhook icon
Script icon
If icon
SlackIncomingWebhook icon
Log icon
OutputValues icon

Automate Apache Iceberg Table Maintenance and Snapshot Expiry via REST Catalog

Maintain Apache Iceberg tables via REST catalog in Kestra. Expire snapshots, prune orphan files with PyIceberg, and report reclaimed storage to Slack.

Categories
Data

Continuous streaming ingestion and microbatch writes into Apache Iceberg tables produce thousands of small metadata manifests and snapshot logs over time. Without regular Day-2 table maintenance, query planning performance degrades in engines like Trino, DuckDB, Snowflake, and Spark, and storage costs climb from abandoned historic snapshots. This blueprint automates Apache Iceberg table maintenance by connecting directly to an Iceberg REST Catalog using PyIceberg, enforcing retention policies to expire stale snapshots, and dispatching an audit summary to Slack.

How it works

  1. A weekly Schedule trigger (weekly_maintenance_sweep) runs the maintenance audit during off-peak weekend hours (Sunday at 02:00 UTC), while an authenticated Webhook trigger (on_demand_webhook) allows upstream transformation jobs (e.g. dbt or Apache Spark) to trigger table cleanup immediately following batch ingestion.
  2. audit_and_maintain_iceberg_table (io.kestra.plugin.scripts.python.Script) runs an isolated Python container with pyiceberg, initializes a connection to the target REST Catalog using the catalog URI and authentication token, and inspects the live metadata for table_identifier.
  3. The script evaluates historical snapshots against the snapshot_retention_days threshold while enforcing max_snapshots_to_retain as a safety guard to ensure sufficient point-in-time recovery versions remain active.
  4. For qualified snapshots, table.manage_snapshots().expire_snapshot(...) commits metadata updates, retiring expired snapshot records and freeing underlying storage.
  5. evaluate_maintenance_impact (io.kestra.plugin.core.flow.If) evaluates whether any snapshots were expired:
    • If snapshots were retired (snapshots_expired > 0), notify_slack_maintenance_success (io.kestra.plugin.slack.notifications.SlackIncomingWebhook) sends a Slack Block Kit card summarizing the table name, expired snapshot count, and execution duration.
    • If the table was already clean, log_table_optimized records a confirmation log.
  6. output_maintenance_summary (io.kestra.plugin.core.output.OutputValues) exposes typed execution variables for downstream observability or catalog sync jobs.
  7. An errors block intercepts catalog connection drops or expired tokens, sending an emergency notification to the #lakehouse-ops Slack channel.

What you get

  • Automated metadata optimization preventing query planning slowdowns across distributed engines.
  • Guaranteed retention enforcement with a minimum snapshot safety threshold preventing accidental data loss.
  • Vendor-neutral REST catalog compatibility supporting Apache Polaris, Project Nessie, Tabular, and Snowflake Open Catalog.
  • Formatted Slack notifications providing immediate operational visibility into reclaimed storage.

Who it's for

  • Data Platform Engineers operating Apache Iceberg lakehouses in production.
  • Data Engineers looking for automated, serverless table maintenance without managing dedicated Spark clusters.
  • FinOps teams managing and minimizing cloud object storage expenditure across historical lakehouse snapshots.

Why orchestrate this with Kestra

Performing table maintenance through custom cron scripts often results in silent failures, unmasked tokens in logs, and a lack of audit visibility. Kestra provides declarative YAML flow definitions, containerized Python task execution, unified secret management ({{ secret(...) }}), and automatic retry handling. With built-in schedule and webhook triggers, teams can automate maintenance across dozens of tables without deploying heavy cluster infrastructure.

Prerequisites

  • A running Apache Iceberg REST Catalog (e.g. Apache Polaris, Project Nessie, AWS Glue REST, or Tabular).
  • An S3-compatible cloud storage bucket (AWS S3, MinIO, or Google Cloud Storage) housing Iceberg data and metadata files.
  • A Kestra worker enabled to execute Docker containers.

Secrets

Configure the following secrets in your Kestra namespace:

  • ICEBERG_REST_TOKEN: Bearer authentication token for the Iceberg REST Catalog.
  • AWS_ACCESS_KEY_ID: IAM access key with read/write access to the table warehouse bucket.
  • AWS_SECRET_ACCESS_KEY: IAM secret key.
  • AWS_REGION: Cloud storage region (e.g., us-east-1).
  • S3_ENDPOINT: Custom S3 endpoint URL (only needed when using MinIO or Ceph).
  • SLACK_WEBHOOK_URL: Slack Incoming Webhook URL for lakehouse audit reports.
  • WEBHOOK_KEY: Secret authentication key for triggering maintenance via HTTP Webhook.

Quick start

  1. Configure the required secrets (ICEBERG_REST_TOKEN, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, SLACK_WEBHOOK_URL) in your Kestra namespace.
  2. Import this blueprint into your Kestra instance.
  3. Update the catalog_uri, warehouse_location, and table_identifier inputs to match your environment.
  4. Click Execute to run an initial maintenance pass and verify catalog connectivity in the task logs.
  5. Enable the weekly_maintenance_sweep trigger to automate table lifecycle management.

How to extend

  • Loop over an entire catalog namespace using io.kestra.plugin.core.flow.ForEachItem to maintain all tables in a single execution.
  • Add partition bin-pack file compaction using PySpark or DuckDB after snapshot expiration.
  • Upload an audit log artifact to Amazon S3 using io.kestra.plugin.aws.s3.Upload for long-term compliance records.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.