amazon-web-servicesaws-cloudformationaws-api-gatewayaws-sam

SAM template authorizerr error: authorizerUri/Fn::Sub/1/__FunctionArn__] 'null' values are not allowed in templates


Trying to create and API Gateway with lambda and attach the authorizer to it. The api and lambda creation works perfectly, but when I add the authorizer section, I get the following error:

Error: Failed to create changeset for the stack: dev-device-management-api-stack, ex: Waiter ChangeSetCreateComplete failed: Waiter encountered a terminal failure state: For expression "Status" we matched expected path: "FAILED" Status: FAILED. Reason: [/Resources/DeviceManagementApi/Type/Body/securityDefinitions/JwtAuthorizer/x-amazon-apigateway-authorizer/authorizerUri/Fn::Sub/1/FunctionArn] 'null' values are not allowed in templates

Couldn't understand the error and the reason.. any hlep?

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Parameters:
  EnvironmentStackName:
    Type: String
    AllowedValues:
      - dev
      - prod

Resources:
  DeviceManagementApi:
    Type: AWS::Serverless::Api
    Properties:
      Name: !Sub "${EnvironmentStackName}-device-management"
      StageName: "api"
      EndpointConfiguration: REGIONAL
      Auth:
        Authorizers:
          JwtAuthorizer:
            AuthorizationScopes:
              - scope
            IdentitySource: $request.header.Authorization
            JwtConfiguration:
              audience:
                - "my-audience"
              issuer: "https://issuer.clerk.accounts.dev"

  GetAllLocationsLambda:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: !Sub "${EnvironmentStackName}-lambda-locations-get-all"
      Handler: app.lambda_handler
      Runtime: python3.12
      CodeUri: src/location/get-all/
      MemorySize: 128
      Timeout: 10
      Role: !GetAtt DeviceApiLambdaExecutionRole.Arn
      Environment:
        Variables:
          STACK_NAME: !Ref EnvironmentStackName
      Events:
        GetAllLocationsApiEvent:
          Type: Api
          Properties:
            Path: /locations
            Method: GET
            RestApiId: !Ref DeviceManagementApi
#            Auth:
#              Authorizer: MyOauth2Authorizer
  
  DeviceApiLambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub "${EnvironmentStackName}-lambda-device-api-execution-role"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: "sts:AssumeRole"
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
      Policies:
        - PolicyName: LambdaDynamoDBReadAccess
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - dynamodb:Scan
                  - dynamodb:GetItem
                  - dynamodb:PutItem
                  - dynamodb:BatchGetItem
                  - dynamodb:BatchWriteItem
                  - dynamodb:ConditionCheckItem
                  - dynamodb:PutItem
                  - dynamodb:DescribeTable
                  - dynamodb:DeleteItem
                  - dynamodb:GetItem
                  - dynamodb:Scan
                  - dynamodb:Query
                  - dynamodb:UpdateItem
                Resource: "*"

Solution

  • You can't have a JWT authorizer with AWS::Serverless::Api.

    Either switch to use AWS::Serverless::HttpApi, or implement your own JWT authorizer with a Lambda authorizer. I can't see anything in your template that isn't supported by AWS::Serverless::HttpApi so switching to that is probably your best option.