diff --git a/README.md b/README.md index ee1f2557..bb2dbf9b 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ Doing serverless with Terraform? Check out [serverless.tf framework](https://ser - Create new SNS topic or use existing one - Support plaintext and encrypted version of Slack webhook URL - Most of Slack message options are customizable +- Custom Lambda function - Various event types are supported, even generic messages: - AWS CloudWatch Alarms - AWS CloudWatch LogMetrics Alarms @@ -114,6 +115,7 @@ See the [functions](https://github.com/terraform-aws-modules/terraform-aws-notif | [lambda\_function\_vpc\_security\_group\_ids](#input\_lambda\_function\_vpc\_security\_group\_ids) | List of security group ids when Lambda Function should run in the VPC. | `list(string)` | `null` | no | | [lambda\_function\_vpc\_subnet\_ids](#input\_lambda\_function\_vpc\_subnet\_ids) | List of subnet ids when Lambda Function should run in the VPC. Usually private or intra subnets. | `list(string)` | `null` | no | | [lambda\_role](#input\_lambda\_role) | IAM role attached to the Lambda Function. If this is set then a role will not be created for you. | `string` | `""` | no | +| [lambda\_source\_path](#input\_lambda\_source\_path) | The source path of the custom Lambda function | `string` | `null` | no | | [log\_events](#input\_log\_events) | Boolean flag to enabled/disable logging of incoming events | `bool` | `false` | no | | [recreate\_missing\_package](#input\_recreate\_missing\_package) | Whether to recreate missing Lambda package if it is missing locally or not | `bool` | `true` | no | | [reserved\_concurrent\_executions](#input\_reserved\_concurrent\_executions) | The amount of reserved concurrent executions for this lambda function. A value of 0 disables lambda from being triggered and -1 removes any concurrency limitations | `number` | `-1` | no | diff --git a/examples/notify-slack-simple/README.md b/examples/notify-slack-simple/README.md index 47b49720..a364f5bf 100644 --- a/examples/notify-slack-simple/README.md +++ b/examples/notify-slack-simple/README.md @@ -38,12 +38,14 @@ Note that this example may create resources which can cost money (AWS Elastic IP | Name | Source | Version | |------|--------|---------| +| [custom\_lambda](#module\_custom\_lambda) | ../../ | n/a | | [notify\_slack](#module\_notify\_slack) | ../../ | n/a | ## Resources | Name | Type | |------|------| +| [aws_sns_topic.custom_lambda](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic) | resource | | [aws_sns_topic.example](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic) | resource | | [local_file.integration_testing](https://registry.terraform.io/providers/hashicorp/local/latest/docs/resources/file) | resource | diff --git a/examples/notify-slack-simple/custom-lambda.tf b/examples/notify-slack-simple/custom-lambda.tf new file mode 100644 index 00000000..377c5bf6 --- /dev/null +++ b/examples/notify-slack-simple/custom-lambda.tf @@ -0,0 +1,36 @@ +locals { + custom = { + name = "ex-${replace(basename(path.cwd), "_", "-")}-custom" + tags = merge({ "Type" = "custom" }, local.tags) + } +} + +################################################################################ +# Supporting Resources +################################################################################ + +resource "aws_sns_topic" "custom_lambda" { + name = local.custom.name + tags = local.custom.tags +} + +################################################################################ +# Slack Notify Module +################################################################################ + +module "custom_lambda" { + source = "../../" + + lambda_function_name = "custom_lambda" + lambda_source_path = "../../functions/mylambda.py" + + iam_role_name_prefix = "custom" + + sns_topic_name = aws_sns_topic.custom_lambda.name + + slack_webhook_url = "https://hooks.slack.com/services/AAA/BBB/CCC" + slack_channel = "aws-notification" + slack_username = "reporter" + + tags = local.custom.tags +} diff --git a/functions/mylambda.py b/functions/mylambda.py new file mode 100644 index 00000000..1d41db10 --- /dev/null +++ b/functions/mylambda.py @@ -0,0 +1,25 @@ +#!/usr/bin/python3.6 +# CUSTOM LAMBDA FUNCTION + +import urllib3 +import json +import os +http = urllib3.PoolManager() + + +def lambda_handler(event, context): + url = os.environ["SLACK_WEBHOOK_URL"] + msg = { + "channel": "#channel-name", + "username": "Prometheus", + "text": event['Records'][0]['Sns']['Message'], + "icon_emoji": "" + } + + encoded_msg = json.dumps(msg).encode('utf-8') + resp = http.request('POST', url, body=encoded_msg) + print({ + "message": event['Records'][0]['Sns']['Message'], + "status_code": resp.status, + "response": resp.data + }) diff --git a/main.tf b/main.tf index a7080e88..5a0075fe 100644 --- a/main.tf +++ b/main.tf @@ -22,6 +22,8 @@ locals { actions = ["kms:Decrypt"] resources = [var.kms_key_arn] } + + lambda_handler = try(split(".", basename(var.lambda_source_path))[0], "notify_slack") } data "aws_iam_policy_document" "lambda" { @@ -77,8 +79,8 @@ module "lambda" { function_name = var.lambda_function_name description = var.lambda_description - handler = "notify_slack.lambda_handler" - source_path = "${path.module}/functions/notify_slack.py" + handler = "${local.lambda_handler}.lambda_handler" + source_path = var.lambda_source_path != null ? "${path.root}/${var.lambda_source_path}" : "${path.module}/functions/notify_slack.py" recreate_missing_package = var.recreate_missing_package runtime = "python3.8" timeout = 30 diff --git a/variables.tf b/variables.tf index daceeae4..04bd7771 100644 --- a/variables.tf +++ b/variables.tf @@ -28,6 +28,12 @@ variable "lambda_description" { default = null } +variable "lambda_source_path" { + description = "The source path of the custom Lambda function" + type = string + default = null +} + variable "sns_topic_name" { description = "The name of the SNS topic to create" type = string