Serverless-application-model: Lambda + API Gateway stack works, but missing Lambda permissions

Created on 8 Jun 2017  路  2Comments  路  Source: aws/serverless-application-model

My template below is about 95% working! The only thing is, my GraphQL and GraphiQL endpoints don't work right after a stack deploy, yielding this error:

Thu Jun 08 02:36:32 UTC 2017 : Execution failed due to configuration error: Invalid permissions on Lambda function

The way I'm able to fix this is if I go into each resource, click on "Integration Request", uncheck and re-check "Use Lambda Proxy integration" - which gives me a key message:

You are about to give API Gateway permission to invoke your Lambda function:
arn:aws:lambda:us-west-2:xxx:function:GraphQL-GraphQLInspector-YRXVD1AYWPMY

And then everything works great. So there's some kind of permission that has to be granted to the API Gateway to call the Lambda functions. If I don't specify my own AWS::Serverless::Api and it creates its own, it works fine. But when specifying my own API in the template, the permissions are broken. How do I fix this?

Template:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
  GraphQL:
    Type: AWS::Serverless::Function
    Properties:
      Handler: serverless.graphqlHandler
      Runtime: nodejs6.10
      MemorySize: 256
      Events:
        GetRequest:
          Type: Api
          Properties:
            Path: /graphql
            Method: get
            RestApiId: ApiGateway
        PostRequest:
          Type: Api
          Properties:
            Path: /graphql
            Method: post
            RestApiId: ApiGateway
  GraphQLInspector:
    Type: AWS::Serverless::Function
    Properties:
      Handler: serverless.graphiqlHandler
      Runtime: nodejs6.10
      MemorySize: 256
      Events:
        GetRequest:
          Type: Api
          Properties:
            Path: /graphiql
            Method: get
            RestApiId: ApiGateway
  ApiGateway:
    Type: AWS::Serverless::Api
    Properties:
      StageName: prod
      DefinitionBody:
        swagger: 2.0
        info:
          version: 1.0
          title:
            Ref: AWS::StackName
        paths:
          "/graphiql":
            get:
              responses: {}
              x-amazon-apigateway-integration:
                uri:
                  Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GraphQLInspector.Arn}/invocations
                httpMethod: POST
                type: aws_proxy
          "/graphql":
            get:
              responses: {}
              security:
              - UserPool: []
              x-amazon-apigateway-integration:
                uri:
                  Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GraphQL.Arn}/invocations
                httpMethod: POST
                type: aws_proxy
            post:
              responses: {}
              security:
              - UserPool: []
              x-amazon-apigateway-integration:
                uri:
                  Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GraphQL.Arn}/invocations
                httpMethod: POST
                type: aws_proxy
        securityDefinitions:
          UserPool:
            type: apiKey
            name: Authorization
            in: header
            x-amazon-apigateway-authtype: cognito_user_pools
            x-amazon-apigateway-authorizer:
              providerARNs:
              - arn:aws:cognito-idp:us-west-2:xxx:userpool/xxx
              type: cognito_user_pools

Most helpful comment

Got it! Had to add these two resources:

  GraphQLPerms:
    Type: AWS::Lambda::Permission
    DependsOn:
      - ApiGateway
      - GraphQL
    Properties:
      Action: lambda:InvokeFunction
      FunctionName: !Ref GraphQL
      Principal: apigateway.amazonaws.com
  GraphQLInspectorPerms:
    Type: AWS::Lambda::Permission
    DependsOn:
      - ApiGateway
      - GraphQLInspector
    Properties:
      Action: lambda:InvokeFunction
      FunctionName: !Ref GraphQLInspector
      Principal: apigateway.amazonaws.com

All 2 comments

I had to use the Cloud Formation YAML Ref: method for RestApiId - not sure if that is your problem but worth a try:

Events:
  GetRequest:
    Type: Api
    Properties:
      Path: /graphiql
      Method: get
      RestApiId:
        Ref: ApiGateway

Got it! Had to add these two resources:

  GraphQLPerms:
    Type: AWS::Lambda::Permission
    DependsOn:
      - ApiGateway
      - GraphQL
    Properties:
      Action: lambda:InvokeFunction
      FunctionName: !Ref GraphQL
      Principal: apigateway.amazonaws.com
  GraphQLInspectorPerms:
    Type: AWS::Lambda::Permission
    DependsOn:
      - ApiGateway
      - GraphQLInspector
    Properties:
      Action: lambda:InvokeFunction
      FunctionName: !Ref GraphQLInspector
      Principal: apigateway.amazonaws.com
Was this page helpful?
0 / 5 - 0 ratings