aws / serverless-application-model

The AWS Serverless Application Model (AWS SAM) transform is a AWS CloudFormation macro that transforms SAM templates into CloudFormation templates.
https://aws.amazon.com/serverless/sam
Apache License 2.0
9.36k stars 2.38k forks source link

SAM Creates stage named "Stage" by default? #191

Closed sdole closed 5 years ago

sdole commented 7 years ago

I have a template like this:

AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Resources:
  Api:
    Properties:
      StageName: dv01
      DefinitionUri: api_spec_SAM.json
    Type: AWS::Serverless::Api

After package and deploy with the cli, it creates an API with two stages named "Stage" and "dv01". In reality, I do not want to create either stages. The StageName property is "required". Not sure why. My intention is to create a separate set of templates to create the stages, deployments, lambda function versions etc.

The reason I need separation is because we have multiple code pipelines that are owned by different people (dev, build teams). I would like these templates to live in separate git repos.

Is there a way to create an API without any stages?

Else, the work around is to simply ignore this one default stage created via SAM. Thanks!

adam-roweit commented 5 years ago

@Daniel-Redmond Ah that makes perfect sense, thanks for your help!

jlhood commented 5 years ago

Yes, this is a known issue with SAM CLI and should be addressed in the next SAM CLI release. @Daniel-Redmond Thanks for the great explanation!

azarboon commented 5 years ago

To get around this bug, we added the fix for it behind the OpenApiVersion flag. To opt into this fix, you would need to specify OpenApiVersion flag like here. Regardless of the value (2.0, 3.0.1, etc), the stage stage fix will be applied if the flag is present.

Thanks. I tried it. This solutions works ONLY when one creates API from scratch. If an API was created before, and user adds OpenApiVersion: '2.0' to it, it doesn't remove "Stage" stage. It needs to be added from the beginning. Here is my code:

  MyApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: dev
      Cors:
        AllowMethods: "'GET,POST,DELETE,OPTIONS'"
        AllowHeaders: "'authorization'"
        AllowOrigin: "'*'"
      OpenApiVersion: '2.0'
keetonian commented 5 years ago

Correct, I noticed this as well. CFN doesn't delete the extra stage, but that extra stage does stop getting updates from your CFN stack. To get rid of the extra stage, you have to manually delete it in ApiGateway (using either the CLI or console) and then it won't be created/updated any more if you have the OpenApiVersion flag set.

rainabba commented 4 years ago

I've found the solution thanks to @azarboon and https://github.com/awslabs/serverless-application-model/issues/191#issuecomment-551051431

To avoid the unwanted "Stage" stage AND not get errors if you've already ended up with one, add 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 or otherwise.

I had to [for now] exclude the CORS options shown in the template provided in that post (this one).

Globals:
  Api:
    OpenApiVersion: 3.0.1
alnaranjo commented 4 years ago

Thanks a lot! This worked perfectly.

wesgt commented 4 years ago

Thanks a lot! This solved my doubts.

rainabba commented 4 years ago

Another (and perhaps the "better" approach) is to use AutoPublishAlias to control the name of the alias that will be used and automatically get new code. Below is an example of how to use this AND another alias to maintain a "staging" alias (latest code, will always point to the newest version deployed through SAM deploy) and a "live" alias (production code that must be updated to a newer version by some other mechanism). Note, this does depend on a custom resource to get the latest version (how I maintain the staging alias version). That's out of the scope here, but I'll share that code on request. More good info at sam-function-autopublishalias and automating-updates-to-serverless-apps.

SampleLambdaFunction:
    Type: AWS::Serverless::Function
    Properties:
        FunctionName: SampleLambda
        AutoPublishAlias: staging
        CodeUri: src/
        Handler: SampleLambda.handler
        Runtime: nodejs12.x
SampleLambdaLiveAlias:
    Type: AWS::Lambda::Alias
    Properties:
        FunctionName: !Ref SampleLambdaFunction
        FunctionVersion: !GetAtt SampleLambdaGetMaxVersionFunction.version
        Name: live
rainabba commented 4 years ago

