Resource Policy help - allow AWS Lex to access deployed Lambda function

I hope someone can help me, or direct me to some sources if possible.

I’m creating a lambda function that should be accessible to Amazon Lex. The usual thing that happens is that I deploy my function, then manually setup the Lex bot using the Console. When setting the dialog and fulfillment code hooks, there is a popup asking me asking for permission to access the lambda function.

Instead, now, I would like to upload a zip file with the pre-configured Lex data, but the Console warns me that the intent can’t access the lambda. I look around and find that adding resourcePolicy would be the way to solve this.

But the following error occurs:

An error occurred: ApiGatewayRestApi - Invalid policy document. Please check the policy syntax and ensure that Principals are valid. (Service: AmazonApiGateway; Status Code: 400; Error Code: BadRequestException; Request ID: 385e25d5-50a9-11e9-bd93-9bfe4922d6f0).`

It’s odd because I’m not even using resourcePolicy with Api Gateway, just a regular lambda, so that’s odd.

There’s another issue, and it’s that deploying takes over 15 minutes, and only at the end of a long “Checking Stack Update progress” does it tell me that the policy was invalid in the first place.

Some (hopefully) relevant portion of my serverless.yml file:

service: supertest

  secrets: ${file(config.yml)}

  name: aws
  runtime: nodejs8.10
  stage: dev
    - Effect: Allow
      Action: Lambda:InvokeFunction
      SourceArn: "arn:aws:lex:us-east-1:XYZXYZXYZYXYZ:intent:*"
      Resource: "arn:aws:lambda:us-east-1:XYZXYZXYZYXYZ:function:supertest-dev-lex"
    - Effect: Allow
        - Lex:PostText
        - Lex:PostContent
      Resource: "arn:aws:lex:us-east-1:XYZXYZXYZYXYZ:*"

  environment: ${self:custom.secrets}

    handler: handler.lex

Came across this a couple years later but have worked it out with some help from the solution mentioned here:

    description: 'Lex Chatbot Lambda function'
    handler: index.handler
    timeout: 20 # optional, in seconds, default is 6
    # Lambda resource permission to allow Lex to invoke it
    # NOTE - Serverless tries to create resources first so you'll need to comment this
    #        out on first install and then run again to apply this permission
      Type: AWS::Lambda::Permission
        FunctionName: arn:aws:lambda:${aws:region}:${aws:accountId}:function:${self:service}-${self:provider.stage}-lex-handler
        Action: lambda:InvokeFunction

One caveat is that it tries to create resources first and fails because the Lambda does not exist yet.

So I deployed once with the resource commented out and then uncommented and ran again once the Lambda was created. There might be a better solution to that though.