How to wire CloudWatch alarms through SNS and AWS Chatbot so your entire team gets real-time infrastructure alerts directly in Slack or Microsoft Teams with interactive response capabilities built in.
There's a version of cloud operations that many teams are still living in an alarm fires at 2am, the on-call engineer wakes up to 47 emails, opens three separate dashboards, and spends twenty minutes reconstructing what happened before even beginning to respond. The infrastructure was smart enough to detect the problem. The notification system failed everyone.
This project puts AWS alerts where your team already lives in Slack or Microsoft Teams. When a CloudWatch alarm changes state, AWS Chatbot delivers a formatted, interactive notification directly to the channel in seconds. The team sees it together, in context, and can respond without ever leaving the conversation.
This is ChatOps and AWS makes it achievable with two services and about 25 minutes of configuration.
"The fastest incident response starts with the right people seeing the right alert in the right place at the right time."
What Is ChatOps?
ChatOps is a collaboration model where infrastructure operations happen inside a team's chat platform. Instead of engineers pulling data from dashboards and sharing findings in chat, the operations themselves alerts, runbooks, acknowledgements, commands originate from within the chat. The channel becomes the control plane.
| Metric | Value |
|---|---|
| Faster incident response | 40β60% improvement with chat-based alerting |
| Cost of AWS Chatbot | $0 β you only pay for underlying SNS and CloudWatch |
| Estimated setup time | ~25 minutes |
| Scale | Thousands of notifications per second |
Architecture From Alarm to Slack in Four Hops
π CloudWatch Alarm (metric threshold breached) β π£ SNS Topic (publishes encrypted event) β π€ AWS Chatbot (formats message into rich card) β π¬ Slack / Microsoft Teams (team notified instantly)
CloudWatch monitors your infrastructure and detects threshold breaches. When an alarm changes state, it publishes a notification to an SNS topic. AWS Chatbot, subscribed to that topic, picks up the message, formats it into a rich card, and delivers it to your configured Slack channel within seconds.
What Makes AWS Chatbot More Than Just a Relay
Before diving into setup, it's worth understanding why AWS Chatbot exists as a dedicated service rather than using a plain SNS HTTP subscription pointing at a Slack webhook. The capabilities it adds are significant:
-
Run AWS CLI commands from Slack β type
@aws describe-instancesdirectly in a channel and get the response without leaving the conversation - Custom interactive actions β buttons that trigger Lambda functions, acknowledge alerts, or launch CloudFormation stacks from a notification card
- Granular IAM guardrails β define exactly which AWS operations team members can invoke from chat
- Rich message formatting β alarm notifications rendered as structured cards, not raw JSON dumps
- Supports both Slack and Microsoft Teams β one AWS service, two enterprise chat platforms
π‘ From notifications to ChatOps: A basic SNS-to-Slack webhook tells you something happened. AWS Chatbot lets you respond to it without context-switching to another tool. That's the difference between being notified and being operational.
Step 1 β Set Up Your Environment
# Set environment variables
export AWS_REGION=$(aws configure get region)
export AWS_ACCOUNT_ID=$(aws sts get-caller-identity \
--query Account --output text)
# Generate unique resource names
RANDOM_SUFFIX=$(aws secretsmanager get-random-password \
--exclude-punctuation --exclude-uppercase \
--password-length 6 --require-each-included-type \
--output text --query RandomPassword)
export SNS_TOPIC_NAME="team-notifications-${RANDOM_SUFFIX}"
export ALARM_NAME="demo-cpu-alarm-${RANDOM_SUFFIX}"
echo "β
Environment ready for region: ${AWS_REGION}"
Step 2 β Create the SNS Topic With Encryption
This SNS topic is the central hub CloudWatch publishes to it, and AWS Chatbot subscribes to it. Create it with KMS encryption enabled from the start:
# Create SNS topic with server-side encryption
aws sns create-topic \
--name ${SNS_TOPIC_NAME} \
--attributes '{
"KmsMasterKeyId": "alias/aws/sns",
"DisplayName": "Team Notifications Topic"
}'
# Store the Topic ARN
export SNS_TOPIC_ARN=$(aws sns get-topic-attributes \
--topic-arn arn:aws:sns:${AWS_REGION}:${AWS_ACCOUNT_ID}:${SNS_TOPIC_NAME} \
--query 'Attributes.TopicArn' --output text)
echo "β
SNS topic created: ${SNS_TOPIC_ARN}"
π Why encrypt an SNS topic? SNS messages for CloudWatch alarms can contain sensitive operational details instance IDs, IP addresses, metric values, and account identifiers. The key
alias/aws/snsuses the AWS-managed key for SNS, which incurs no extra cost beyond standard KMS API calls.
Step 3 β Connect Slack to AWS Chatbot
AWS Chatbot's initial workspace authorisation must happen through the AWS Console there is no CLI path for this OAuth step. Navigate to AWS Chatbot β Configure a chat client β Slack.
- Click Configure client and you'll be redirected to Slack
- Select your Slack workspace from the dropdown
- Review the permissions AWS Chatbot requests and click Allow
- You'll be redirected back to the AWS console with the workspace connected
β οΈ This step requires Slack workspace admin permissions. If you're not the Slack workspace admin, you'll need to request that an admin authorise the AWS Chatbot app, or ask them to create the connection. AWS Chatbot will appear as a new app in your Slack workspace's App directory after authorisation.
For Microsoft Teams
Navigate to AWS Chatbot β Configure a chat client β Microsoft Teams and follow the OAuth flow. Teams requires a Global Admin or Teams Administrator role to complete authorisation.
Step 4 β Create the Slack Channel Configuration
With your workspace connected, configure which specific Slack channel receives AWS notifications. In the AWS Chatbot console, click Configure new channel.
-
Configuration name:
team-alerts-{your-suffix} -
Slack channel: select your target alert channel (e.g.
#aws-alertsor#ops-critical) - IAM role: create a new role (AWS Chatbot will generate one with appropriate permissions)
-
Channel guardrail policies: add
ReadOnlyAccess - SNS topics: add your topic ARN from Step 2
π What guardrail policies actually do: Guardrail policies define the maximum permissions available to anyone running AWS commands from that Slack channel. If you add ReadOnlyAccess, no one can accidentally delete a resource from a Slack command regardless of their personal IAM permissions. Think of it as the outer fence IAM roles define what Chatbot can do in principle; guardrails define what's reachable from chat.
Step 5 β Create a CloudWatch Alarm
For testing, we'll set a very low CPU threshold that's easy to trigger intentionally:
# Create alarm that fires when CPU drops below 1%
aws cloudwatch put-metric-alarm \
--alarm-name ${ALARM_NAME} \
--alarm-description "Demo CPU alarm for testing notifications" \
--metric-name CPUUtilization \
--namespace AWS/EC2 \
--statistic Average \
--period 300 \
--threshold 1.0 \
--comparison-operator LessThanThreshold \
--alarm-actions ${SNS_TOPIC_ARN} \
--evaluation-periods 1
echo "β
Alarm created: ${ALARM_NAME}"
echo "π Will trigger when CPU < 1% (for testing)"
π‘ Why CPU < 1% as the test threshold? This creates an alarm that transitions to ALARM state almost immediately (no EC2 instances running = CPU averages zero), giving you a real state-change event to flow through SNS and Chatbot without needing actual compute resources. In production, set meaningful thresholds like
GreaterThanThresholdat 80% for real CPU alerts.
Step 6 β Test the Full Notification Pipeline
Don't wait for an alarm publish a test message directly to the SNS topic to validate end-to-end delivery:
# Send a test notification
aws sns publish \
--topic-arn ${SNS_TOPIC_ARN} \
--subject "Test Alert: Infrastructure Notification" \
--message '{
"AlarmName": "Manual Test Alert",
"AlarmDescription": "Testing chat notification system",
"NewStateValue": "ALARM",
"NewStateReason": "Testing notification delivery to Slack",
"StateChangeTime": "'$(date -u +"%Y-%m-%dT%H:%M:%S.%3NZ")'"
}'
echo "β
Test sent β check your Slack channel"
Validate with CLI checks
# 1. Confirm SNS topic exists and is encrypted
aws sns get-topic-attributes \
--topic-arn ${SNS_TOPIC_ARN} \
--query 'Attributes.{Name:DisplayName,Key:KmsMasterKeyId}'
# 2. Confirm alarm is pointing to SNS
aws cloudwatch describe-alarms \
--alarm-names ${ALARM_NAME} \
--query 'MetricAlarms[0].{Name:AlarmName,State:StateValue,Actions:AlarmActions}'
# 3. Confirm AWS Chatbot is subscribed to your topic
aws sns list-subscriptions-by-topic \
--topic-arn ${SNS_TOPIC_ARN} \
--query 'Subscriptions[*].{Protocol:Protocol,Endpoint:Endpoint}'
π Your ChatOps pipeline is live. Every CloudWatch alarm state change will now appear as a formatted card in your Slack channel, visible to the whole team, in real time. No email chains, no dashboard context-switching, no missed alerts buried in an inbox.
What the Notification Looks Like in Slack
AWS Chatbot formats CloudWatch alarm notifications into structured cards showing the alarm name, description, state transition (OK β ALARM), the reason for the state change, timestamp, and a direct link to the alarm in the AWS console. Teams get information, not data.
What makes it even more powerful: team members can run AWS CLI commands directly from the channel. For example:
@aws cloudwatch describe-alarm-history --alarm-name "prod-api-errors"
With the right guardrail permissions, that command runs and the response comes back all without leaving Slack.
Troubleshooting Common Issues
Test message sent but nothing appeared in Slack
AWS Chatbot subscription may not be confirmed. Go to SNS β Subscriptions and look for a subscription with protocol AWSChatbot. If the status is PendingConfirmation, the channel configuration may have failed revisit the channel configuration in the AWS Chatbot console.
AWS Chatbot authorisation failed / workspace not connecting
Almost always a permissions issue at the Slack level. Ensure you're authorising with a Slack workspace admin account, not a regular member.
Alarm is in ALARM state but Slack received nothing
Confirm the alarm's AlarmActions includes the correct SNS topic ARN. Run aws cloudwatch describe-alarms --alarm-names ${ALARM_NAME} and check the AlarmActions field.
Getting "Access Denied" when running AWS commands from Slack
The guardrail policy on the channel configuration is restricting the command. Either the command requires permissions beyond ReadOnlyAccess, or the IAM role attached to the configuration doesn't have the specific permission needed.
The ChatOps Roadmap
The reference architecture outlines five natural extensions:
-
Multi-environment routing β separate SNS topics for dev, staging, and production, each routing to dedicated Slack channels. A prod alert in
#ops-criticalis different from a dev alert in#dev-alerts. - Custom alert enrichment via Lambda β subscribe a Lambda function to your SNS topic to transform raw alarm messages before delivery, adding runbook links, affected service names, and on-call rotation info
- Escalation workflows with Step Functions β time-based escalation: if an alert in Slack goes unacknowledged for 10 minutes, Step Functions escalates from Slack to email, then SMS, then PagerDuty
- Interactive acknowledgement buttons β AWS Chatbot custom actions let engineers acknowledge alerts, trigger automated Lambda remediation, or mute an alarm from a button inside the Slack notification
- Cross-account centralisation β aggregate alarms from multiple AWS accounts into a single SNS topic using cross-account role assumptions
Cleanup
# Remove the test CloudWatch alarm
aws cloudwatch delete-alarms \
--alarm-names ${ALARM_NAME}
# Delete the SNS topic
aws sns delete-topic \
--topic-arn ${SNS_TOPIC_ARN}
# Manual: delete channel config in AWS Chatbot console
echo "π§ https://console.aws.amazon.com/chatbot/"
# Clear environment variables
unset SNS_TOPIC_NAME SNS_TOPIC_ARN ALARM_NAME RANDOM_SUFFIX
What I Learned From This Project
SNS topics, CloudWatch alarms, and IAM policies were familiar territory. What was new was understanding how they compose into something with genuine operational impact.
The insight that stuck most was about where information lives. In a traditional ops setup, infrastructure information lives in dashboards and humans have to go get it. In a ChatOps setup, that information comes to where the humans already are. That's not just a convenience; it changes who sees the alert (the whole team, not just whoever happens to be checking email), how fast they see it (immediately, not after polling), and what they can do with it (respond directly, in context, together).
A few technical things that clicked:
- AWS Chatbot is an SNS subscriber with superpowers β conceptually, it's just another SNS endpoint. The magic is in what it does with the message before delivery: formatting, rich cards, IAM-backed interactivity
- Guardrail policies are not IAM roles β they're a separate layer that caps what's possible from chat, independent of user IAM permissions. A developer with broad permissions can't accidentally use those permissions from Slack if the guardrail prevents it
-
KMS encryption on SNS is a one-liner β adding
"KmsMasterKeyId": "alias/aws/sns"to the topic attributes takes ten seconds and means you're not sending operational data in cleartext. No excuse not to do this in production - Test with direct SNS publish before debugging Chatbot β publishing directly to the SNS topic lets you isolate whether the problem is in the alarm β SNS path or the SNS β Chatbot path
Quick Reference: The Full Setup
# Services and their roles
CloudWatch alarm β monitors infrastructure metrics; changes state on breach
SNS topic β receives alarm state-change events; fans out to subscribers
AWS Chatbot β SNS subscriber; formats + delivers to Slack/Teams channels
IAM role β grants Chatbot permission to post and run commands
Guardrail policy β caps what AWS operations are accessible from chat
KMS encryption β protects message content at rest within SNS
# The alert chain
CPU > 80%
β CloudWatch alarm transitions to ALARM state
β Publishes to SNS topic (encrypted)
β AWS Chatbot receives, formats message
β Delivers rich card to #aws-alerts in Slack
β Team sees it, responds, acknowledges β all in one channel
Iβm also excited to share that Iβve been able to secure a special discount, in partnership with Sanjeev Kumarβs team, for the DevOps & Cloud Job Placement / Mentorship Program.
For those who may not be familiar, Sanjeev Kumar brings over 20 years of hands-on experience across multiple domains and every phase of product delivery. He is known for his strong architectural mindset, with a deep focus on Automation, DevOps, Cloud, and Security.
Sanjeev has extensive expertise in technology assessment, working closely with senior leadership, architects, and diverse software delivery teams to build scalable and secure systems. Beyond industry practice, he is also an active educator, running a YouTube channel dedicated to helping professionals successfully transition into DevOps and Cloud careers.
This is a great opportunity for anyone looking to level up their DevOps/Cloud skills with real-world mentorship and career guidance.
Do refer below for the link with a dedicated discount automatically applied at checkout;
DevOps & Cloud Job Placement / Mentorship Program.
If you also found this interesting and would love to take the next steps in the application process with AltSchool Africa do use my referral link below;
Apply here or use this Code: W2jBG8 during the registration process and by so doing, you will be supporting me and also getting a discount!
Special Offer: By signing up through the link and using the code shared, youβll receive a 10% discount!
Donβt miss out on this opportunity to transform your future and also save while doing it! Letβs grow together in the tech space. Also feel free to reach out if you need assistance or clarity regarding the program.
Iβm Ikoh Sylva, a passionate cloud computing enthusiast with hands-on experience in AWS. Iβm documenting my cloud journey here from a beginnerβs perspective, aiming to inspire others along the way.
If you find my contents helpful, please like and follow my posts, and consider sharing this article with anyone starting their own cloud journey.
Letβs connect on social media. Iβd love to engage and exchange ideas with you!



Top comments (0)