Pavel Vlasov

Pavel Vlasov
Jan 30, 2018

Power up serverless framework with javascript configurations

Power up serverless framework with javascript configurations

Building a larger project with serverless framework forces you to break your application into many services. But, yaml and json configurations are not always flexible enough to cover all the needs. Fortunately, 1.26 release will change it all with support of serverless.js files.

Inheritance

There’re bunch of commonly used chunks of configuration copied from one file to another. Now you can easily extend base file or use default settings:

base-serverless.js

'use strict'

module.exports = {
    provider: {
        name: 'aws',
        runtime: 'nodejs6.10',
        stage: '${opt:stage, "dev"}',
        region: '${opt:region, "us-east-1"}',
        memorySize: 128,
        timeout: 10,
        deploymentBucket: {
            name: 'sls-js-config',
        },
    },
}

serverless.js

'use strict'

const merge = require('lodash/merge')
const baseConfig = require('./base-serverless')

module.exports = merge({}, baseConfig, {
    service: 'sls-js-base-config',

    functions: {
        hello: {
            handler: 'index.hello',
            events: [
                {
                    http: {
                        path: 'hello',
                        method: 'get',
                    },
                },
            ],
        },
    },
})

I used lodash merge to extend base-serverless.js.

Composition

Serverless has a mechanism to include settings from external files. But it doesn’t allow you to generate it dynamically or include custom logic. With serverless.js you can use external modules, that’s slightly more flexible:

functions.js

module.exports = {
    hello: {
        handler: 'index.hello',
        events: [
            {
                http: {
                    path: 'hello',
                    method: 'get',
                },
            },
        ],
    },
}

serverless.js

'use strict'

module.exports = {
    service: 'sls-js-composition-config',

    provider: {
        name: 'aws',
        runtime: 'nodejs6.10',
        stage: '${opt:stage, "dev"}',
        region: '${opt:region, "us-east-1"}',
        memorySize: 128,
        timeout: 10,
        deploymentBucket: {
            name: 'sls-js-config',
        },
    },

    functions: require('./functions'),
}

Use cli arguments and environment variables

It’s a tricky one. Because js configuration will be executed in the same process with serverless, it allows you to get access to the cli arguments and environment variables (or even define you own!!!). You’ll need you choice of cli arguments parser (I used commander):

serverless.js

'use strict'

const program = require('commander')

program
    .option('--stage <n>', 'stage')
    .option('--region <n>', 'region')
    .option('--bucket <n>', 'bucket')
    .parse(process.argv)

module.exports = {
    service: 'sls-js-composition-config',

    provider: {
        name: 'aws',
        runtime: 'nodejs6.10',
        stage: program.stage || 'dev',
        region: program.region || 'us-east-1',
        memorySize: 128,
        timeout: 10,
        deploymentBucket: {
            name: program.bucket || 'sls-js-config',
        },
        environment: {
            FOO: process.env.FOO,
            BAR: process.env.BAR,
        },
    },

    functions: {
        hello: {
            handler: 'index.hello',
            events: [
                {
                    http: {
                        path: 'hello',
                        method: 'get',
                    },
                },
            ],
        },
    },
}

I used commander to parse command line and inject properties into configuration. You can implement quite more complex workflows. For example, you are able to inject different properties depending on cli arguments. Another common use case is to configure different domains for different stages.

That’s it!

Thanks for reading! All the examples are available on github (checkout base-config, composition and props-and-env folders).

Would love to hear your suggestions or use cases in comments.

The article was originally posted on medium.