============================================================================
Slack Notification Lambda for CloudWatch Alarms
============================================================================
Copy
# Local variables
locals {
slack_webhook_url = "https://hooks.slack.com/services/xx"
lambda_function_name = "CloudWatch-Alarms-To-Slack"
lambda_handler = "lambda_function.lambda_handler"
lambda_runtime = "python3.11"
}
# ============================================================================
# SNS Topic for Slack Notifications
# ============================================================================
# This uses the existing SNS topic from variables.tf
# No need to create a new one, we'll just add Lambda as a subscriber
# ============================================================================
# IAM Role for Lambda Function
# ============================================================================
resource "aws_iam_role" "lambda_slack_role" {
name = "${local.lambda_function_name}-Role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "lambda.amazonaws.com"
}
}
]
})
tags = {
Name = "${local.lambda_function_name}-Role"
Application = "CommonInfraResource"
Environment = "Production"
ManagedBy = "Terraform"
}
}
# Attach basic Lambda execution policy
resource "aws_iam_role_policy_attachment" "lambda_basic_execution" {
role = aws_iam_role.lambda_slack_role.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}
# ============================================================================
# CloudWatch Log Group for Lambda
# ============================================================================
resource "aws_cloudwatch_log_group" "lambda_log_group" {
name = "/aws/lambda/${local.lambda_function_name}"
retention_in_days = 14
tags = {
Name = "${local.lambda_function_name}-LogGroup"
Application = "CommonInfraResource"
Environment = "Production"
ManagedBy = "Terraform"
}
}
# ============================================================================
# Lambda Function
# ============================================================================
# Create ZIP file from Python code
data "archive_file" "lambda_zip" {
type = "zip"
source_file = "${path.module}/lambda-code/lambda_function.py"
output_path = "${path.module}/lambda-code/lambda_function.zip"
}
resource "aws_lambda_function" "slack_notifier" {
filename = data.archive_file.lambda_zip.output_path
function_name = local.lambda_function_name
role = aws_iam_role.lambda_slack_role.arn
handler = local.lambda_handler
source_code_hash = data.archive_file.lambda_zip.output_base64sha256
runtime = local.lambda_runtime
timeout = 30
memory_size = 256
environment {
variables = {
SLACK_WEBHOOK_URL = local.slack_webhook_url
}
}
tags = {
Name = local.lambda_function_name
Application = "CommonInfraResource"
Environment = "Production"
ManagedBy = "Terraform"
}
depends_on = [
aws_cloudwatch_log_group.lambda_log_group,
aws_iam_role_policy_attachment.lambda_basic_execution
]
}
# ============================================================================
# SNS Topic Subscription - Lambda
# ============================================================================
resource "aws_sns_topic_subscription" "lambda_subscription" {
topic_arn = var.sns_topic_arn
protocol = "lambda"
endpoint = aws_lambda_function.slack_notifier.arn
}
# Give SNS permission to invoke Lambda
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"
source_arn = var.sns_topic_arn
}
# ============================================================================
# Test Lambda Function (Optional - can be run manually)
# ============================================================================
# This creates a test event to validate the Lambda function works
resource "null_resource" "test_lambda" {
# Only run this when Lambda is created or updated
triggers = {
lambda_arn = aws_lambda_function.slack_notifier.arn
}
provisioner "local-exec" {
command = <<-EOT
echo "Testing Lambda function...."
aws lambda invoke \
--function-name ${aws_lambda_function.slack_notifier.function_name} \
--cli-binary-format raw-in-base64-out \
--payload file://${path.module}/lambda-code/test-event.json \
--region ap-south-1 \
/tmp/lambda-test-output.json
echo "TF - Lambda test output:"
cat /tmp/lambda-test-output.json
echo ""
EOT
}
depends_on = [
aws_lambda_function.slack_notifier,
aws_sns_topic_subscription.lambda_subscription,
aws_lambda_permission.allow_sns
]
}
