New to Kestra?
Use blueprints to kickstart your first workflows.
Sample an Amazon SQS queue on a schedule without deleting messages and alert Slack when backlog crosses warning or critical thresholds.
An Amazon SQS backlog can build for minutes before anyone notices, since SQS itself has no built-in alerting on depth. This blueprint turns a scheduled, non-destructive sample into a Day 2 health gate: io.kestra.plugin.aws.sqs.Consume reads up to critical_queue_depth messages with autoDelete disabled, so nothing sampled here is ever permanently removed, classifies the count against two thresholds, and routes the result to a quiet log, an informational Slack note, or a Slack page depending on severity.
probe_queue_depth (io.kestra.plugin.aws.sqs.Consume) polls queue_url in aws_region for up to probe_duration, stopping early at critical_queue_depth messages. autoDelete: false means every sampled message stays in the queue and simply becomes visible again to real consumers after sample_visibility_timeout seconds, instead of being deleted. allowFailure: true keeps a connection or permissions failure from aborting the flow outright.classify_queue_depth (io.kestra.plugin.core.debug.Return) evaluates a single Pebble expression against the sampled count: missing entirely becomes UNREACHABLE, at or above critical_queue_depth becomes CRITICAL, at or above warning_queue_depth becomes WARNING, otherwise HEALTHY.route_by_depth (io.kestra.plugin.core.flow.Switch) branches on that classification: HEALTHY logs a quiet confirmation; WARNING posts an informational Slack note; CRITICAL and UNREACHABLE each page Slack with the sampled count, the configured thresholds, and the execution id; a defaults fallback logs the raw value for any classification outside the four known cases.log_audit_result (io.kestra.plugin.core.log.Log) writes one audit line per run, independent of which Switch branch fired, so the check's own history stays queryable even if Slack delivery fails.errors block pages Slack separately if the flow fails outright, so a broken sentinel is never mistaken for a quiet queue.queue_depth_schedule trigger samples every 10 minutes and ships disabled: true, with explicit inputs: overrides for probe_duration and sample_visibility_timeout so the scheduled run's probe window is pinned regardless of this flow's own defaults.status output (HEALTHY / WARNING / CRITICAL / UNREACHABLE) other flows can gate on.CloudWatch can alarm on ApproximateNumberOfMessagesVisible, but that lives outside your flow logic in a separate alarm resource with its own actions to wire up. Kestra keeps the whole check in one place: the schedule, the non-destructive sample, the threshold classification, and the Slack call are all one auditable execution history, with the Switch branch ready to grow into real remediation (fanning out more consumers, opening a ticket) without rewriting the check itself.
queue_url.sqs:ReceiveMessage permission on that queue (and nothing else, since autoDelete: false never calls DeleteMessage).AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY: AWS credentials used to sample the queue.SLACK_WEBHOOK_URL: Slack incoming webhook used for every alert branch and the flow-failure alert.In Kestra OSS (no Enterprise secrets backend), secrets are supplied as environment variables prefixed SECRET_, base64-encoded, and read back in flows with {{ secret('NAME') }}, for example SECRET_SLACK_WEBHOOK_URL=$(echo -n 'https://hooks.slack.com/services/<placeholder>' | base64). This keeps credentials out of the flow YAML but, per Kestra's own documentation, offers no encryption at rest or access control beyond the host environment; use the Enterprise secrets backend for stronger guarantees.
docker run -d --name localstack -p 4566:4566 localstack/localstack:latestdocker network connect YOUR_KESTRA_NETWORK localstackdocker exec localstack awslocal sqs create-queue --queue-name orders
docker exec localstack awslocal sqs send-message --queue-url http://localhost:4566/000000000000/orders --message-body "test"AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY (LocalStack accepts any non-empty placeholder values, e.g. test/test) and SLACK_WEBHOOK_URL as secrets, set queue_url to the LocalStack queue URL, and run the flow once manually to confirm status reads HEALTHY.queue_depth_schedule once pointed at a real queue.queue_url/aws_region to a live queue; no code change is needed for the non-LocalStack path.endpointOverride property to probe_queue_depth pointing at your emulator; leave it unset for real AWS rather than templating it to an empty string.info_queue_depth tier if you want a Slack note on any non-zero backlog, not just at the warning threshold.status into a KV store and alert only on state transitions instead of every run.queue_url: full URL of the SQS queue to sample.aws_region: AWS region the queue lives in.probe_duration: ISO-8601 duration cap on how long the sampling task runs.sample_visibility_timeout: seconds a sampled message stays hidden before returning to visibility.warning_queue_depth: floor at or above which the queue is classified WARNING.critical_queue_depth: floor at or above which the queue is classified CRITICAL, and the sampling task's maxRecords cap.status: one of HEALTHY, WARNING, CRITICAL, UNREACHABLE.ApproximateNumberOfMessagesVisible attribute; under concurrent consumers or overlapping runs the sampled count can undercount the true backlog.warning_queue_depth or critical_queue_depth too low relative to real traffic produces false alerts; tune both against an observed healthy baseline before enabling the schedule.autoDelete: false is what makes this check non-destructive; changing it to true turns this monitor into a consumer that permanently removes the messages it samples.sample_visibility_timeout short. A long timeout hides sampled messages from real consumers for that entire window even though they are never deleted.endpointOverride to an empty string to "optionally" support LocalStack; only add the property when actually targeting a non-AWS endpoint.