aws-lambda - Terraform:通知 SNS 的 CloudWatch 事件

标签 aws-lambda terraform amazon-sns amazon-cloudwatch terraform-provider-aws

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

  • 一个简单的 lambda 函数
  • 一个SNS话题
  • 获取该 lambda 以订阅 SNS 主题
  • 以某个时间间隔向主题发布消息的 Cloud Watch 事件
  • 用于检查 lambda 是否收到 SNS 通知的 Cloud Watch 日志组
  • 允许来自 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-lambda - Terraform:通知 SNS 的 CloudWatch 事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59032142/

    相关文章:

    amazon-web-services - 找出谁调用了 AWS lambda 函数

    azure - 状态 = 403 代码 ="AuthorizationFailure"消息 ="This request is not authorized to perform this operation"

    aws-lambda - Lambda 找不到文件 test_lambda.js。确保您的处理程序支持格式 : file-name. 方法

    iOS AWS SNS : How does client confirm SNS Topic subscription?

    aws-lambda - 如何在无服务器 lambda 中使用 Typeorm 的装饰器?

    amazon-web-services - AWS Lambda 函数无法访问 AppSync GraphQL API - 权限被拒绝

    terraform - 无法获取现有工作区 : querying Cloud Storage failed: storage: bucket doesn't exist

    amazon-web-services - 使用 Cloudformation AWS SNS 到 SQS 发布失败

    aws-lambda - 如何从另一个触发一个 AWS Lambda 函数,保证第二个只运行一次?

    amazon-s3 - 当对象上传到 S3 存储桶时,如何触发 AWS Cloudformation 堆栈的更新?