您如何 "DependsOn" 来自 CFN 资源的 Lambda 函数?

How do you "DependsOn" a Lambda function from a CFN resource?

在 Serverless 中,我正在创建一个 AWS::Lambda::Permission CFN 资源,它允许 Cognito 调用 Custom Message Lambda Handler

AWS::Lambda::Permission 取决于 lambda。如何确保首先创建 lambda?

我已经尝试将 DependsOn 属性 添加到 AWS::Lambda::Permission CFN 资源,但没有成功。

下面是我的 CFN 资源,它试图向 Cognito 添加权限以调用 lambda:

UserPoolLambdaInvokePermission:
  Type: AWS::Lambda::Permission
  Properties:
    Action: lambda:invokeFunction
    Principal: cognito-idp.amazonaws.com
    FunctionName: arn:aws:lambda:${self:provider.region}:#{AWS::AccountId}:function:${self:service}-${self:provider.stage}-cognitoCustomMessage
    SourceArn: arn:aws:cognito-idp:${self:provider.region}:#{AWS::AccountId}:userpool/${self:provider.environment.USER_POOL_ID}

这是我的 lambda 在 serverless.yml 中的样子:

cognitoCustomMessage:
  handler: src/main/lambdas/users_handler.cognitoCustomMessage

这是我的 lambda 在非常基础的层面上所做的事情:

cognitoCustomMessage(event, next) {
  if (event.triggerSource === 'CustomMessage_ForgotPassword') {
    // do stuff
  }
  return next(null, event);
}

我从上面得到的错误是:

An error occurred: CognitoCustomMessageLambdaFunction - Function not found: arn:aws:lambda:us-west-2:1234567890:my-service-dev-cognitoCustomMessage (Service: AWSLambdaInternal; Status Code: 404; Error Code: ResourceNotFoundException; Request ID: e2a98525-5090-4d0f-a1f5-20610474f93b).

如果我加一个DependsOn:

UserPoolLambdaInvokePermission:
  Type: AWS::Lambda::Permission
  DependsOn: arn:aws:lambda:${self:provider.region}:#{AWS::AccountId}:function:${self:service}-${self:provider.stage}-cognitoCustomMessage
  ...
  ....

我从上面得到的错误是:

The CloudFormation template is invalid: Template format error: DependsOn must be a string or list of strings.

我也试过:

UserPoolLambdaInvokePermission:
  Type: AWS::Lambda::Permission
  DependsOn: CognitoCustomMessageLambdaFunction
  ...
  ....

我从上面得到的错误是:

An error occurred: CognitoCustomMessageLambdaFunction - Function not found: arn:aws:lambda:us-west-2:1234567890:my-service-dev-cognitoCustomMessage (Service: AWSLambdaInternal; Status Code: 404; Error Code: ResourceNotFoundException; Request ID: b888ae82-a0d7-4d69-888e-9e63027925c1).

我希望在 CFN 资源需要使用它之前,应该有一些方法可以先创建一个 lambda 函数,但是 DependsOn 似乎不是这种情况。

DependsOn 属性应具有云形成模板中 Lambda 函数的逻辑名称,而不是 Lambda 函数的 ARN。例如,如果您的 Lambda 函数在 Cloud Formation 模板中的逻辑名称是 MyLambda,那么 DependsOn 应该是这样的:

UserPoolLambdaInvokePermission:
  Type: AWS::Lambda::Permission
  DependsOn: MyLambda 

注意:打开云形成模板 .serverless/cloudformation-template-update-stack.json 并查找 logical lambda 函数名称。

示例:

{
    "MonitorLambdaFunction": {
    "Type": "AWS::Lambda::Function",
    "Properties": {
      "Code": {
        "S3Bucket": "deploy-dev",
        "S3Key": "serverless/dev/1641551717730-2022-01-07T10:35:17.730Z/zip"
      },
      "Handler": "src/monitors/handler.devMonitor",
      "Runtime": "nodejs14.x",
      "FunctionName": "dev-monitor",
      "MemorySize": 1024,
      "Timeout": 6,
      "Environment": {
        "Variables": {
          "STAGE": "dev",
        }
      },
      "Role": {
        "Fn::GetAtt": [
          "monitorIamRoleLambdaExecution",
          "Arn"
        ]
      }
    }
}

MonitorLambdaFunction是您要找的名字。

您在 serverless.yml 中定义的函数在后台转换为 cloudformation 资源。该资源称为 XLambdaFunction,其中 X = 首字母大写的函数名称。

所以如果你有:

functions:
  hello:
    handler: handler.hello
    ...other function stuff...

您可以参考:

DependsOn: HelloLambdaFunction

我只能假设如果你的函数已经命名为 CognitoCustomMessageLambdaFunction 那么你必须参考:

DependsOn: CognitoCustomMessageLambdaFunctionLambdaFunction

我遇到了类似的问题,添加 dependsOn 键对我有用。