> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ahmadraza.in/llms.txt
> Use this file to discover all available pages before exploring further.

# HOW SNS WORKS

# Quick Reference: How SNS Works with Lambda for Slack Notifications

## 🎯 The Simple Version

### What Happens When an Alarm Triggers?

```
1. RDS CPU hits 85% for 15 minutes
   ↓
2. CloudWatch Alarm: "CW-RDS-AppName-prod-rds-db-CPUUtilization" → ALARM state
   ↓
3. Alarm has this config: alarm_actions = ["arn:aws:sns:...:PROD_Default_CloudWatch_Alarms_Topic"]
   ↓
4. SNS Topic receives the alarm notification
   ↓
5. SNS sees: "I have a Lambda subscriber for this topic!"
   ↓
6. SNS invokes Lambda: CloudWatch-Alarms-To-Slack
   ↓
7. Lambda receives SNS event, parses the alarm data
   ↓
8. Lambda formats a pretty message with colors & emojis
   ↓
9. Lambda sends HTTP POST to Slack webhook
   ↓
10. 💬 Message appears in your Slack channel!
```

## 🔑 Key Concepts

### SNS (Simple Notification Service)

* **Think of it as**: A message router/broadcaster
* **What it does**: When it receives a message, it forwards it to all subscribers
* **Subscribers can be**: Lambda, Email, SMS, HTTP endpoints, etc.
* **In our case**: CloudWatch → SNS → Lambda

### Why use SNS instead of CloudWatch → Lambda directly?

✅ **Flexibility**: You can add multiple subscribers (email, Lambda, etc.)
✅ **Decoupling**: CloudWatch doesn't need to know about Lambda
✅ **Fan-out**: One alarm can notify multiple destinations
✅ **Retry logic**: SNS handles retries if Lambda fails

### Lambda Subscription to SNS

```hcl theme={null}
resource "aws_sns_topic_subscription" "lambda_subscription" {
  topic_arn = "arn:aws:sns:ap-south-1:3AWS-Account-ID-NO5:PROD_Default_CloudWatch_Alarms_Topic"
  protocol  = "lambda"  # ← This tells SNS: "Call a Lambda function"
  endpoint  = aws_lambda_function.slack_notifier.arn  # ← This Lambda
}
```

This creates a subscription that says:

> "Hey SNS topic! Whenever you receive a message, please invoke this Lambda function"

### Permission for SNS to Call Lambda

```hcl theme={null}
resource "aws_lambda_permission" "allow_sns" {
  statement_id  = "AllowExecutionFromSNS"
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.slack_notifier.function_name
  principal     = "sns.amazonaws.com"  # ← SNS service
  source_arn    = var.sns_topic_arn    # ← Only this specific SNS topic
}
```

This permission says:

> "Lambda function, please allow SNS to invoke you"

## 📊 Data Flow Example

### CloudWatch Alarm Data

```json theme={null}
{
  "AlarmName": "CW-RDS-AppName-prod-rds-db-CPUUtilization",
  "NewStateValue": "ALARM",
  "NewStateReason": "Threshold Crossed: 3 datapoints were greater than threshold",
  "Region": "ap-south-1",
  "Trigger": {
    "MetricName": "CPUUtilization",
    "Namespace": "AWS/RDS",
    "Threshold": 80.0
  }
}
```

### SNS Wraps it

```json theme={null}
{
  "Records": [
    {
      "Sns": {
        "Type": "Notification",
        "TopicArn": "arn:aws:sns:ap-south-1:3AWS-Account-ID-NO5:PROD_Default_CloudWatch_Alarms_Topic",
        "Message": "{...CloudWatch alarm JSON above...}",
        "Timestamp": "2026-01-12T10:30:00.000Z"
      }
    }
  ]
}
```

### Lambda Receives & Processes

```python theme={null}
def lambda_handler(event, context):
    # Extract the CloudWatch alarm from SNS wrapper
    sns_record = event['Records'][0]['Sns']
    alarm_data = json.loads(sns_record['Message'])
    
    # alarm_data now has: AlarmName, NewStateValue, etc.
    
    # Format for Slack
    slack_message = {
        "text": f"🚨 {alarm_data['AlarmName']} is in {alarm_data['NewStateValue']} state"
    }
    
    # Send to Slack
    requests.post(SLACK_WEBHOOK_URL, json=slack_message)
```

