aws-sam-cli icon indicating copy to clipboard operation
aws-sam-cli copied to clipboard

sam local start-api cannot parse lambda authorizer correctly

Open gnowobu opened this issue 1 year ago • 5 comments

Description:

Got this error when trying to test my lambda authorizer locally with sam build and sam local start-api: Unable to parse the Lambda ARN for Authorizer 'LambdaAuthorizer', skipping

here's my cloudformation template:

  lambdaAuthorizer:
    Type: AWS::Serverless::Function
    Properties:
        FunctionName: !Sub LambdaAuthorizer-${StageName}
        CodeUri: lambda_authorizer/
        Handler: src/handlers/authorizer.handler
        Runtime: nodejs20.x
        Timeout: 900
        MemorySize: 512
        Role: !GetAtt MyLambdaExecutionRole.Arn
        Environment:
          Variables:
            COGNITO_USERPOOL_ID: "..."
            COGNITO_CLIENT_ID: "..."

  MyApi:
    Type: AWS::Serverless::Api
    Properties:
      #      StageName: dev
      StageName: !Sub MyApi-${StageName}
      Auth:
        DefaultAuthorizer: CognitoAuthorizer
        AddDefaultAuthorizerToCorsPreflight: False
        Authorizers:
          LambdaAuthorizer: 
            FunctionArn: !GetAtt lambdaAuthorizer.Arn
          CognitoAuthorizer:
            UserPoolArn: arn:aws:cognito-idp:us-east-1:$account_id:userpool/...
        

Steps to reproduce:

Observed result:

The authorizer lambda function's arn cannot be parsed, but i have followed multiple AWS docs and it seems this is the only correct way to do it

Expected result:

I think this is quite a straightforward cloudformation and i don't understand why it cannot parse the arn

Additional environment details (Ex: Windows, Mac, Amazon Linux etc)

  1. OS: Mac
  2. sam --version: SAM CLI, version 1.124.0
  3. AWS region: us-east-1
{
  "version": "1.124.0",
  "system": {
    "python": "3.8.20",
    "os": "macOS-12.7.5-x86_64-i386-64bit"
  },
  "additional_dependencies": {
    "docker_engine": "20.10.16",
    "aws_cdk": "Not available",
    "terraform": "1.9.3"
  },
  "available_beta_feature_env_vars": [
    "SAM_CLI_BETA_FEATURES",
    "SAM_CLI_BETA_BUILD_PERFORMANCE",
    "SAM_CLI_BETA_TERRAFORM_SUPPORT",
    "SAM_CLI_BETA_RUST_CARGO_LAMBDA"
  ]
}

Add --debug flag to command you are running

gnowobu avatar Sep 18 '24 03:09 gnowobu

Hi @gnowobu thanks for raising this issue! Could you provide the full sam cli output when running the command with the --debug flag?

I tried with a couple different templates and was unable to reproduce the error.

sidhujus avatar Sep 19 '24 18:09 sidhujus

Hi @sidhujus thanks for reaching out. Here's the debug output that i think it's related, please let me know if you need more output from that.

--template_file=/.../.aws-sam/build/template.yaml
--host=127.0.0.1 --port=3000 --static_dir=public                                                  
--layer_cache_basedir=/.../.aws-sam/layers-pkg --container_host=localhost              
--container_host_interface=127.0.0.1                                                              
2024-09-19 14:15:49,849 | local start-api command is called                                       
2024-09-19 14:15:50,383 | Collected default values for parameters: {'StageName': 'Stage'}         
2024-09-19 14:15:50,457 | Sam customer defined id is more priority than other IDs. Customer       
defined id for resource lambdaAuthorizer is lambdaAuthorizer                                      
2024-09-19 14:15:50,458 | There is no customer defined id or cdk path defined for resource MyApi, 
so we will use the resource logical id as the resource id                                         
2024-09-19 14:15:50,459 | There is no customer defined id or cdk path defined for resource        
MyLambdaExecutionRole, so we will use the resource logical id as the resource id                  
2024-09-19 14:15:50,461 | Sam customer defined id is more priority than other IDs. Customer       
defined id for resource dashboardAdmin is dashboardAdmin                                          
2024-09-19 14:15:50,462 | There is no customer defined id or cdk path defined for resource        
TopFansDb, so we will use the resource logical id as the resource id                              
2024-09-19 14:15:50,469 | Unable to resolve property FunctionArn: OrderedDict([('Fn::GetAtt',     
['lambdaAuthorizer', 'Arn'])]). Leaving as is.                                                    
2024-09-19 14:15:50,474 | 0 stacks found in the template                                          
2024-09-19 14:15:50,475 | Collected default values for parameters: {'StageName': 'Stage'}         
2024-09-19 14:15:50,552 | Sam customer defined id is more priority than other IDs. Customer       
defined id for resource lambdaAuthorizer is lambdaAuthorizer                                      
2024-09-19 14:15:50,553 | There is no customer defined id or cdk path defined for resource MyApi, 
so we will use the resource logical id as the resource id                                         
2024-09-19 14:15:50,554 | There is no customer defined id or cdk path defined for resource        
MyLambdaExecutionRole, so we will use the resource logical id as the resource id                  
2024-09-19 14:15:50,556 | Sam customer defined id is more priority than other IDs. Customer       
defined id for resource dashboardAdmin is dashboardAdmin                                          
2024-09-19 14:15:50,557 | There is no customer defined id or cdk path defined for resource        
TopFansDb, so we will use the resource logical id as the resource id                              
2024-09-19 14:15:50,566 | Unable to resolve property FunctionArn: OrderedDict([('Fn::GetAtt',     
['lambdaAuthorizer', 'Arn'])]). Leaving as is.                                                    
2024-09-19 14:15:50,572 | 5 resources found in the stack                                          
2024-09-19 14:15:50,573 | Found Serverless function with name='lambdaAuthorizer' and              
CodeUri='lambdaAuthorizer'                                                                        
2024-09-19 14:15:50,574 | --base-dir is not presented, adjusting uri lambdaAuthorizer relative to 
/.../.aws-sam/build/template.yaml                
2024-09-19 14:15:50,575 | Found Serverless function with name='dashboardAdmin' and                
CodeUri='dashboardAdmin'                                                                          
2024-09-19 14:15:50,582 | --base-dir is not presented, adjusting uri dashboardAdmin relative to   
/.../.aws-sam/build/template.yaml                
2024-09-19 14:15:51,012 | Found '0' API Events in Serverless function with name 'lambdaAuthorizer'
2024-09-19 14:15:51,015 | CORS Property MaxAge was not fully resolved. Will proceed as if the     
Property was not defined.                                                                         
2024-09-19 14:15:51,018 | Detected Inline Swagger definition                                      
2024-09-19 14:15:51,019 | Parsing Swagger document using 2.0 specification                        
2024-09-19 14:15:51,021 | Found '0' authorizers in resource 'MyApi'                               
        
