Stages in Serverless Framework

From @jayair on Fri Oct 06 2017 22:39:56 GMT+0000 (UTC)

Link to chapter - https://serverless-stack.com/chapters/stages-in-serverless-framework.html

Copied from original issue: https://github.com/AnomalyInnovations/serverless-stack-com/issues/149

Could someone help further explain how to set up stages for API endpoints?

Right now, I have 3 stages setup: DEV, STAGING, and PROD. Each work with my frontend, but only with the latest deployment. For example…

  • I deploy the API to DEV, I can’t access the STAGING or PROD APIs anymore from the client.
  • I deploy the API to STAGING, I can’t access the DEV or PROD APIs anymore from the client.
  • I deploy the API to PROD, I can’t access the DEV or STAGING APIs anymore from the client.

I looked into it and in the API Gateway, the stages are being created without a problem. However, the lambda functions backing the API are replaced with each stage. So, if I have a DEV-{function} lambda function, when I deploy using --stage STAGING, it is replaced with STAGING-{function}. I would expect DEV-{function} to not get replaced and STAGING-{function} to just be added (or updated).

I think this might be me misunderstanding the concept, as it’s explained that it is better to have separate APIs, one for each stage. However, I don’t know how to set this up in the serverless.yml.

Can anyone help?
Thanks in advance!

So the process you described of how Lambda functions are named based on the stage is accurate. However Serverless Framework does not replace them. It duplicates them. So you’ll have multiple versions of the Lambda function and API endpoints tied to the stage that you create.

In our guide we have two stages and the frontend of the app has both listed in the config:

For reference, here is the backend that we deploy:

I’m not sure why your endpoints are not accessible anymore. What’s the error that you are getting?

1 Like

Specifically, I get a 500 error when hitting an API endpoint that I didn’t deploy last. The endpoint that I most recently deployed is accessible. For example, I just ran serverless deploy --stage DEV yesterday and my lambda statements look like this:

I can hit my API ~/DEV successfully. However, when I run serverless deploy --stage STAGING all those functions are replaced. I end up with…

  • STAGING-submit-module
  • STAGING-get-course
  • STAGING-get-module

and my DEV functions are no longer there. Then, I can’t hit my ~/DEV api anymore, but I can hit my ~/STAGING now.

Hey Cpritch,

can you maybe provide your github repo to this?
Would love to look at the files and figure out why its doing this.

I can’t provide the source code for this, but I could provide pieces of it. Perhaps my serverless.yml would be helpful?

Here’s my serverless.yml. I replaced some of the identifying names with arbitrary ones.

service: my-service-name

# Create an optimized package for our functions
package:
  individually: true

plugins:
  - serverless-bundle     # Package our functions with Webpack
  - serverless-offline
  - serverless-delete-loggroups

provider:
  name: aws
  runtime: nodejs10.x
  stage: ${opt:stage, 'DEV'}
  region: us-east-1
  stackName: my-stack-name
  apiName: my-api-name
  logRetentionInDays: 7
  iamRoleStatements:
    - Effect: Allow
      Action:
        - dynamodb:DescribeTable
        - dynamodb:Query
        - dynamodb:Scan
        - dynamodb:GetItem
        - dynamodb:PutItem
        - dynamodb:UpdateItem
        - dynamodb:DeleteItem
      Resource: "arn:aws:dynamodb:us-east-1:*:*"
  deploymentBucket:
    name: my-deployment-bucket
    blockPublicAccess: true
  environment:
    stage: ${self:provider.stage}

functions:
  get-course:
    name: ${self:provider.stage}-get-course
    handler: src/get-course.main
    events:
      - http:
          path: course
          method: get
          cors: true
          authorizer: aws_iam
  submit-module:
    name: ${self:provider.stage}-submit-module
    handler: src/submit-module.main
    events:
      - http:
          path: course/{moduleNo}
          method: post
          cors: true
          authorizer: aws_iam
  get-module:
    name: ${self:provider.stage}-get-module
    handler: src/get-module.main
    events:
      - http:
          path: course/{moduleNo}
          method: get
          cors: true
          authorizer: aws_iam

# Create our resources with separate CloudFormation templates
resources:
  # API Gateway Errors
  - ${file(resources/api-gateway-errors.yml)}

Maybe not serverless.yml -> don’t think this is the file that has an issue.

Doesn’t this cause our environment variable values to end up in version control since we are entering them directly in serverless.yml file? Thanks.