/aws-sns-slack-terraform

A Terraform module which sends SNS events to Slack with AWS lambda function

Primary LanguagePythonApache License 2.0Apache-2.0

aws-sns-slack-terraform

Minimal CloudWatch Screenshot

This is a Terraform module which maps an AWS SNS topic name to a Slack channel. The AWS Lambda function code it uses is derived from robbwagoner/aws-lambda-sns-to-slack.

The supported features are:

  • Posting AWS SNS notifications to Slack channels
  • Building necessary AWS resources by Terraform automatically
  • Customizable topic-to-channel map

Usage

aws-sns-slack-terraform is a Terraform module. You just need to include the module in one of your Terraform scripts and set up SNS topics and permissions. See examples/ for concrete examples.

module "sns_to_slack" {
  source = "github.com/builtinnya/aws-sns-slack-terraform/module"

  slack_webhook_url = "hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX"
  slack_channel_map = "{ \"topic-name\": \"#slack-channel\" }"

  # The following variables are optional.
  lambda_function_name = "sns-to-slack"
  default_username = "AWS Lambda"
  default_channel = "#webhook-tests"
  default_emoji = ":information_source:"
}

resource "aws_sns_topic" "test_topic" {
  name = "topic-name"
}

resource "aws_lambda_permission" "allow_lambda_sns_to_slack" {
  statement_id = "AllowSNSToSlackExecutionFromSNS"
  action = "lambda:invokeFunction"
  function_name = "${module.sns_to_slack.lambda_function_arn}"
  principal = "sns.amazonaws.com"
  source_arn = "${aws_sns_topic.test_topic.arn}"
}

resource "aws_sns_topic_subscription" "lambda_sns_to_slack" {
  topic_arn = "${aws_sns_topic.test_topic.arn}"
  protocol = "lambda"
  endpoint = "${module.sns_to_slack.lambda_function_arn}"
}

Configurable variables

Variable Description Required Default
slack_webhook_url Slack incoming webhook URL without protocol name. yes
slack_channel_map Topic-to-channel mapping string in JSON. yes
lambda_function_name AWS Lambda function name for the Slack notifier no "sns-to-slack"
default_username Default username for notifications used if no matching one found. no "AWS Lambda"
default_channel Default channel used if no matching channel found. no "#webhook-tests"
default_emoji Default emoji used if no matching emoji found. no ":information_source:"
lambda_iam_role_name IAM role name for lambda functions. no "lambda-sns-to-slack"
lambda_iam_policy_name IAM policy name for lambda functions. no "lambda-sns-to-slack-policy"

Output variables

Variable Description
lambda_function_arn AWS Lambda notifier function ARN.

Examples

minimal

The minimal example is located at examples/minimal. It builds no extra AWS resources except a CloudWatch alarm for AWS Lambda's duration metric.

Building steps

  1. Move to the examples/minimal directory.

    $ cd examples/minimal
  2. Copy secrets.tfvars.example to secrets.tfvars and fill in the values.

    $ cp secrets.tfvars.example secrets.tfvars
    $ # Edit secrets.tfvars using your favorite editor.
    access_key = "<your AWS Access Key>"
    secret_key = "<your AWS Secret Key>"
    region = "<region>"
    slack_webhook_url="hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX"
  3. Execute the following commands to build resources using Terraform.

    $ terraform init
    $ terraform plan -var-file=terraform.tfvars -var-file=secrets.tfvars
    $ terraform apply -var-file=terraform.tfvars -var-file=secrets.tfvars

Destroying resources

To destory AWS resources created by the above steps, execute the following command in examples/minimal directory.

$ terraform destroy -var-file=terraform.tfvars -var-file=secrets.tfvars

Testing

To test notification, use awscli cloudwatch set-alarm-state as following.

$ AWS_ACCESS_KEY_ID=<ACCESS_KEY> \
  AWS_SECRET_ACCESS_KEY=<SECRET> \
  AWS_DEFAULT_REGION=<REGION> \
    aws cloudwatch set-alarm-state \
      --alarm-name lambda-duration \
      --state-value ALARM \
      --state-reason xyzzy

Development

The main AWS Lambda function code is located in sns-to-slack/ directory. To prepare development, you need to create virtualenv for this project and install required pip packages as following.

$ virtualenv sns-to-slack/virtualenv
$ source sns-to-slack/virtualenv/bin/activate
$ pip install -r sns-to-slack/requirements.txt

You need to create module/lambda/sns-to-slack.zip to update the code as following.

$ source sns-to-slack/virtualenv/bin/activate # if you haven't yet
$ ./build-function.sh

Testing

To test the function locally, just run lambda_function.py with some environment variables.

$ WEBHOOK_URL="hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX" \
  CHANNEL_MAP=`echo '{ "production-notices": "#webhook-tests" }' | base64` \
  python sns-to-slack/lambda_function.py

Contributors

See CONTRIBUTORS.md.

License

Copyright © 2017-2018 Naoto Yokoyama

Distributed under the Apache license version 2.0. See the LICENSE file for full details.