2024-09-19 14:15:51,070 | Found '0' APIs in resource 'MyApi'                                      
2024-09-19 14:15:51,073 | This Integration URI format is not supported:                           
OrderedDict([('Fn::GetAtt', ['lambdaAuthorizer', 'Arn'])])                                        
2024-09-19 14:15:51,075 | Extracted Function ARN: None                                            
2024-09-19 14:15:51,076 | Unable to parse the Lambda ARN for Authorizer 'LambdaAuthorizer',       
skipping                                                                                          
2024-09-19 14:15:51,077 | Authorizer 'CognitoAuthorizer' is currently unsupported (must be a      
Lambda Authorizer), skipping                                                                      
2024-09-19 14:15:51,079 | Found '20' API Events in Serverless function with name 'dashboardAdmin' 
2024-09-19 14:15:51,082 | Removed duplicates from '20' Explicit APIs and '0' Implicit APIs to     
produce '20' APIs            

gnowobu avatar Sep 19 '24 18:09 gnowobu

I am having this same issue , its been driving me crazy i tried everything is there an update on this fix ?

sernone avatar Apr 04 '25 21:04 sernone

Here's another template that exhibits this issue.

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

Parameters:
  StageName:
    Type: String
    Default: dev

Resources:
  MyApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: !Sub ${StageName}
      Auth:
        DefaultAuthorizer: MyLambdaAuthorizer
        Authorizers:
          MyLambdaAuthorizer:
            FunctionPayloadType: REQUEST
            FunctionArn: !GetAtt MyAuthFunction.Arn
            Identity:
              Headers:
                - Authorization

  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: ./src/MyFunction
      Handler: lambda_function.lambda_handler
      Runtime: python3.13
      Events:
        GetRoot:
          Type: Api
          Properties:
            RestApiId: !Ref MyApi
            Path: /
            Method: get

  MyAuthFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: !Sub MyAuthFunction-${StageName}
      CodeUri: ./src/MyAuthFunction
      Handler: lambda_function.lambda_handler
      Runtime: python3.13

When sam local start-api is executed, we get the following:

Unable to parse the Lambda ARN for Authorizer 'MyLambdaAuthorizer', skipping                                                                                                                                         
Linking authorizer skipped for route '/', authorizer 'None' is unsupported or not found 

With the --debug option, we get the following, which I suppose is the problem.

2025-09-30 05:11:27,842 | This Integration URI format is not supported: OrderedDict({'Fn::GetAtt': ['MyAuthFunction', 'Arn']})                                                                                       
2025-09-30 05:11:27,843 | Extracted Function ARN: None 

If we remove the FunctionName property from MyAuthFunction or change it to a fixed value, SAM works as expected.

My current workaround requires conditionally creating an alternate nameless authorizer resource for use with SAM. Obviously, not ideal.

damiengiese avatar Sep 30 '25 09:09 damiengiese

After some debugging and reviewing the CLI local command implementations, I discovered that it only supports the Sub intrinsic function: https://github.com/aws/aws-sam-cli/blob/main/samcli/commands/local/lib/swagger/integration_uri.py#L96.

So a possible solution now would be to construct the authorizer function's ARN manually:

  lambdaAuthorizer:
    Type: AWS::Serverless::Function
    Properties:
        FunctionName: !Sub LambdaAuthorizer-${StageName}
        CodeUri: lambda_authorizer/
        Handler: src/handlers/authorizer.handler
        Runtime: nodejs20.x
        Timeout: 900
        MemorySize: 512
        Role: !GetAtt MyLambdaExecutionRole.Arn
        Environment:
          Variables:
            COGNITO_USERPOOL_ID: "..."
            COGNITO_CLIENT_ID: "..."

  MyApi:
    Type: AWS::Serverless::Api
    Properties:
      #      StageName: dev
      StageName: !Sub MyApi-${StageName}
      Auth:
        DefaultAuthorizer: CognitoAuthorizer
        AddDefaultAuthorizerToCorsPreflight: False
        Authorizers:
          LambdaAuthorizer: 
            FunctionArn: !Sub "arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:LambdaAuthorizer-${StageName}"
          CognitoAuthorizer:
            UserPoolArn: arn:aws:cognito-idp:us-east-1:$account_id:userpool/...

This is still far from ideal, but an acceptable workaround in my opinion, as you can't reuse the function name because CF doesn't support intrinsic functions in any of the template sections where you might define it.

lukacssandor avatar Nov 19 '25 10:11 lukacssandor