Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

In Serverless, I am creating an AWS::Lambda::Permission CFN resource that allows Cognito to invoke a Custom Message Lambda Handler.

AWS::Lambda::Permission depends on the lambda. How do I ensure that the lambda is created first?

I have already tried adding a DependsOn property to the AWS::Lambda::Permission CFN resource with no luck.

Below is my CFN resource that is trying to add permissions to Cognito to invoke a 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}

Here is what my lambda looks like in my serverless.yml:

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

Here is what my lambda is doing on a very basic level:

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

The error I get from the above is:

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).

If I add a DependsOn:

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

The error I get from above is:

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

I have also tried:

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

The error I get from above is:

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).

I expect that there should be some method to create a lambda function first prior to the CFN resource needing to use it, but this does not seem to be the case with DependsOn.

like image 721
Jeffrey Wen Avatar asked Dec 31 '22 19:12

Jeffrey Wen


1 Answers

The DependsOn attribute should have the logical name of the Lambda Function in the Cloud formation template not the ARN of Lambda Function. For example, if your Lambda function's logical name in the Cloud Formation template is MyLambda then DependsOn should be like this:

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

NOTE: open cloud formation template .serverless/cloudformation-template-update-stack.json and look for logical lambda function name.

Example:

{
    "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 is the name you are looking for.

like image 105
Haider Ali Avatar answered Jan 13 '23 13:01

Haider Ali