Creating A Helpful Plugin For The Serverless Framework
At MySense, we pride ourselves on innovation and resourcefulness. It is for this reason that we have written a plugin for the Serverless Framework, which allows you to publish parameters to AWS SSM as part of your deployment flow.
We use Serverless Framework as it is easy to use and has a rich ecosystem of plugins to help with a variety of tasks. In the rare instance where you may not be able to find a plugin, you can simply write your own.
Serverless Framework Plugins
Plugins for the Serverless Framework can either run as part of your deployment (hooking into a variety of lifecycle hooks) or independently when triggered through the CLI. They have access to any configuration accessible through your serverless.yml file and are able to make calls to AWS services as part of their flow. Some other popular plugins allow you to run your lambdas offline or integrate webpack into your deployment flow.
SSM Publish Plugin
SSM Publish delivers exactly what it promises. It publishes parameters to AWS SSM as part of a deployment flow. Using our plugin, you can provide hard coded values, variable bits of build configuration (such as STAGE vars), or CloudFormation outputs in a simple yaml configuration and store them to SSM. You can store values as Strings, SecureStrings, or Stringlists and provide them as strings or in yaml format. You can pass through descriptions, encryption flags, etc., as part of the configuration for each parameter. The plugin runs after your deployment has finished, so failures will not affect your deployment. This has the added benefit of allowing it to access CloudFormation outputs that were created during the deployment itself. It gives a visual representation of created, updated, and unchanged variables to let you verify your work.
Use Cases and Motivation
We found that what we were missing was a simple way to share information between services as part of our deployment flows. Things like API Gateway Ids or DynamoDB Table names are clearly linked to one service and are defined as part of the infrastructure of that service, but might need to be referenced in another.
One of our main issues was that while you can export CloudFormation outputs and access outputs from one service as part of the deployment of another, this creates a strong link which at times prevents changes to one service due to dependencies in CloudFormation.
AWS SSM, on the other hand, is great for storing and retrieving shared configurations or other values. It also has great integration with the Serverless Framework when it comes to retrieving values, although not necessarily with exporting them.There is no need to limit yourself to values that are generated as part of a specific service. You might want to store configurable values that are shared across multiple services in SSM, but have the peace of mind of defining them in code, allowing rollbacks and avoiding manually creating/changing values.
How To Use The Plugin
Install
In order to start using the plugin, follow the same steps as with any other Serverless plugin. Install it with npm or yarn as a dev dependency, add it to your plugins array in your configuration and you are ready to go.
Usage
Configuration for the plugin itself is handled via a block in the custom section of your serverless.yaml file. The required keys are enabled (to enable/disable the plugin from running), and params (to give a list of parameters you want to store, their values etc). As said above, you can store all three types of values that SSM supports, and pass a variety of configurations for each parameter. You can find the full list in the project readme, and have a look at an example configuration below.
Things To Look Out For
While we have been using the plugin in production for months now, there are some features that we are still working towards at the moment. If you were to use Serverless to remove a service stack, the plugin does not currently delete SSM parameters that it has created. Keep that in mind when it comes to cleanup — however we are looking at implementing this at some point, so watch this space, or feel free to add your own pull request here with another link to the repo.
Written by Fabian Feldberg, Serverless Engineer at MySense