title: AWS SAM template (with OpenAPI) for deploying HTTP API with custom Lambda authorizer
body: <p>I've managed to deploy an AWS HTTP API with differents routes and lambda integrations via yaml SAM template with OpenAPI definition but I'm stuck with adding custom lambda authorizer to my routes. When I deploy the stack I got some timeout for API creation :</p>
  <pre><code>ROLLBACK_IN_PROGRESS                     AWS::CloudFormation::Stack               CloudArYer                               The following resource(s) failed to
                                                                                                                             create: [Api]. . Rollback requested by
                                                                                                                             user.
  CREATE_FAILED                            AWS::ApiGatewayV2::Api                   Api                                      Internal server error (Service:
                                                                                                                             AmazonApiGatewayV2; Status Code: 500;
                                                                                                                             Error Code: InternalServerException;
                                                                                                                             Request ID: 18242cfd-
                                                                                                                             cc94-4909-a26a-6631806f94e7; Proxy:
                                                                                                                             null)
  </code></pre>
  <p>here is the main part of my template with API definition :</p>
  <pre><code>...
    AuthorizerLambdaTemplate:
      Type: AWS::Serverless::Application
      Properties:
        Location: ./templates/Authorizer-template-function.yaml
        Parameters:
          ProjectName: !Sub &quot;${ProjectName}&quot;
          ProjectApiKey: !Sub &quot;${ProjectApiKey}&quot;
  
    Api:
      Type: AWS::Serverless::HttpApi
      Properties:
        StageName: CloudArYerAPI
        CorsConfiguration:
          AllowCredentials: true
          AllowHeaders: &quot;*&quot;
          AllowMethods:
            - GET
            - POST
            - PUT
          AllowOrigins:
            - https://*
        DefinitionBody:
          openapi: 3.0.1
          info:
            title: CoudArYer-API
            description: HTTP API for connected chicken coop (Cloud Ar Yer)
            version: 2020-09-26
          paths:
            /config/{device}:
              get:
                x-amazon-apigateway-integration:
                  $ref: &quot;#/components/x-amazon-apigateway-integrations/GETLambda&quot;
            /event/{type}:
              post:
                x-amazon-apigateway-integration:
                  $ref: &quot;#/components/x-amazon-apigateway-integrations/POSTLambda&quot;
            /image/{origin}/{device}:
              put:
                x-amazon-apigateway-integration:
                  $ref: &quot;#/components/x-amazon-apigateway-integrations/PUTLambda&quot;
  
          security:
            - CloudArYer-Authorizer: []
  
          components:
            securitySchemes:
              CloudArYer-Authorizer:
                type: apiKey
                name: authorization
                in: header
                x-amazon-apigateway-authtype: custom
                x-amazon-apigateway-authorizer:
                  type: request
                  identitySource: $request.header.authorization
                  authorizerUri: 
                    Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${AuthorizerLambdaTemplate.Outputs.FunctionArn}/invocations
                  authorizerCredentials: !GetAtt ApiGatewayAuthorizerRole.Arn
                  authorizerPayloadFormatVersion: &quot;2.0&quot;
                  authorizerResultTtlInSeconds: 60
                  enableSimpleResponses: true
  
            x-amazon-apigateway-integrations:
              PUTLambda:
                payloadFormatVersion: &quot;2.0&quot;
                type: &quot;aws_proxy&quot;
                httpMethod: &quot;POST&quot;
                uri:
                  Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PUTImageLambdaTemplate.Outputs.FunctionArn}/invocations
                connectionType: &quot;INTERNET&quot;
              GETLambda:
                payloadFormatVersion: &quot;2.0&quot;
                type: &quot;aws_proxy&quot;
                httpMethod: &quot;POST&quot;
                uri:
                  Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GETConfigLambdaTemplate.Outputs.FunctionArn}/invocations
                connectionType: &quot;INTERNET&quot;
              POSTLambda:
                payloadFormatVersion: &quot;2.0&quot;
                type: &quot;aws_proxy&quot;
                httpMethod: &quot;POST&quot;
                uri:
                  Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${POSTEventLambdaTemplate.Outputs.FunctionArn}/invocations
                connectionType: &quot;INTERNET&quot;
  
    ApiGatewayAuthorizerRole:
      Type: AWS::IAM::Role
      Properties:
        AssumeRolePolicyDocument: 
          Version: &quot;2012-10-17&quot;
          Statement: 
            - Effect: &quot;Allow&quot;
              Principal: 
                Service: 
                  - &quot;apigateway.amazonaws.com&quot;
              Action: 
                - sts:AssumeRole
        Policies: 
          - PolicyName: &quot;InvokeAuthorizerFunction&quot;
            PolicyDocument: 
              Version: &quot;2012-10-17&quot;
              Statement: 
                - Effect: &quot;Allow&quot;
                  Action:
                    - lambda:InvokeAsync
                    - lambda:InvokeFunction
                  Resource: !GetAtt AuthorizerLambdaTemplate.Outputs.FunctionArn
  ...
  </code></pre>
  <p>My authorizer lambda is define in a nested stack (AuthorizerLambdaTemplate)</p>
  <pre><code>AWSTemplateFormatVersion: '2010-09-09'
  Transform: AWS::Serverless-2016-10-31
  Resources:
    AuthorizerFunction:
      Type: AWS::Serverless::Function
      Properties:
        FunctionName: !Sub &quot;${ProjectName}-Authorizer-Lambda&quot;
        CodeUri: ../src/authorizer
        Handler: handler.authorizer
        Runtime: nodejs10.x
        Role: !Sub &quot;${CustomAuthorizerFunctionRole.Arn}&quot;
        Environment:
          Variables:
            ProjectApiKey: !Sub &quot;${ProjectApiKey}&quot;
  
    CustomAuthorizerFunctionRole:
      Type: AWS::IAM::Role
      Properties:
        AssumeRolePolicyDocument: 
          Version: &quot;2012-10-17&quot;
          Statement:
            - Effect: &quot;Allow&quot;
              Principal: 
                Service: 
                  - &quot;lambda.amazonaws.com&quot;
              Action: 
                - sts:AssumeRole
        ManagedPolicyArns:
          - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
  
  Parameters:
    ProjectName: 
      Type: String
    ProjectApiKey:
      Type: String
  
  Outputs:
    FunctionArn:
      Description: Arn Authorizer function
      Value: !GetAtt AuthorizerFunction.Arn
  </code></pre>
  <p>and the code for lambda is defined as follow in an extenal directory</p>
  <pre><code>exports.authorizer = async(event) =&gt; {
      let response = {
          &quot;isAuthorized&quot;: false,
          &quot;context&quot;: {
              &quot;stringKey&quot;: &quot;test&quot;
          }
      };
  
      if (event.headers.authorization === process.env.ProjectApiKey) {
          response = {
              &quot;isAuthorized&quot;: true,
              &quot;context&quot;: {
                  &quot;stringKey&quot;: &quot;test&quot;
              }
          };
      }
  
      return response;
  };
  </code></pre>
  <p>I do not understand why the deployment is blocked on the API creation ... and failed with an InternalServerException. Where am I wrong on the stack definition. I've browsed many sites, snippets... but less info for new HTTP API and for instance no clue to fix my issue.</p>
  <p>Thanks for your potential help ! :-)</p>