1
votes

To enable AWS_IAM auth and CORS, I made my sam template as follows.

However, I got an error saying

Failed to create the changeset: Waiter ChangeSetCreateComplete failed: Waiter encountered a terminal failure state Status: FAILED. Reason: Transform AWS::Serverless-2016-10-31 failed with: Invalid Serverless Application Specification document. Number of errors found: 1. Resource with id [ListFunction] is invalid. Event with id [ListFunctionCors] is invalid. Unable to set Authorizer [NONE] on API method [options] for path [/list] because the related API does not define any Authorizers.

What is wrong here?

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
  ListApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: Prod
      Auth:
        DefaultAuthorizer: AWS_IAM
      Cors:
        AllowMethods: "'*'"
        AllowHeaders: "'*'"
        AllowOrigin: "'*'"
  ListFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: app_src/
      Handler: app.lambda_handler
      Runtime: python3.7
      Events:
        ListFunction:
          Type: Api
          Properties:
            RestApiId: !Ref ListApi
            Path: /list
            Method: GET
        ListFunctionCors:
          Type: Api
          Properties:
            RestApiId: !Ref ListApi
            Path: /list
            Method: OPTIONS
            Auth:
              Authorizer: 'NONE'
2

2 Answers

2
votes

Just ran into this same problem, and figured it out. Per https://github.com/awslabs/serverless-application-model/issues/781, that function event should be:

ListFunctionCors:
          Type: Api
          Properties:
            RestApiId: !Ref ListApi
            Path: /list
            Method: OPTIONS
            Auth:
              Authorizer: null

It's Authorizer: null, not Authorizer: 'NONE'.

Hope this helps!

2
votes

The solution I found to this issue is more of a workaround. It appears that the source of the error message you get is here

From my understanding, 3 cases are not allowed when you select to have a method authorizer other than AWS_IAM: 1. Having no authorizers defined 2. Selecting an authorizer other than NONE which does not exist in the defined authorizers 3. Selecting NONE as an authorizer without setting a default Authorizer.

The cases above do not handle the case of the AWS_IAM authorizer. It's the only type of authorizer which is only set as the DefaultAuthorizer without having to list it in the Authorizers dictionary.

So the workaround here would be to define a dummy custom authorizer and never use it.

In your case, this could be done like this:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
  ListApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: Prod
      Auth:
        DefaultAuthorizer: AWS_IAM
        Authorizers:
          Dummy:
            FunctionArn: !GetAtt ListFunction.Arn
      Cors:
        AllowMethods: "'*'"
        AllowHeaders: "'*'"
        AllowOrigin: "'*'"
  ListFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: app_src/
      Handler: app.lambda_handler
      Runtime: python3.7
      Events:
        ListFunction:
          Type: Api
          Properties:
            RestApiId: !Ref ListApi
            Path: /list
            Method: GET
        ListFunctionCors:
          Type: Api
          Properties:
            RestApiId: !Ref ListApi
            Path: /list
            Method: OPTIONS
            Auth:
              Authorizer: 'NONE'

I added a custom lambda authorizer in your API, Dummy, which is never used. I used the arn of your already defined lambda, but you could create a placeholder lambda to use instead.

Bottomline: The only way you can currently use Authorizer: 'NONE' in SAM when using only DefaultAuthorizer: AWS_IAM is to add any other authorizer to your API.

Note: The null value for the Authorizer was proposed in the initial GitHub issue, but in the implementation they went for NONE value, as it is described in the documetation.