New to Kestra?
Use blueprints to kickstart your first workflows.
File driven Kestra ETL that detects new S3 objects, batch inserts each file into Postgres in parallel, runs dbt transformations, and sends Slack alerts on failure.
Turn an S3 bucket into the front door of your warehouse. This Kestra blueprint polls a bucket prefix for new files, and whenever objects land it loads each one into Postgres with an efficient batch insert, then runs your dbt project to transform the raw rows into analytics ready models. Concurrency control keeps runs from stepping on each other, automatic retries absorb transient database hiccups, and a flow level error handler posts to Slack the moment anything breaks.
s3 trigger (io.kestra.plugin.aws.s3.Trigger) checks the etl-demo- prefix of the bucket every minute. Detected objects are downloaded into Kestra's internal storage and then deleted from the bucket (action: DELETE) so files are processed exactly once.concurrency with behavior: QUEUE and limit: 1 serializes executions, so overlapping trigger fires queue instead of racing on the same tables.each task (io.kestra.plugin.core.flow.ForEach) iterates over trigger.objects with concurrencyLimit: 2, processing two files at a time.jsonToIon (io.kestra.plugin.serdes.json.JsonToIon) normalizes the JSON, then insert_raw_data (io.kestra.plugin.jdbc.postgresql.Batch) streams the rows into raw_events with a parameterized insert.dbt task (io.kestra.plugin.dbt.cli.Run) executes dbt run in the ghcr.io/kestra-io/dbt-postgres container, reading your dbt project from namespace files and injecting connection details from secrets into profiles.retry policy retries any failed task up to three times, and the errors branch fires io.kestra.plugin.slack.notifications.SlackIncomingWebhook if the run still fails.A homegrown version of this needs an S3 poller, a queue, a loader, a dbt scheduler, and alerting glue. Kestra provides all of it declaratively: the S3 trigger handles detection and cleanup, ForEach handles fan out with bounded parallelism, flow concurrency prevents overlapping runs, and retries and error handling are flow level policies rather than code. Every file, insert, and dbt log line is visible in one execution view.
my-landing-bucket) receiving JSON files under the configured prefix. Note that action: DELETE removes processed files, switch to MOVE if you need an archive.AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY: credentials for the S3 trigger.JDBC_CONNECTION_STRING, PG_USERNAME, PG_PASSWORD, PG_HOST, PG_PORT: Postgres connection for the batch insert and the dbt profile.SLACK_WEBHOOK: incoming webhook URL for failure alerts.profiles block with your dbt_project.yml name.io.kestra.plugin.dbt.cli.Test after the run to gate downstream consumers on dbt tests.action: DELETE for MOVE with a moveTo prefix to keep an archive of processed files.concurrencyLimit for high file volumes, or remove flow concurrency if runs are independent.io.kestra.plugin.core.flow.Switch.