Sending notifications to Slack using AWS Chatbot.

Sending notifications to Slack using AWS Chatbot.

What is AWS Chatbot?

AWS Chatbot is an interactive agent for “ChatOps” that makes it easy to monitor and interact with your AWS resources in your Slack channels and Amazon Chime chat rooms. AWS Chatbot is free to use. It supports the following services.

  • Amazon CloudWatch
  • AWS Health
  • AWS Budgets
  • AWS Security Hub
  • Amazon GuardDuty
  • AWS CloudFormation
  • AWS Codepipeline/CodeBuild

In a previous article of the series of articles on monitoring, we shown how to create a custom Lambda function and a SNS topic to send CloudWatch alarms to Slack. A few months ago, AWS made the Chatbot service generally available, so we are going to switch our Lambda function for AWS Chatbot.

Set up AWS Chatbot

Authorize Chatbot to post to Slack

First of all, we need to authorize AWS Chatbot to send messages to our Slack. To do that, we have to perform these steps from the console:

Open the AWS Chatbot console at https://console.aws.amazon.com/chatbot/.

Under Configure a chat client, choose Slack, then choose Configure client.

From the dropdown list at the top right, choose the Slack workspace that you want to use with AWS Chatbot and choose Allow.

Terraform module to manage Chatbot

Chatbot was launched without API support. This means it has no native Terraform support. However, it supports configuration via CloudFormation. So, we are going to use a Terraform module that launches a CloudFormation stack behind the scenes to workaround this limitation.

The Terraform code of this module is available on OBytes GitHub public repos.

This module creates a AWS::Chatbot::SlackChannelConfiguration resource that maps a SNS topic to a Chatbot configuration. So, we send notifications to that SNS topic and Chatbot handles the process of sending messages to Slack.

Sending notifications to Slack using the Chatbot Terraform module

To send notifications, for example, when an AWS CodePipeline project starts or finishes, we will create a SNS topic and configure Chatbot to map that SNS topic. Then, we create an aws_codestarnotifications_notification_rule that notifies the SNS topic when one of these events occur. Besides this, we need to create an IAM role for Chatbot.

In the following snippet of code, we show how to send notifications to Slack when an AWS CodePipeline project starts or finishes using our Chatbot module.

resource "aws_sns_topic" "alerts_ci_slack_notifications_sns_topic" {
  name = "alerts-ci-slack-notifications"
}

resource "aws_sns_topic_policy" "alerts_ci_slack_notifications_sns_topic_policy" {
  arn    = aws_sns_topic.alerts_ci_slack_notifications_sns_topic.arn
  policy = data.aws_iam_policy_document.alerts_ci_slack_notifications_sns_topic_access.json
}

data "aws_iam_policy_document" "alerts_ci_slack_notifications_sns_topic_access" {
  statement {
    actions = ["sns:Publish"]

    principals {
      type = "Service"
      identifiers = [
        "codestar-notifications.amazonaws.com"
      ]
    }

    resources = [aws_sns_topic.alerts_ci_slack_notifications_sns_topic.arn]
  }
}

resource "aws_codepipeline" "cd" {
    ...
}

resource "aws_codestarnotifications_notification_rule" "aws_codestarnotifications_notification_rule_codepipeline" {
  count = var.slack_notifications_enabled ? 1 : 0

  detail_type = "BASIC"
  event_type_ids = [
    "codepipeline-pipeline-pipeline-execution-failed",
    "codepipeline-pipeline-pipeline-execution-canceled",
    "codepipeline-pipeline-pipeline-execution-started",
    "codepipeline-pipeline-pipeline-execution-resumed",
    "codepipeline-pipeline-pipeline-execution-succeeded",
    "codepipeline-pipeline-pipeline-execution-superseded"
  ]

  name     = "alerts-ci-slack-notification-rule-codepipeline"
  resource = aws_codepipeline.cd.arn

  target {
    address = aws_sns_topic.alerts_ci_slack_notifications_sns_topic.arn
  }
}

resource "aws_iam_policy" "chatbot_iam_policy" {
  path        = "/"
  description = "chatbot-iam-policy"
  policy      = data.aws_iam_policy_document.chatbot_iam_policy_document.json
  name        = "chatbot-iam-policy"
}

data "aws_iam_policy_document" "chatbot_iam_policy_document" {
  statement {
    actions = [
        "cloudwatch:Describe*",
        "cloudwatch:Get*",
        "cloudwatch:List*"
    ]

    resources = ["*"]
  }
}

resource "aws_iam_role" "chatbot_iam_role" {
  name = "chatbot-iam-role"

  assume_role_policy = data.aws_iam_policy_document.chatbot_assume
}

data "aws_iam_policy_document" "chatbot_assume" {
  statement {
    actions = [
      "sts:AssumeRole",
    ]

    principals {
      type = "Service"

      identifiers = [
        "chatbot.amazonaws.com.com",
      ]
    }
  }
}

resource "aws_iam_role_policy_attachment" "chatbot_iam_role_policy_attachment" {
  role       = aws_iam_role.chatbot_iam_role.id
  policy_arn = aws_iam_policy.chatbot_iam_policy.arn
}

module "chatbot" {
  source  = "./terraform-aws-chatbot-slack"

  configuration_name = "CI alerts"
  iam_role_arn       = aws_iam_role.chatbot_iam_role.arn
  slack_channel_id   = "ABCDEFGH"
  slack_workspace_id = "I342UFDS"

  sns_topic_arns = [
    aws_sns_topic.alerts_ci_slack_notifications_sns_topic.name
  ]
}

How does this look?

Once you finish the set up, you will start receiving notifications on Slack like this one.

And that's all folks! If you have any doubt, feel free to reach me out using the comments or via Twitter (@kstromeiraos).

Jose López
Jose López
2020-08-03 | 4 min read
Share article

More articles