Terraform:通知 SNS 的 CloudWatch 事件

Raf*_*nto 4 amazon-sns amazon-cloudwatch aws-lambda terraform terraform-provider-aws

我正在学习 TF 并尝试应用一个基础设施来创建:

  1. 一个简单的 lambda 函数
  2. SNS 话题
  3. 获取 lambda 来订阅 SNS 主题
  4. 以一定时间间隔向主题发布消息的 Cloud Watch Event
  5. Cloud Watch Log Group 用于检查 lambda 是否收到 SNS 通知
  6. 允许来自 SNS 调用的 lambda 权限

我能够成功地应用它。基础设施看起来非常好(当我通过 Visual AWS 控制台自己创建它时,它具有相同的方面)

但是云监视事件不会被触发(当从 TF 构建时),因此不会将消息发布到 SNS,并且不会调用 lambda。我不知道为什么

有人知道我怎样才能做到这一点吗?下面是我的 .tf 脚本:

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
}
Run Code Online (Sandbox Code Playgroud)

Raf*_*nto 8

我发现了,我忘记添加允许 CloudWatch 发布到 SNS 主题的 SNS 策略。要使上述脚本正常工作,只需添加以下内容:

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"]
    }
  }
}
Run Code Online (Sandbox Code Playgroud)