I've also setup a stackoverflow question to see if anyone has a better approach: how-to-use-sam-deploy-to-get-a-lambda-with-autopublishalias-and-additional-alises

AvinashDalvi89 commented 3 years ago

To get around this bug, we added the fix for it behind the OpenApiVersion flag. To opt into this fix, you would need to specify OpenApiVersion flag like here. Regardless of the value (2.0, 3.0.1, etc), the stage stage fix will be applied if the flag is present.

Thanks. I tried it. This solutions works ONLY when one creates API from scratch. If an API was created before, and user adds OpenApiVersion: '2.0' to it, it doesn't remove "Stage" stage. It needs to be added from the beginning. Here is my code:

  MyApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: dev
      Cors:
        AllowMethods: "'GET,POST,DELETE,OPTIONS'"
        AllowHeaders: "'authorization'"
        AllowOrigin: "'*'"
      OpenApiVersion: '2.0'

Thanks for this.

iongion commented 3 years ago

Still facing the same issue - they all end in Stage or Prod, no matter my input parameter

image

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: SAM Template for annotator

Globals:
  Function:
    Timeout: 600
    MemorySize: 512
    Runtime: nodejs12.x
  Api:
    OpenApiVersion: '3.0.1'
    # See https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessapi
    BinaryMediaTypes:
      - "*~1*"

Parameters:
  StageName:
    Type: String
    Default: dev
    Description: (Required) Enter dev, test, stag, prod. Default is dev.
    AllowedValues:
      - dev
      - test
      - stag
      - prod

Resources:
  AnnotatorApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: !Ref StageName
      Auth:
        DefaultAuthorizer: JWTCustomAuthorizer
        Authorizers:
          JWTCustomAuthorizer:
            FunctionArn: !GetAtt AnnotatorApiAuthorizerFunction.Arn
specious commented 3 years ago

I just opened issue aws/aws-sam-cli#3247 because StageName: !Ref Stage is being treated as an empty stage name (albeit template validation passes because the 'required' StageName property is technically present).

@iongion, what you're describing where whichever value you choose for your StageName parameter seems to take no effect sounds like running into the same issue.

aprilmintacpineda commented 3 years ago

StageName: !Ref Stage

Which will be weird because doing StageName: !Ref Stage actually deploys two stages, the actual value of !Ref Stage (say dev), and another one called "Stage".

aprilmintacpineda commented 3 years ago
  API:
    Type: AWS::Serverless::Api
    Properties:
      Name: myapp-api
      StageName: !Ref Stage

It creates a stage for whatever I provided in !Ref Stage and then it creates another one called Stage.

image

and !Ref Stage was resolved to dev but as you can see, there's an extra Stage in there, who created that? where that came from? Is still a mystery left unsolve.

specious commented 3 years ago

My apologies, I misinterpreted what was happening because StageName: !Ref Stage creates an AWS::ApiGateway::Stage resource with logical id <gateway-resource-id>Stage rather than <gateway-resource-id><StageName>Stage, which is the case when StageName is hard-coded.

My stages are being deployed correctly, however it may be so because I've been using:

Properties:
  OpenApiVersion: 3.0.3
simplyi commented 2 years ago

hmm... When I use OpenApiVersion: 3.0.3 in my SAM template, I can deploy to one stage only. If I try to deploy to a new stage, the previous stage gets deleted. Is there a way to tell SAM not to delete a previously created stage? If I create the second stage manually, then sam refuses to deploy to that new stage because it already exists...

How do you guys configure sam so that it can keep two stages and deploy to a specified stage?

ptejada commented 2 years ago

@simplyi See https://stackoverflow.com/questions/68826108/how-to-deploy-to-different-environments-with-aws-sam You basically need to have different stacks. You can't control multiple API Gateways Stages from a sam template.

TingyuShare commented 2 years ago

add OpenApiVersion works for me, it will delete the stage and rebuild: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-api.html#sam-api-openapiversion

nikitasius commented 2 years ago

perfectly works (no stage created), but i have a strange issue #2377

cookiejest commented 3 months ago

This seems like a fundamental flaw of the SAM approach that this has been left open for years without being properly solved. I will use terraform based approach because of this as it seems more stable.