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

Bug: aws-sam-cli version 1.80 An invalid OpenApi version was detected

Open shzxcv opened this issue 2 years ago • 11 comments

Description:

openapi.yml

openapi: 3.0.3
info:
  title: test
  description: test
  version: 1.0.0

I can get the error that

$ sam local start-api
Error: An invalid OpenApi version was detected: '', must be one of 2.x or 3.x
make: *** [debug] Error 1

Steps to reproduce:

AWS SAM

Observed result:

Error: An invalid OpenApi version was detected: '', must be one of 2.x or 3.x

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

  1. OS: mac
  2. sam --version: SAM CLI, version 1.80.0
  3. AWS region: ap-northeast-1
{
  "version": "1.80.0",
  "system": {
    "python": "3.8.16",
    "os": "macOS-12.3.1-arm64-arm-64bit"
  },
  "additional_dependencies": {
    "docker_engine": "20.10.14",
    "aws_cdk": "Not available",
    "terraform": "Not available"
  }
}

shzxcv avatar Apr 18 '23 07:04 shzxcv

Thanks for reporting this, can you post a sample template with resources that consume this OpenApi spec file? I am not able to reproduce this with the following examples:

template.yaml:

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

Resources:
  HttpApiOpenApi:
    Type: AWS::Serverless::HttpApi
    Properties:
      DefinitionUri: test.yaml

test.yaml:

openapi: "3.0.3"
info:
  title: HttpApiOpenApi
components:
  securitySchemes:
    Simple:
      type: apiKey
      in: header
      name: unused
      "x-amazon-apigateway-authorizer":
        authorizerPayloadFormatVersion: "2.0"
        enableSimpleResponses: true
        type: "request"
        identitySource: $request.header.header, $request.querystring.query
        authorizerUri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${AuthorizerFunction.Arn}/invocations
paths:
  "/simple":
    get:
      security:
        - Simple: []
      x-amazon-apigateway-integration:
        payloadFormatVersion: "2.0"
        httpMethod: POST
        type: aws_proxy
        uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${HelloWorldFunction.Arn}/invocations

lucashuy avatar Apr 18 '23 16:04 lucashuy

@lucashuy OK, I show you all the files.

  • template.yml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: test

Parameters:
  ENV:
    Type: String
    AllowedValues:
      - snd
      - dev
      - prd
    Default: snd

Resources:
  APIStack:
    Type: AWS::Serverless::Application
    Properties:
      Location: template/api.yml
      Parameters:
        ENV: !Ref ENV
  • template/api.yml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: test

Globals:
  Function:
    Timeout: 60

Parameters:
  ENV:
    Type: String

Resources:
  AuthAPI:
    Type: AWS::Serverless::Api
    Properties:
      Name: !Sub "auth-${ENV}-api"
      StageName: auth
      EndpointConfiguration: REGIONAL
      MethodSettings:
        - LoggingLevel: INFO
          MetricsEnabled: true
          HttpMethod: '*'
          ResourcePath: '/*'
      Auth:
        ApiKeyRequired: true
      DefinitionBody:
        Fn::Transform:
          Name: AWS::Include
          Parameters:
            Location: ./openapi.yml

  AuthFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: !Sub "auth-${ENV}-function"
      MemorySize: 2048
      CodeUri: ../cmd/
      Handler: main
      Runtime: go1.x
      Tracing: Active
      Environment:
        Variables:
          ENV: !Ref ENV
      Events:
        HelloAPI:
          Type: Api
          Properties:
            Path: /hello
            Method: get
            RestApiId: !Ref AuthAPI

  AuthFunctionLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub "/aws/lambda/auth-${ENV}-function"
  • template/openapi.yml
openapi: 3.0.3
info:
  title: test
  description: test
  version: 1.0.0

paths:
  /hello:
    get:
      summary: return hello
      description: hello world
      responses:
        '200':
          description: successfull
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Success'
      x-amazon-apigateway-integration:
        uri:
          Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${AuthFunction.Arn}/invocations
        passthroughBehavior: when_no_templates
        httpMethod: GET
        type: aws_proxy

components:
  schemas:
    Success:
      description: successfull
      type: object
      Properties:
        message:
          type: string
      required:
        - message

shzxcv avatar Apr 19 '23 04:04 shzxcv

