Serverless plugin to securely manage environment variables

We have been embracing Serverless to develop products with AWS since over a year and one challenge we faced was handling credentials in our development workflow.

Firstly, storing .env files containing environment variables in our password managers, proved to be a real headache when working in distributed teams. While we track and synchronize code changes with git, every credentials change had to be communicated to and manually integrated by every team member. As we often work on multiple geographically distributed projects, this turned out to not only be an annoying distraction, but also a source of bugs. As we always strive to improve how we work, we asked ourselves: Why not synchronise our credentials with the same ease as the rest of the project?

A new plugin is born

After long discussions about the best way to meet the needs of our projects, we created our first Serverless plugin: serverless-env-generator. This plugin automatically creates an .env file during deployment by merging environment variables from one or more YAML files. Values can be encrypted with AWS KMS. During runtime these variables can then be loaded into process.env using dotenv.

Key features of our plugin include:

Environment variables, which can be loaded with dotenv on startup, without delays from KMS.

Values of environment variables, which can be encrypted with AWS KMS, allowing teams to manage sensitive information in git.

KMS by using which, access to secrets can be controlled with IAM and linked to deployment permissions.

Supporting Multi-stage and custom profile configurations.

A primer on usage

To get started with our plugin, simply follow the instructions on Github. After installing the plugin, environment variables can easily be viewed or changed within Serverless’ CLI interface:

With these commands, a YAML file similar to the one below is created to manage the environment variables. We decided to use YAML files because it is not only a familiar format to every Serverless user, but also an easy way to configure multiple stages within a single file.

During Serverless deployments the plugin reads these YAML files, decrypts the secrets and creates a stage-specific .env file from them:

Finally, using dotenv, the variables in the generated .env file are loaded with _ require('dotenv').config()_ into process.env on execution.

Further information about installation, configuration and usage can be found on the project’s Github site.

Limitations

The uploaded .env file contains secrets in cleartext. With this tool we aim to strike a balance between storing secrets in cleartext in Lambda environment variables and having to decrypt them at runtime using KMS. For critical secrets we recommend to use a tool that decrypts KMS secrets at runtime, for example Serverless Crypt.

Furthermore the tool does not support environment variables generated by Serverless. We recommend to set these variables directly in each functions configuration in serverless.yml.

Our first Serverless plugin

Why did we write our own plugin? While there are a lot of great plugins such as serverless-crypt, none of these plugins matched the requirements we face in our projects. In addition, we viewed creating a plugin as a great learning experience to figure out more about the inner workings of a tool we use. And, of course, it will solve a daily problem and make our lives easier.

It turned out that writing plugins for Serverless is actually pretty simple. Using the plugin in a variety of our projects, we were not only able to reduce the number of bug hunting sessions, but we could also focus more on developing products.

As we could not do our daily work without open source tools, we want to contribute to this community and thus open sourced our plugin under the MIT license. You can find serverless-env-generator on Github and npm.