Terraform: CloudWatch Event that notifies SNS

别等时光非礼了梦想. 提交于 2021-02-08 07:21:59

问题


I'm learning TF and trying to apply an infrastructure that creates:

  1. a simple lambda function
  2. an SNS topic
  3. get that lambda to subscribe the SNS topic
  4. a Cloud Watch Event that publishes a message to the topic at some interval
  5. a Cloud Watch Log Group to check if the lambda gets notified by the SNS
  6. The lambda permission to allow calls from SNS

I'm able to apply that successfully. The infrastructure seems perfectly fine (it has the same aspect when I create that myself through the visual aws console)

But the cloud watch Event doesn't get triggered (when built from TF), so no message is published to SNS and lambda doesn't get called. I don't know why

Anyone know how can I accomplish that? Bellow my .tf script:

provider "aws" {
  region = "us-east-1"
}

//lambda function handler & code file
resource "aws_lambda_function" "lambda-function" {
  function_name = "Function01"
  handler = "com.rafael.lambda.Function01"
  role = "arn:aws:iam::12345:role/LambdaRoleTest"
  runtime = "java8"
  s3_bucket = aws_s3_bucket.sns-test.id
  s3_key = aws_s3_bucket_object.file_upload.id
  source_code_hash = filebase64sha256("../target/sns-cw-lambda-poc.jar")
}

//allow sns to call lambda
resource "aws_lambda_permission" "allow-sns-to-lambda" {
  function_name = aws_lambda_function.lambda-function.function_name
  action = "lambda:InvokeFunction"
  principal = "sns.amazonaws.com"
  source_arn = aws_sns_topic.call-lambdas-topic.arn
  statement_id = "AllowExecutionFromSNS"
}

//app s3 repository
resource "aws_s3_bucket" "sns-test" {
  bucket = "app-bucket-12345"
  region = "us-east-1"
}

//app jar file
resource "aws_s3_bucket_object" "file_upload" {
  depends_on = [
    aws_s3_bucket.sns-test
  ]
  bucket = aws_s3_bucket.sns-test.id
  key = "sns-cw-lambda-poc.jar"
  source = "../target/sns-cw-lambda-poc.jar"
  server_side_encryption = "AES256"
  etag = filebase64sha256("../target/sns-cw-lambda-poc.jar")
}

//to check lambda exec logs
resource "aws_cloudwatch_log_group" "lambda-cloudwatch-logs" {
  name = "/aws/lambda/${aws_lambda_function.lambda-function.function_name}"
  retention_in_days = 1
}

//rule to trigger SNS
resource "aws_cloudwatch_event_rule" "publish-sns-rule" {
  name = "publish-sns-rule"
  schedule_expression = "rate(1 minute)"
}

//cloud watch event targets SNS
resource "aws_cloudwatch_event_target" "sns-publish" {
  count = "1"
  rule = aws_cloudwatch_event_rule.publish-sns-rule.name
  target_id = aws_sns_topic.call-lambdas-topic.name
  arn = aws_sns_topic.call-lambdas-topic.arn
}

//SNS topic to subscribe
resource "aws_sns_topic" "call-lambdas-topic" {
  name = "call-lambdas-topic"
}

//lambda subscribes the topic, so it should be nofied when other resource publishes to the topic
resource "aws_sns_topic_subscription" "sns-lambda-subscritption" {
  topic_arn = aws_sns_topic.call-lambdas-topic.arn
  protocol = "lambda"
  endpoint = aws_lambda_function.lambda-function.arn
}

回答1:


I figured it out, I forgot to add the SNS policies that allow CloudWatch to publish to SNS topic. To get the above script to work, just add this:

resource "aws_sns_topic_policy" "default" {
  count  = 1
  arn    = aws_sns_topic.call-lambdas-topic.arn
  policy = "${data.aws_iam_policy_document.sns_topic_policy.0.json}"
}

data "aws_iam_policy_document" "sns_topic_policy" {
  count = "1"
  statement {
    sid       = "Allow CloudwatchEvents"
    actions   = ["sns:Publish"]
    resources = [aws_sns_topic.call-lambdas-topic.arn]

    principals {
      type        = "Service"
      identifiers = ["events.amazonaws.com"]
    }
  }
}


来源:https://stackoverflow.com/questions/59032142/terraform-cloudwatch-event-that-notifies-sns

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!