【问题标题】:How to add a subscription filter using CloudFormation?如何使用 CloudFormation 添加订阅过滤器?
【发布时间】:2023-03-31 08:20:01
【问题描述】:

我正在生成一个包含多个 AWS Lambda 函数的 CloudFormation 模板。作为 CloudFormation 模板的一部分,我还想添加一个订阅过滤器,以便将 CloudWatch 日志发送到不同的账户。 但是,由于我事先不知道日志组的名称,也找不到任何方法来引用它们,所以我无法解决它。

有办法吗?

【问题讨论】:

    标签: aws-lambda amazon-cloudformation amazon-cloudwatch


    【解决方案1】:

    Serverless 的方式应该适合你。它会创建一个名称与您的 Lambda 函数将使用的名称相匹配的日志组资源。然后,您可以在任何需要的地方引用该日志组。您必须为您的 Lambda 函数命名,而不是使用默认命名行为。您可以使用堆栈名称使其唯一。

    类似:

    {
      "AWSTemplateFormatVersion": "2010-09-09",
      "Resources": {
        "FunctionLogGroup": {
          "Type": "AWS::Logs::LogGroup",
          "Properties": {
            "LogGroupName": {
              "Fn::Sub": "/aws/lambda/MyFunction-${AWS::StackName}"
            }
          }
        },
        "MyFunctionNameRole": {
          "Type": "AWS::IAM::Role",
          "Properties": {
            "ManagedPolicyArns": ["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"],
            "AssumeRolePolicyDocument": {
              "Version": "2012-10-17",
              "Statement": [{
                "Action": ["sts:AssumeRole"],
                "Effect": "Allow",
                "Principal": {
                  "Service": ["lambda.amazonaws.com"]
                }
              }]
            }
          }
        },
        "MyFunction": {
          "Type": "AWS::Lambda::Function",
          "Properties": {
            "Code": {
              "ZipFile": "def index():\n  return 'hello world'\n"
            },
            "FunctionName": {
              "Fn::Sub": "MyFunction-${AWS::StackName}"
            },
            "Handler": "handler.index",
            "MemorySize": 128,
            "Role": {
              "Fn::GetAtt": [
                "MyFunctionNameRole",
                "Arn"
              ]
            },
            "Runtime": "python3.6"
          },
          "DependsOn": [
            "FunctionLogGroup"
          ]
        },
        "MySubscriptionFilter": {
          "Type" : "AWS::Logs::SubscriptionFilter",
          "Properties" : {
            "DestinationArn": "TODO TODO",
            "FilterPattern": "",
            "LogGroupName": {"Ref": "FunctionLogGroup"},
            "RoleArn": "TODO TODO"
          }
        }
      }
    }
    

    【讨论】:

    • 谢谢kichik。我尝试遵循您的指导方针,但是在构建堆栈时,我从 AWS 收到了这个奇怪的错误:nullnull (Service: AWSLambdaInternal; Status Code: 400; Error Code: null; Request ID: null) 当从函数定义:“FunctionName”:{“Fn::Sub”:“/aws/lambda/FunctionName-${AWS::StackName}”},我能够创建堆栈。有什么想法吗?
    • 似乎只是在使用: "FunctionName": { "Fn::Sub": "/FunctionName-${AWS::StackName}" } 成功了。再次感谢。
    • 是的,这是一个错字。函数名称不应有 /aws/lambda
    【解决方案2】:

    您可以使用函数来获取日志组名称。例如:

    "LogGroupName": {
        "Fn::Join": [
            "",
            [
                "/aws/lambda/",
                {
                    "Ref": "MyLambdaFunction"
                }
            ]
        ]
    }
    

    请注意,MyLambdaFunction 是 CloudFormation 模板中您的 Lambda 函数块的名称。

    【讨论】:

    • 谢谢普拉文。这对我有帮助,但现在我进入下一步,在创建堆栈期间出现错误:指定的日志组不存在。 (服务:AWSLogs;状态代码:400;错误代码:ResourceNotFoundException;请求 ID:e4a3ffd1-0b19-4c83-b172-9f19737e2e8b)也许日志仅在第一次调用后创建?有什么我们可以在这里做的吗?
    • 您可以在 CloudFormation 中创建与 Lambda 函数期望的名称相同的日志组。然后,您可以依赖该日志组资源进行订阅。
    【解决方案3】:

    您可以尝试使用custom function 来调用您的 lambda,后者又可以使用测试有效负载或类似的东西运行您的 lambda,最终将创建一个日志流,然后您可以参考该日志组进行订阅,如上所述早前由 praveen 撰写。

    【讨论】:

      猜你喜欢
      • 2019-07-28
      • 2021-06-26
      • 1970-01-01
      • 2020-03-03
      • 1970-01-01
      • 2019-08-14
      • 2022-10-13
      • 2018-12-13
      • 2018-07-19
      相关资源
      最近更新 更多