At the moment, we do not current support nested stacks with local start-api (see #3306). Is it possible to extract the serverless API out and have that as a deployable stack as a possible workaround for now?

lucashuy avatar Apr 19 '23 17:04 lucashuy

The 1.79.0 version works with this configuration. With 1.80.0, I get an issue error.

shzxcv avatar Apr 20 '23 01:04 shzxcv

Hi, sorry about the incorrect assertion from before, it looks like the locations in the yaml files are relative where command is run, not where the file is located. Inside of template/api.yml, can you change the location to Location: template/openapi.yml for the Serverless Api resource?

lucashuy avatar Apr 21 '23 21:04 lucashuy

@lucashuy I have made the changes exactly as they were made, but the error seems to be the same. Obviously the behavior seems to have changed between 1.79 and 1.80.

Location: template/openapi.yml

shzxcv avatar Apr 25 '23 01:04 shzxcv

We have the same issue in our project. The problem occurs with 1.80 and 1.84, but on 1.79 it runs ok.

POlczak-ITTouch avatar May 31 '23 13:05 POlczak-ITTouch

Could you provide a reproducible example? In the OP, paths should be relative to the working directory, not the location of the file.

Debug output from the original reproducible example:

2023-05-31 15:51:13,794 | Successfully parsed location from AWS::Include transform: ./openapi.yml
2023-05-31 15:51:13,794 | Trying to download Swagger from ./openapi.yml
2023-05-31 15:51:13,794 | Unable to download Swagger file. File not found at location /Users/lucashuy/<folders>/5035/./openapi.yml
2023-05-31 15:51:13,794 | Found '0' APIs in resource 'AuthAPI'
2023-05-31 15:51:13,794 | Found '1' API Events in Serverless function with name 'AuthFunction'
2023-05-31 15:51:13,794 | Removed duplicates from '1' Explicit APIs and '0' Implicit APIs to produce '1' APIs
2023-05-31 15:51:13,794 | 1 APIs found in the template

This is still able to find an API since there is one implicitly defined under the Lambda Function, however if we take a look at the lines above that we can see that it's trying to find the file under the project root, not under template/.

After updating the path to Location: template/openapi.yml:

2023-05-31 16:01:23,518 | Detected Inline Swagger definition
2023-05-31 16:01:23,518 | Resolved Sub intrinsic function: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/arn:aws:lambda:${AWS::Region}:123456789012:function:AuthFunction/invocations
2023-05-31 16:01:23,519 | Extracted Function ARN: arn:aws:lambda:${AWS::Region}:123456789012:function:AuthFunction
2023-05-31 16:01:23,519 | Found '1' APIs in resource 'AuthAPI'
2023-05-31 16:01:23,519 | Found '1' API Events in Serverless function with name 'AuthFunction'
2023-05-31 16:01:23,519 | Removed duplicates from '2' Explicit APIs and '0' Implicit APIs to produce '1' APIs
2023-05-31 16:01:23,519 | 1 APIs found in the template

Here it is able to find the Swagger definition since the Location resolution is off the working directory. We can see this, as it found an endpoint for AuthAPI and we see that it removed the duplicate.

The reason why this is failing now (>=1.80.0), is that we explicitly check for an OpenApi version when parsing a body definition. Since it isn't able to resolve the file location, the document is not loaded.

lucashuy avatar May 31 '23 23:05 lucashuy

I have the same issue with sam cli version 1.104.0 when running sam local start-api.

alexandervantrijffel avatar Jan 12 '24 08:01 alexandervantrijffel

Sorry, I wasn't able to provide a reproducible example, because our project is quite big and carving out a small-enough stub, which still would show this behavior on the newer versions would take a lot of work we couldn't afford at that time...

@alexandervantrijffel Would it be possible for you to provide a reproducible example?

POlczak-ITTouch avatar Jan 12 '24 10:01 POlczak-ITTouch

sorry for reigniting this one but using last version of sam as of this writing (1.119.0), the behaviour is as follows:

  1. if we use non relative path with openapi.yaml then the start-api works locally but the sam deploy fails with: Parameter Location of resource AWS::Include refers to a file or folder that does not exist /Users/user/projects/stuff-api/cloudformation/api/api/openapi.yaml because it needs relative path.
  2. using relative path doesn't work with start-api but works with sam deploy command

alez007 avatar Jun 19 '24 13:06 alez007