Development, staging and prod environments

Hi!
I’ve done small serverless app using Serverless framework and AWS.
And I’m wondering what is proper way to distinguish environment settings for development (verification), staging and prod environments. I have separate AWS accounts for environments (company requirment)
I have ENV for DB connection to RDS, ARN for AWS Cognito, SG and subnets to distinguish between environments.
Would appreciate any advises on how to do that.

Hi @kukula! I recommend handling this with different JSON config files for each environment. You can then tell Serverless which config file to use based on the stage.

For example, let’s say I have an environment variable called DB_CONN that is my db connection string. I want this to vary across dev, staging, and prod environments. I’d set my serverless.yml with:

# serverless.yml

custom:
  defaultStage: dev
  currentStage: ${opt:stage, self:custom.defaultStage} # 'dev' is default unless overriden by --stage flag


provider:
  name: aws
  runtime: nodejs6.10
  stage: ${self:custom.currentStage}
  environment:
      DB_CONN: ${file(./config.${self:custom.currentStage}.json):DB_CONN}

In the custom block, I’m setting up my stage. My default stage is dev, but I can override it by passing a --stage variable at the command line.

Note the DB_CONN line in the environments section – It pulls the DB_CONN value from a file named config.<stage>.json. Now, I can have three different files in my repository:

# config.dev.json
{
    "DB_CONN": "<db_connection_string_for_dev>"
}
# config.staging.json
{
    "DB_CONN": "<db_connection_string_for_staging>"
}
# config.prod.json
{
    "DB_CONN": "<db_connection_string_for_prod>"
}

Let me know if this works for you!

2 Likes

Thank you for advise alexdebrie1!
What it is best practice with a listed settings like securityGroupIds and subnetIds?

You’re welcome, @kukula!

For lists, you can use an array in your JSON:

# serverless.yml

provider:
  name: aws
  .... <other config settings>...
  vpc:
    securityGroupIds: ${file(./config.$self:custom.currentStage}.json):SECURITY_GROUP_IDS}
    subnetIds: ${file(./config.$self:custom.currentStage}.json):SUBNET_IDS}
# config.prod.json
{
  "SECURITY_GROUP_IDS": ["securityGroupId1", "securityGroupId2"],
  "SUBNET_IDS": ["subnetId1", "subnetId2"]
}

Note that you could also make your config file in YML if it’s easier to write in yml for both your serverless.yml file and your config.prod.yml file:

# config.prod.yml

securityGroupIds:
  - securityGroupId1
  - securityGroupId2
subnetIds:
  - subnetId1
  - subnetId2

Just make sure you’re referencing the proper file name and property within the file.