ALB/Lambda CloudFormation 循环依赖关系

0

【以下的问题经过翻译处理】 我正在尝试创建一个 CFN 堆栈,其中包括一个由 ALB 调用的 Lambda 函数。其中一部分需要授予ALB调用Lambda函数的权限

但是,当我在CloudFormation中执行此操作时,我收到以下错误:

API: elasticloadbalancingv2:RegisterTargets elasticloadbalancing principal does not have permission to invoke <Lambda ARN> from target group <ALB Target Group ARN>

这是因为CFN在创建权限之前创建ALB目标组。通常,我会在目标组定义中放置一个DependsOn,但是当我这样做时,CFN告诉我存在循环依赖关系,因为权限引用了Lambda函数和目标组。

我可以从权限中删除对目标组的引用(确实可以解决问题),但这样做将允许帐户中的任何内容调用该函数**(如果我错了,请纠正我)**。

有没有解决这个问题的方法?最简模板如下:

AWSTemplateFormatVersion: "2010-09-09"

Resources:
    ALB:
        Type: "AWS::ElasticLoadBalancingV2::LoadBalancer"
        Properties:
            Name: "test-alb"
            Scheme: "internal"
            Type: "application"
            Subnets: 
              - "subnet-01c47f76"
              - "subnet-957eecf0"

    ALBListener:
        Type: "AWS::ElasticLoadBalancingV2::Listener"
        Properties:
            LoadBalancerArn: !Ref ALB
            Port: 80
            Protocol: "HTTP"
            DefaultActions: 
              - 
                Type: "forward"
                ForwardConfig: 
                    TargetGroups:
                      - TargetGroupArn: !Ref ALBTargetGroup

    ALBLambdaPermission:
        DependsOn:
          - LambdaFunction
        Type: AWS::Lambda::Permission
        Properties:
            FunctionName: !GetAtt LambdaFunction.Arn
            Action: lambda:InvokeFunction
            Principal: elasticloadbalancing.amazonaws.com
            SourceArn: !Ref ALBTargetGroup

    ALBTargetGroup:
        DependsOn: ALBLambdaPermission
        Type: "AWS::ElasticLoadBalancingV2::TargetGroup"
        Properties:
            HealthCheckPath: "/"
            TargetType: "lambda"
            Targets: 
              - 
                Id: !GetAtt LambdaFunction.Arn

    LambdaRole:
      Type: AWS::IAM::Role
      Properties:
        AssumeRolePolicyDocument:
          Version: "2012-10-17"
          Statement:
            - Effect: Allow
              Principal:
                Service:
                  - lambda.amazonaws.com
              Action:
                - sts:AssumeRole
        ManagedPolicyArns:
          - !Sub "arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"


    LambdaFunction:
        Type: "AWS::Lambda::Function"
        Properties:
            FunctionName: "alb-test-lambda"
            Handler: "index.lambda_handler"
            Code: 
              ZipFile: |
                def lambda_handler(event, context):
                    return  {
                        "statusCode": 200,
                        "body": "Hello from Lambda!",
                        "headers": {
                            "Content-Type": "text/html"
                        }
                    }
            Role: !GetAtt LambdaRole.Arn
            Runtime: "python3.6"

profile picture
专家
已提问 5 个月前34 查看次数
1 回答
0

【以下的回答经过翻译处理】 对于这些情况的诀窍是构建(一个)ARN作为字符串而不是引用,从而打破循环依赖关系。在您的情况下,如果您去掉SourceArn并使用通配符,则应该可以工作:

           DependsOn:
          - LambdaFunction
        Type: AWS::Lambda::Permission
        Properties:
            FunctionName: !GetAtt LambdaFunction.Arn
            Action: lambda:InvokeFunction
            Principal: elasticloadbalancing.amazonaws.com
            SourceArn: !Sub "arn:aws:elasticloadbalancing:${AWS::Region}:${AWS::AccountId}:targetgroup/Bingo/*" # Rather than !Ref ALBTargetGroup

    ALBTargetGroup:
        DependsOn: ALBLambdaPermission
        Type: "AWS::ElasticLoadBalancingV2::TargetGroup"
        Properties:
            HealthCheckPath: "/"
            Name: "Bingo"
            TargetType: "lambda"
            Targets: 
              - 
                Id: !GetAtt LambdaFunction.Arn
profile picture
专家
已回答 5 个月前

您未登录。 登录 发布回答。

一个好的回答可以清楚地解答问题和提供建设性反馈,并能促进提问者的职业发展。

回答问题的准则