Serverless Custom Configuration

Some time there is requirement to have mutliple configuration files for different environment.
You might want to have different configuration for test env and separate configuration for prod environment. This article aim to give idea how to configure different environment using serverless framework.

Let say you have configuration file as:

service: new-service
provider:
  name: aws
  stage: dev
  region: west-2

functions:
  hello:
    handler: handler.hello
  events:
    http:
      path: hello
      method: get
  environment:
     apiConnectionTimeout: 20
     SECRET_KEY: 'testing'

Let say you want to make following values dynamic based on env at deploy/run time:

    1. stage
    1. apiConnectionTimeout
    1. SECRET_KEY

Using Configuration Files:

Let say, I have three different env: dev, test and prod.
You can create three files like this:

  • config.prod.yml => Prod environment config file
  • config.test.yml => Test environment config file
  • config.dev.yml => Dev Environment config file
  • Now you can define values(this is dev example, you can change values in other files)

    REGION: west-1
    ENVIRONMENT:
      apiTimeout: 20
      SECRET_KEY: 'dev_testing'
    

    Now your serverless.yml should be modify to this:

    service: new-service
    
    #default configuration is dev
    custom:
      defaultStage: dev
      currentStage: ${opt:stage, self:custom.defaultStage}
    
    provider:
      name: aws
      region: ${file(./config.${self:custom.currentStage}.yml):REGION}
      runtime: python3.6
    
    functions:
      functions:
      hello:
        handler: handler.hello
      events:
        http:
          path: hello
          method: get
      environment:
        apiConnectionTimeout: ${file(./config.${self:custom.currentStage}.yml):ENVIRONMENT.apiTimeout}
        SECRET_KEY: ${file(./config.${self:custom.currentStage}.yml):ENVIRONMENT:SECRET_KEY}
    

    Now you can use any configuration file at deployment time as:

    sls deploy --stage prod --configFile config.prod.yml
    

    For running locally using specific config files at run time:

    # Make sure you have serverless-offline plugin installed locally.
    sls offline start --stage test
    

    Using Command Lines Arguments:
    You can also use command line argument while running your serverless code.
    For That you can modify your serverless as:

    service: new-service
    provider:
      name: aws
      stage: dev
      region: west-2
    
    functions:
      hello:
        handler: handler.hello
      events:
        http:
          path: hello
          method: get
      # These variable now can accept command line argument as well
      environment:
         apiConnectionTimeout: ${opt:apiTimeout}
         SECRET_KEY: ${opt: key}
    

    You can now pass command line argument simply using following commands:

    # Make sure you have serverless-offline plugin installed locally.
    sls offline start --apiTimeout 90 --key 'command testing'
    

    Using Environment Variables:
    To use environment variable at run time, you can modify your serverless.yml file as:

    service: new-service
    provider:
      name: aws
      stage: dev
      region: west-2
    
    functions:
      hello:
        handler: handler.hello
      events:
        http:
          path: hello
          method: get
      # These variable will read files from environment variable
      environment:
         apiConnectionTimeout: ${env:apiTimeout}
         SECRET_KEY: ${env: key}
    

    This will read environment variable set in your environment variable.

    # Setting the environment variable
    export apiConnectionTimeout=90
    export SECRET_KEY='environment testing'
    # Make sure you have serverless-offline plugin installed locally.
    sls offline start
    

    Now you might be wondering, is it possible to combine all these options so you can use at run/deploy time based on your need. Absolutely!! We can do that.

    For that you can define your serverless.yml file as:

    service: new-service
    
    #default configuration is dev
    custom:
      defaultStage: dev
      currentStage: ${opt:stage, self:custom.defaultStage}
    
    provider:
      name: aws
      region: ${env:region, opt:region,file(./config.${self:custom.currentStage}.yml):REGION}
      runtime: python3.6
    
    functions:
      functions:
      hello:
        handler: handler.hello
      events:
        http:
          path: hello
          method: get
      environment:
        apiConnectionTimeout: ${file(./config.${env:api_timeout,opt:api_timeout, self:custom.currentStage}.yml):ENVIRONMENT:API_TIMEOUT}
        SECRET_KEY: ${env:secret_key, opt:secret_key,file(./config.${self:custom.currentStage}.yml):ENVIRONMENT:SECRET_KEY}
    

    The way it works, it would look for environment variable first, if not found, will look for command line argument if not provided then will read variables from config file.
    You can change the order as per your wish!

    Now you can run following command. We have combine all three ways to set variable.
    This command will read dev file for REGION, command line for SECRET_KEY and apiConnectionTimeout from environment variable

    # Setting the environment variable
    export apiConnectionTimeout=90
    # Make sure you have serverless-offline plugin installed locally.
    sls offline start --stage dev --key='testing'
    

    Hope this will help!

    Advertisements

    Leave a Reply

    Fill in your details below or click an icon to log in:

    WordPress.com Logo

    You are commenting using your WordPress.com account. Log Out /  Change )

    Google+ photo

    You are commenting using your Google+ account. Log Out /  Change )

    Twitter picture

    You are commenting using your Twitter account. Log Out /  Change )

    Facebook photo

    You are commenting using your Facebook account. Log Out /  Change )

    Connecting to %s

    Blog at WordPress.com.

    Up ↑

    %d bloggers like this: