Staging deployment

Hi, I’m hoping to use serverless 1.5 to make my life easier in deploying two restful APIs backed by one handler, that writes to a “prod_dynamo” table and another that writes “staging_dynamo” table.

Issue 1

serverless deploy --stage prod deploys an entire new API?!

Am I missing something? Why doesn’t it uses API gateway’s stages construct? I don’t want to track two different opaque URLs. One is bad enough. :smiley:

Issue 2

~/serverless$  serverless deploy function -f hello --verbose
Serverless: Deploying function: hello...
Serverless: Packaging function: hello...
Serverless: Uploading function: hello (583 B)...
Serverless: Successfully deployed function: hello
~/serverless$  serverless deploy function -f hello --stage prod --verbose
Serverless: Deploying function: hello...
Serverless: Packaging function: hello...
Serverless: Uploading function: hello (583 B)...
Serverless: Successfully deployed function: hello

It’s not clear here how or where the functions were deployed to. Staging or Production? I need to have a better track on this. Ideally need to embed git version into the lambda function actually. How do people accomplish this?

Issue 3

I did see Design Environment Variable Support · Issue #2673 · serverless/serverless · GitHub and I am still a little confused how to simply say in serverless.yml:

Set TABLENAME “staging_dynamo” for dev (Default)
Set TABLENAME “prod_dynamo” for when I do a serverless deploy function -f hello --stage prod --verbose

And how to use TABLENAME from the handler.

I would be grateful to any pointers or examples! Thank you

1 Like

We recently had the AWS solution architects pay us a visit and their advice was the use multiple AWS account and use consolidated billing. This is because there is on 1 Dynamo instance per account. By separating the Prod from staging in different accounts, your code would not need to change ie. staging_dynamo -> prod_dynamo and also provides better security. By doing it this way, this will eliminated using stages.

I agree two AWS accounts is probably best, but I don’t have the time and energy to set up another. :sob:

Esp when API gateway seem to have an API level construct for this!

Issue 1
The Serverless framework doesn’t use the API gateway stages. When it talks about a stage it refers to a complete copy of the environment (API Gateway, Lambda’s, Dynamo DB Tables, etc). I think it’s actually a better solution as it allows you to deploy and test changes without risking the production environment.

Issue 2
It deploys to the stage set in your serverless.yml file (or dev if none is set) by default. You can override this by using the --stage command line option.

Issue 3
You need to use variables in your serverless.yml. My preference is to set resource name in the custom section and use that throughout my config.

custom:
  usersTable: "users-${self:provider.stage}"

profile:
    environment:
      USERS_TABLE: ${self:custom.usersTable}

resources:
  Resources:
    ShopsTable:
      Type: AWS::DynamoDB::Table
      Properties:
        TableName: ${self:custom.usersTable}

Inside your code you use environment variables to find the name of the resource so you don’t need to modify the code for each stage.

While this would allow you to deploy everything to a single AWS account the best practice is to use one account per stage with consolidated billing as @fracca said.

I’ll try to do a full write-up of this later today.

1 Like

Thank you buggy for your reply.

The issue is that I expect at the very least verbose output to tell me I am deploying to the $stage (dev as default)! :smiley:

I also expect to pull dev into my serverless config. Neither ${self:custom.stage} or ${opt:stage} works with a simple severless deploy. Why ${opt:stage} isn’t set to dev by default? :sob:

Sorry, I eventually found self:provider.stage to work even though stage was not set in provider. YASSS. :clap: a default that works.

1 Like

Sorry about that. I quickly copied a the code from a config file and forgot to update it correctly.

Rich

I found this example, but I haven’t tested it out yet. Use the “myStage” variable in your serverless.yml file, which will use the opt:stage if it is set, or else default to self:provider.stage. I think I would leave self:provider.stage set to dev to keep this as the default behaviour, and set to production when I need to using the --stage command line option.

custom:
       myStage: ${opt:stage, self:provider.stage}