New to Kestra?
Use blueprints to kickstart your first workflows.
Schedule a backfillable SQL Server SQL report with Kestra, convert it to CSV, and email it as an attachment, skipping empty days and alerting Slack on failure.
Turn a daily SQL Server reporting query into an automated email without writing glue code or babysitting a SQL Server Agent job step. This blueprint runs an aggregate query against SQL Server on a schedule, converts the result to CSV, and emails it to stakeholders as an attachment. It skips the send entirely when a day has no data and posts a Slack alert if anything fails, so a missed morning report is never silent. It also stays fully backfillable: rerun any past day on demand without editing the flow.
io.kestra.plugin.core.trigger.Schedule trigger fires every morning at 06:00 UTC (cron: 0 6 * * *).daily_sales_report task (io.kestra.plugin.jdbc.sqlserver.Query) aggregates the report day's orders by region and stores the full result set in internal storage (fetchType: STORE). The day is bound as a :day prepared-statement parameter.email_when_data task (io.kestra.plugin.core.flow.If) checks outputs.daily_sales_report.size > 0.report_to_csv (io.kestra.plugin.serdes.csv.IonToCsv) converts the stored ION result to CSV and email_report (io.kestra.plugin.email.MailSend) emails it over SMTP with TLS as an attachment.log_no_data (io.kestra.plugin.core.log.Log) records that the day was empty instead of sending an empty attachment.errors block sends a io.kestra.plugin.slack.notifications.SlackIncomingWebhook alert with the execution id.The report day is derived from inputs.report_date (else the trigger or execution date minus one day) and rendered once into vars.report_day, which drives the SQL filter, the email subject, and the log line in lockstep.
report_date set, no code changes.SQL Server Agent can run a stored procedure or a T-SQL job step on a schedule, but it cannot convert results to CSV, branch on whether the result was empty, attach a file to an email over authenticated SMTP, or alert Slack when the job fails without extra Database Mail configuration and custom T-SQL. Kestra ties all of that together in one declarative YAML flow: a time trigger starts the run, the errors block guarantees failures surface, and every execution is captured with full logs and lineage you can replay. Because the date is parameterized, the same flow that runs nightly also backfills history.
dbo.orders table (created_at, region, total columns).Set these as Kestra secrets, never inline:
SQLSERVER_URL: JDBC URL, for example jdbc:sqlserver://host:1433;trustServerCertificate=true.SQLSERVER_USERNAME / SQLSERVER_PASSWORD: SQL Server credentials.SMTP_HOST, SMTP_USERNAME, SMTP_PASSWORD: SMTP relay credentials.REPORT_FROM_ADDRESS: sender address for the report email.REPORT_RECIPIENTS: recipient email address(es) for the report.SLACK_WEBHOOK_URL: the Slack incoming webhook URL the failure alert is posted to.dbo.orders has created_at, region, and total columns, or adjust the SQL.report_date set.