Manage variables for deploying a serverless project with different environments

Sharing my thinking about “Manage variables for deploying a serverless project with different environments”

With same codes, I need to define the variables for different environments: dev, staging, production. In serverelsss examples, most values are hardcoded or set in provider or custom session in serverless.yml

So what’s best practice to manage variables for deploying a serverless project with different environments? Here is my way to deal with it, manage environments with different configuration yml files.

Use serverless/examples/aws-node-rest-api-with-dynamodb as sample:

$ cat dev.yml
region: ap-southeast-2
stage: ${opt:stage, self:provider.stage}
service: serverless-rest-api-with-dynamodb
deletion_policy: Delete
read_capacity_units: 1
write_capacity_units: 1

$ cat staging.yml
region: ap-southeast-2
stage: ${opt:stage, self:provider.stage}
service: serverless-rest-api-with-dynamodb
deletion_policy: Retain
read_capacity_units: 2
write_capacity_units: 2
-service: serverless-rest-api-with-dynamodb
+service: ${self:custom.service}

 frameworkVersion: ">=1.1.0 <2.0.0"

+custom: ${file(${opt:stage, self:provider.stage}.yml)}
+
 provider:
   name: aws
-  runtime: nodejs4.3
+  runtime: nodejs6.10
+  region: ${self:custom.region, 'ap-southeast-2'}
   environment:
-    DYNAMODB_TABLE: ${self:service}-${opt:stage, self:provider.stage}
+    DYNAMODB_TABLE: ${self:custom.service}-${self:custom.stage}
   iamRoleStatements:
     - Effect: Allow
       Action:
@@ -63,7 +66,7 @@ resources:
   Resources:
     TodosDynamoDbTable:
       Type: 'AWS::DynamoDB::Table'
-      DeletionPolicy: Retain
+      DeletionPolicy: ${self:custom.deletion_policy}
       Properties:
         AttributeDefinitions:
           -
@@ -74,6 +77,6 @@ resources:
             AttributeName: id
             KeyType: HASH
         ProvisionedThroughput:
-          ReadCapacityUnits: 1
-          WriteCapacityUnits: 1
+          ReadCapacityUnits:  ${self:custom.read_capacity_units}
+          WriteCapacityUnits: ${self:custom.write_capacity_units}
         TableName: ${self:provider.environment.DYNAMODB_TABLE}

I can easily manage the environments with same serverless.yml file.

If you have any opinions on this idea, please join to discuss.

But I can’t set variables from s3/ssm/cf in config yml file. For example,

+ deletion_policy: ${ssm:deletion_policy}

I got below error

  Serverless Error ---------------------------------------

  Inaccessible host: `ssm.'. This service may not be available in the `${self:custom.region, 'ap-southeast-2'}' region.

Any suggestion to fix this issue?

I wrote this a while ago about environment variables. You can use the same approach for other variables (i.e. different read/write capacity on tables for each environment, etc)

http://www.goingserverless.com/blog/using-environment-variables-with-the-serverless-framework

Thanks, @buggy, very informative document.

Seems we are in different approach. I prefer to manage the environments with different env files, which you mix them into one.

For my problem that using ${ssm:deletion_policy} in env file, do you think that’s a bug?