How to prevent AWS SAM from creating the default "Stage" in API gateway stage
Tags: aws, learning, cloudskills, devops
Published: 2021-05-27 06:55:17

Hello Devs, 

I am going to tell you one AWS SAM issue regarding resource `AWS::Serverless::Api` and transform `AWS::Serverless-2016-10-31` raised over [StackOverflow](https://stackoverflow.com/questions/67697117/aws-apigateway-deploy-to-specific-stage/67703411#67703411) and their solution to tackle temporary basis because this issue still exist. Let me explain what is a problem first. 

**Problem statement** : 

![stage-duplication.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1622028299100/NfnPCI50A.png)
While creating  [AWS Serverless API gateway using SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-api.html)  this configuration to deploy to the 'Prod' Stage along with serverless code sample, but while creating resources it create two stage under API gateway one which you provided as per below example and one is default **Stage**. So if you want to create own Stage can't create it throw you error is `Stage already exists`:

```
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: AWS SAM template with a simple API definition
Resources:
  ApiGatewayApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: prod
  ApiFunction: # Adds a GET api endpoint at "/" to the ApiGatewayApi via an Api event
    Type: AWS::Serverless::Function
    Properties:
      Events:
        ApiEvent:
          Type: Api
          Properties:
            Path: /
            Method: get
            RestApiId:
              Ref: ApiGatewayApi
      Runtime: python3.7
      Handler: index.handler
      InlineCode: |
        def handler(event, context):
            return {'body': 'Hello World!', 'statusCode': 200}

```
There is a bug in AWS SAM whenever you create `StageName` it creates the default Stage along with the stage name which you provided like Prod. First you delete your current one then you can apply these changes.

To solve this issue there is two ways by adding `OpenApiVersion: '2.0'` in your YAML file :

**Solution 1**: Under properties following `StageName` can add this. This properties can be added for `AWS::Serverless::Api` or other resources like `AWS::Serverless::Lambda`.

```
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: AWS SAM template with a simple API definition
Resources:
  ApiGatewayApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: 'V1'
      OpenApiVersion: '2.0'
  ApiFunction: # Adds a GET api endpoint at "/" to the ApiGatewayApi via an Api event
    Type: AWS::Serverless::Function
    Properties:
      Events:
        ApiEvent:
          Type: Api
          Properties:
            Path: /
            Method: get
            RestApiId:
              Ref: ApiGatewayApi
      Runtime: python3.7
      Handler: index.handler
      InlineCode: |
        def handler(event, context):
            return {'body': 'Hello World!', 'statusCode': 200}

```

**Solution 2**: The following to your SAM template at the top level AND be sure you have defined a stage using "StageName" on your AWS::Serverless:Api resource. This will be global level if you have multiple resources like API or lambda etc.

```
Globals:
  Api:
    OpenApiVersion: 3.0.1
    Cors: '*'

Resources:
  ImplicitApiFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: s3://sam-demo-bucket/member_portal.zip
      Handler: index.gethtml
      Runtime: nodejs12.x
      Events:
        GetHtml:
          Type: Api
          Properties:
            Path: /
            Method: get
  ExplicitApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: Prod
``` 

**Note**: This solution works ONLY when one creates an API from scratch. If an API was created before, and the user adds `OpenApiVersion: '2.0'` to it, it doesn't remove the "Stage" stage. It needs to be added from the beginning. Also this example for YAML same can be applied for JSON format.

If you like my blog please like the article, It will encourage me to write more such problem oriented blogs. Do share your valuable suggestions, I appreciate your honest feedback!. If you have any query regarding can reach out to me over my twitter handle [@aviboy2006](https://twitter.com/aviboy2006)

**Reference** :

https://github.com/aws/serverless-application-model/blob/master/tests/translator/input/api_with_open_api_version.yaml#L3
https://github.com/aws/serverless-application-model/issues/191#issuecomment-551051431