In this article I will be looking at if and when the AWS Parameter Store should be used to replace environment variables within the AWS infrastructure. I will not be looking at what each of these are or how to set them up in any in-depth way but rather a comparison between the two.
A case for environment variables
Easy to setup
It is pretty simple to get setup with environment variables. Node, for example, has a dotenv module that can be installed via npm with a single command:
npm install dotenv
We need to make sure that dotenv has an entry point somewhere in our script, usually via a require statement –
From here, all we need to do is add our enviroment variables to a .env file placed in the root folder of the project.
You can find more information on the dotenv module here:
It should be noted that the Parameter Store does not initially share the same aspects in ease of setup — if you have never worked with the Parameter Store before, the setup process can seem quite laborious with a few things to consider:
- You need access to an AWS account
- You need know how to navigate the AWS dashboard — specifically the SSM section.
- Sensitive/Secure parameters should be encrypted with KMS — which in itself requires some additional setup (https://aws.amazon.com/kms/)
- Depending on your needs, you may need configuration knowledge of other AWS services such as IAM and SSM order to get the Parameter Store to work correctly.
- All parameters are hosted on the cloud requiring IAM programatic access, which means an uninterrupted connection is required (it should be noted that bespoke local setups can be created with local variables that can be used in place of Parameter Store variables depending on the situation— I would in fact encourage this kind of approach).
Easy to update during development, deployment and testing
Environment variables can easily be updated via the aforementioned .env file and dotenv module. Variations of this file can also be created and utilised to suit each relevant environment. Importing our enviroment variables in a testing scenario works in much the same way (importing env vars from the relevant dotenv file).
For deploying to a staging or production server, all we would do is use an alternate version of the .env file. This can easily be done by ignoring the existing .env file in your version control system locally (usually git) and creating a new copy on each stage / server instance.
Environment variables also integrate nicely with Continuous Integration systems (CI). Circle CI, for example, has a dedicated section for managing environment variables where they can be added at a project build level and updated in a single place when ready for deployment —
From a Parameter Store perspective, it is language / framework agnostic, meaning all setup will either need to be done manually using an AWS SDK with programatic access to the Parameter Store service, or similarly through a 3rd party provider (such as an npm module). While AWS and its services are the benchmark for security standards in the cloud computing domain, custom modules that you might want to develop or utilise may have security vulnerabilities due to malice or oversight — bearing in mind that there are industry accepted modules for this that are maintained and endorsed by trusted entities such as AWS themselves.
From a deployment / testing perspective the Parameter Store also comes with a unique set of challenges, as although there are suggested approaches, how and when you choose to interact with the Parameter Store is entirely up to you.
Enviroment Variables are free to use
Although AWS Parameter Store does not include additional charges (https://aws.amazon.com/systems-manager/pricing), Amazon’s pricing structure for related services such as KMS (https://aws.amazon.com/kms/pricing) will start to incur additional costs based off of usage. On the other hand, using environment variables is free.
So why replace environment variables?: a case for the Parameter Store
Up to this point the vanilla environment variable solution seems to be edging the Parameter Store in the race for dominance in the stage/secure variable arena. While the Parameter Store does seem to create more challenges than it solves at this point, there are a few things, however, that the Parameter Store undisputedly does better than environment variables:
Parameter Store variables can be shared across multiple projects
The best setup I have found for sharing environment variables across projects is to use an automated deployment process that fetches environment variables from a file contained in a shared entity, such as a S3 bucket which plugs into the project configuration as needed (usually done through a script that is run from a CI service). From previous experience, this is the most semantically viable option (please let me know if you have experience with any better options). This is unfortunately a tedious exercise initially and ultimately not something you would want to maintain manually in the long run, which is mainly because any mistakes or oversights along the way when setting up or maintaining it could lead to problems.
Everything that we can hand over to an AWS service to automate, we should and this is where the Parameter Store shines. Sharing KMS keys and Parameter Store variables across projects comes out-of-the-box.
I want to take step back and look at AWS from a holistic perspective. Amazon has done a great job at managing every aspect of cloud computing, and has a plethora of development teams dedicated to specific services that you and I will never be able to replicate. This ultimately means that once you have bought into the Amazon ‘experience’ you should make use of all of the services designed to work together under the banner of AWS cloud infrastructure. Although it has its issues (such as you and I now being completely locked into AWS as a service provider), it is ultimately easier to offload everything you can to them, as it is one less thing you need to worry about — even if it costs a little extra.
Parameter Store can use access control
Having specific control over user access makes the IAM service one of AWS’s greatest attributes, especially when it comes to dealing with potentially sensitive information such as API keys or passwords. The concept of controlling access to environment variables within the vanilla sense (e.g. using the dotenv approach) is just not an option (unless you are willing to develop your own bespoke solution — or move outside of the realm of ‘best practices’).
Parameter Store values are easily updated
In order to update any values in your Parameter Store all you need is appropriate access to your AWS dashboard (or the CLI), meaning that even non-technical team members can update values with a bit of AWS dashboard experience.
On the environment variable side of the argument updating environment variables becomes problematic as usually only skilled team members who have access to server update permissions will be able to access and update these. Additionally this opens up your project to a layer of vulnerability, as logging into a server and updating core project files on the fly (even on an automated setup) can lead to issues.
KMS can encrypt Parameter Store values easily
Although the initial setup of encrypting values in the Parameter Store might seem a bit daunting, once you get used to it, it is quite simple and makes a lot of sense — even from a non technical perspective. This is also a great layer of security that is added, out-of-the-box.
It is possible to use encryption for environment variables that you may not want to store in plain text, but this can be difficult to setup and maintain manually.
Parameter Store variables can be organised
Production and Staging parameters are managed in a single place when using the Parameter Store, which includes sorting and filtering parameters and even adding descriptions to clarify their purpose.
From an environment variable perspective you just don’t get out-of-the-box variable organisation. Having a few environment variables might be easy enough to manage, but this becomes problematic when there are too many variables to manage manually. It may be possible to organise environment variables into different files and folders, but there really isn’t a viable out-of-the-box solution for this that doesn’t seem to complicate things unnecessarily.
Ultimately, the decision around which of the two solutions to use should be determined by the complexity and scope of the project, taking into account the factors mentioned above.
There are other factors to take into consideration when choosing whether to use the Parameter Store or environment variables to manage your stage / secure parameters, but hopefully in this article we have covered the important ones.
If you have any other factors that you feel are worth consideration I would like to hear your thoughts.