Atlas now manages Snowflake alerts as a schema object. Declare the condition and the action it takes, and Atlas inspects, diffs, and plans them with CREATE, ALTER, and DROP ALERT.
An alert runs a query on a schedule and executes an action when it returns a row, which makes it Snowflake's built-in way to watch data and react to it. Atlas now manages its full lifecycle: alerts are inspected, diffed, and planned like any other schema object, next to tasks and pipes.
Declaring an Alert
The new alert block requires a condition and an action, and accepts a schedule, a warehouse, a comment, and suspend_alert_after_num_failures:
alert "FAILED_JOBS" { schema = schema.PUBLIC schedule = "USING CRON 0 9 * * * UTC" warehouse = "OPS_WH" condition = "SELECT 1 FROM jobs WHERE status = 'failed'" action = "CALL notify_ops()" comment = "Alert on failed jobs" suspend_alert_after_num_failures = 5}
| Attribute | Notes |
|---|---|
| condition | Required. The query itself. Atlas wraps it in Snowflake's IF (EXISTS (...)) THEN form, so the attribute holds only the SELECT. |
| action | Required. The SQL that runs when the condition returns a row. |
| schedule | An interval such as 1 MINUTE, or a USING CRON expression. |
| warehouse | A reference to a warehouse block or a plain name. Leaving it out runs the alert serverless. |
| suspend_alert_after_num_failures | Consecutive failures after which Snowflake suspends the alert. |
| tag | Repeatable block associating a Snowflake tag with the alert, written inline on CREATE. |
Omitting warehouse is the common case, since a serverless alert needs no compute of its own:
alert "SERVERLESS_ALERT" { schema = schema.PUBLIC condition = "SELECT 1 FROM errors" action = "CALL notify()"}
Generated SQL
-- create alert "FAILED_JOBS"CREATE ALERT "PUBLIC"."FAILED_JOBS" SCHEDULE = 'USING CRON 0 9 * * * UTC' WAREHOUSE = "OPS_WH" COMMENT = 'Alert on failed jobs' SUSPEND_ALERT_AFTER_NUM_FAILURES = 5 IF (EXISTS (SELECT 1 FROM jobs WHERE status = 'failed')) THEN CALL notify_ops(); -- create alert "SERVERLESS_ALERT"CREATE ALERT "PUBLIC"."SERVERLESS_ALERT" IF (EXISTS (SELECT 1 FROM errors)) THEN CALL notify();
The condition and the action are altered in place, each in its own statement, and the schedule, warehouse, and comment are set and unset. Removing a schedule is the one change planned as a drop and a create, since Snowflake has no UNSET SCHEDULE. Every statement carries its inverse, so migrate down works.
-- modify the condition and the action in placeALTER ALERT "PUBLIC"."FAILED_JOBS" MODIFY CONDITION EXISTS (SELECT 2 FROM errors);ALTER ALERT "PUBLIC"."FAILED_JOBS" MODIFY ACTION CALL other(); -- the schedule, warehouse and comment are set and unsetALTER ALERT "PUBLIC"."FAILED_JOBS" SET SCHEDULE = '5 MINUTE' COMMENT = 'new';ALTER ALERT "PUBLIC"."FAILED_JOBS" UNSET WAREHOUSE;
Tags
Unlike an external access integration, CREATE ALERT takes an inline WITH TAG clause, so a tagged alert is created in one statement:
alert "FAILED_JOBS" { schema = schema.PUBLIC schedule = "1 MINUTE" condition = "SELECT 1 FROM errors" action = "CALL notify()" tag { ref = tag.OWNER value = "data-platform" }}
Getting Started
Alerts are opt-in. Enable them in the mode "snowflake" block of your env:
env "snow" { schema { mode "snowflake" { alerts = true } }}
A newly created alert is suspended until it is resumed. Atlas does not track that state, so an ALTER ALERT ... RESUME stays outside the desired state and never shows up as drift.
Snowflake support is part of Atlas Pro. Run atlas login to get started.