### Slack Receives

```
🚨 CloudWatch Alarm: ALARM

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

📌 Alarm Name: CW-RDS-AppName-prod-rds-db-CPUUtilization
🔄 State Change: OK → ALARM
📝 Reason: Threshold Crossed: 3 datapoints...
```

## 🎪 All Components Working Together

```
┌──────────────────────────────────────────────────────────────┐
│                     YOUR AWS ACCOUNT                         │
│                                                              │
│  ┌─────────────────┐                                        │
│  │ RDS Instance    │  CPU at 85%                            │
│  │ AppName-prod-rds │                                        │
│  └────────┬────────┘                                        │
│           │                                                  │
│           │ CloudWatch monitors metrics                     │
│           ▼                                                  │
│  ┌─────────────────┐                                        │
│  │ CloudWatch      │  Threshold breached!                   │
│  │ Alarm           │                                        │
│  └────────┬────────┘                                        │
│           │                                                  │
│           │ alarm_actions = [SNS Topic ARN]                 │
│           ▼                                                  │
│  ┌─────────────────┐                                        │
│  │ SNS Topic       │  Receives alarm notification           │
│  │ PROD_Default_   │                                        │
│  │ CloudWatch_     │  Has subscribers:                      │
│  │ Alarms_Topic    │  - Lambda function                     │
│  └────────┬────────┘                                        │
│           │                                                  │
│           │ Invokes all subscribers                         │
│           ▼                                                  │
│  ┌─────────────────┐                                        │
│  │ Lambda Function │  1. Receives SNS event                 │
│  │ CloudWatch-     │  2. Parses alarm data                  │
│  │ Alarms-To-Slack │  3. Formats message                    │
│  │                 │  4. HTTP POST to Slack                 │
│  └────────┬────────┘                                        │
│           │                                                  │
└───────────┼──────────────────────────────────────────────────┘
            │
            │ HTTPS POST request
            │ with formatted JSON
            ▼
┌─────────────────────────────────────────────────────────────┐
│                        SLACK                                 │
│                                                             │
│  ┌─────────────────┐                                        │
│  │ Your Channel    │  💬 Message appears!                   │
│  │ #alerts or      │                                        │
│  │ #cloudwatch     │  🚨 CW-RDS-AppName-prod-rds-db...      │
│  └─────────────────┘                                        │
└─────────────────────────────────────────────────────────────┘
```

## 🔄 Why This Architecture?

### Alternative 1: CloudWatch → Lambda directly

❌ Not supported by AWS (CloudWatch can't directly invoke Lambda for alarms)
❌ Would need custom EventBridge rules (more complex)

### Alternative 2: CloudWatch → Email

❌ Not pretty, just plain text
❌ No formatting or colors
❌ Hard to filter/organize

### Our Solution: CloudWatch → SNS → Lambda → Slack

✅ Standard AWS pattern (SNS is designed for this)
✅ Flexible (can add email, SMS, etc. to SNS later)
✅ Pretty Slack messages with formatting
✅ Easy to customize Lambda code
✅ Reliable (SNS handles retries)

## 📝 Summary

**SNS is the glue** that connects CloudWatch alarms to Lambda functions.

**Think of SNS as a notification hub:**

* CloudWatch says: "Hey SNS, I have an alarm!"
* SNS says: "Thanks! Let me notify all my subscribers"
* Lambda (as subscriber) says: "Got it! Sending to Slack..."

**Without SNS**, you'd need complex EventBridge rules and more configuration.
**With SNS**, it's a simple, standard AWS pattern that works reliably.

## 🚀 Ready to Deploy?

Run these commands:

```bash theme={null}
# 1. Validate
terraform validate

# 2. Preview what will be created
terraform plan

# 3. Deploy
terraform apply

# 4. Test
aws lambda invoke \
  --function-name CloudWatch-Alarms-To-Slack \
  --payload file://test-event.json \
  output.json
```

Your alarms will automatically flow through this pipeline:
**CloudWatch → SNS → Lambda → Slack** 🎉
