New to Kestra?
Use blueprints to kickstart your first workflows.
Trigger a Kestra pipeline on new S3 files, ingest them into an Apache Iceberg table with Python, then MERGE and OPTIMIZE the data using Amazon Athena.
Build an event-driven data lake ingestion pipeline on AWS that reacts the moment new files land in Amazon S3. Instead of polling on a fixed schedule or running batch jobs that miss fresh data, this blueprint watches an S3 prefix, ingests each new object into an Apache Iceberg table with a Python script, and keeps the table consistent with Amazon Athena MERGE and OPTIMIZE statements. It solves the classic data lake problem of late, duplicated, and fragmented data by combining real-time S3 event detection with declarative, retryable orchestration.
io.kestra.plugin.aws.s3.Trigger watches the source_prefix of the S3 bucket on a PT1S interval, picks up new files (filter: FILES), and uses action: MOVE to relocate each detected object to the destination_prefix, guaranteeing exactly-once processing.io.kestra.plugin.core.flow.WorkingDirectory, the io.kestra.plugin.git.Clone task pulls the public kestra-io/scripts repository so the ingestion logic stays version controlled.io.kestra.plugin.scripts.python.Commands task runs etl/aws_iceberg_fruit.py on an io.kestra.plugin.scripts.runner.docker.Docker runner with awswrangler and kestra dependencies, passing the triggered object key (trigger.objects | jq('.[].key') | first) as the ingestion argument.io.kestra.plugin.aws.athena.Query runs a MERGE INTO against the Iceberg table to upsert rows, then a second Athena query runs OPTIMIZE ... REWRITE DATA USING BIN_PACK to compact files and keep query performance high.MOVE action so files are handled once.MERGE.OPTIMIZE.S3 and Athena have no native scheduler that can chain event detection, containerized Python, an upsert, and table optimization into one observable run. Kestra fills that gap: the S3 event trigger starts the flow declaratively, each task gets retries and full execution logs, lineage across ingest, merge, and optimize is captured end to end, and the entire pipeline is defined in version-controllable YAML rather than scattered scripts.
AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYAWS_DEFAULT_REGIONbucket, database, source_prefix, and destination_prefix variables to match your environment.raw_fruits staging table in Athena.aws_iceberg_fruit.py for your own ingestion script in the cloned repo.prefix and interval to match your file landing pattern.MERGE with your real schema and add partitioning to the OPTIMIZE step.