Aws lambda Terraform:通知SNS的CloudWatch事件

Aws lambda Terraform:通知SNS的CloudWatch事件,aws-lambda,terraform,amazon-sns,amazon-cloudwatch,terraform-provider-aws,Aws Lambda,Terraform,Amazon Sns,Amazon Cloudwatch,Terraform Provider Aws,我正在学习TF,并尝试应用一个能够创建以下内容的基础架构: 一个简单的lambda函数 社交网络话题 让lambda订阅SNS主题 以一定间隔向主题发布消息的云监视事件 一个云监视日志组,用于检查lambda是否收到SNS的通知 允许SNS呼叫的lambda权限 我能够成功地应用它。这个基础架构看起来非常好(当我自己通过可视化aws控制台创建它时,它具有相同的特性) 但是云观察事件不会被触发(当从TF构建时),因此不会向SNS发布消息,也不会调用lambda。我不知道为什么 有人知道我怎样才能做

我正在学习TF,并尝试应用一个能够创建以下内容的基础架构:

  • 一个简单的lambda函数
  • 社交网络话题
  • 让lambda订阅SNS主题
  • 以一定间隔向主题发布消息的云监视事件
  • 一个云监视日志组,用于检查lambda是否收到SNS的通知
  • 允许SNS呼叫的lambda权限
  • 我能够成功地应用它。这个基础架构看起来非常好(当我自己通过可视化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
    }
    

    我弄明白了,我忘了添加允许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"]
        }
      }
    }
    

    当您使用AWS控制台创建资源时,是否会触发cloudwatch事件?是的,当我使用AWS控制台构建相同的基础结构时,会触发cloudwatch事件。SNS以指定的间隔通知Lambda。我可以通过检查cloud watch日志组来确保这一点。