Storing and injecting AWS ECS environment variables into Docker containers is not trivial if it should be elastic and easy to maintain. Modern-day applications will require you to safely store variables such as API Tokens and services' secrets while allowing you to deploy multiple instances – Dev, QA & Prod, for example. There can be a lot of work to maintain these variables and safely split them between the environments.
In this article, I would like to show how to achieve an elastic way of setting environment variables using the Chamber and AWS SSM Parameter Store.
Assumptions:
- you know how Docker works
- you know and use AWS ECS
What’s the goal?
To create a single storage place for all environment variables used by each service or container for each application environment. The available variables should not be hardcoded anywhere, so adding or changing new ones shouldn’t require rebuilding the entire application.
The following diagram presents the solution:
What tools will we use for managing AWS ECS environment variables?
Chamber
Chamber is a library that will live inside a docker container. It will connect to AWS SSM Parameter Store, load environment variables for the container, and inject them into the main process.
AWS SSM Parameter store
AWS SSM Parameter store is where we will put all the environment variables that we would like to store securely.
Solution
First, let's prepare a simple backend service. For the sake of this example, I will use a simple NodeJS application:
This application will display a value from the `GREETING` environment variable and live inside a docker container.
Dockerfile:
Adding secrets to AWS SSM Parameter Store
There are two ways of adding variables to the AWS SSM Parameter Store. You can do it manually in the AWS console or use a simple script to upload them using CLI.
In this example, I want to store variables so that Chamber can select them for each service and environment. So I'll prefix each variable name with env-{environment}-{service}. Then the parameter name for the GREETING variable for the stage environment will be `env-stage-backend/GREETING`.
Adding manually via AWS console:
Go to Systems Manager > Parameter Store on your AWS account, then press the `Create Parameter` button.
In the form, fill the variable’s name as per the instructions above (with the prefix) and value.
You can select String as a type (for the secrets, we strongly recommend using SecureString).
Adding via CLI:
Let’s use a simple script that will allow us to create and edit multiple environment variables from your command line.
I call this tool `ssm-editor`. It will contain two files:
scripts/run.sh
Dockerfile
Assuming that you built the above image with the `ssmeditor` name and you have your AWS credentials configured correctly, you can run the tool using simple docker command:
Use variables in the Docker container
Now, if you have variables in the correct place, you can pass them into a container that will run inside the ECS task.
To achieve this, you will need to modify the Docker file of the service slightly:
The above code copies the Chamber tool to the final image, making it available to call. Also, the CMD is changed, so Chamber will fetch the correct list of variables and inject them into the nodejs process. Suppose you would like to use this solution with a more production-ready environment. In that case, I suggest replacing the hardcoded variable name prefix with other environment variables that will be defined in the task configuration.
There is only one piece left: IAM permissions. The ECS task role should have access to the AWS Parameter Store and KMS key if you use secure variables. If you are using AWS CDK, the code should look like this:
AWS ECS environment variables with Chamber – the sum up
Above I presented how to inject environment variables into the ECS task from AWS SSM Parameter Store. If you want to try this solution, I prepared a minimal GitHub repository with ready-to-use code with stack and infrastructure written in CDK.
If this article becomes helpful, check the SaaS boilerplate made by Apptension, as this and many more exciting things are included.
Read more: https://aws.amazon.com/blogs/mt/the-right-way-to-store-secrets-using-parameter-store/
Check AWS ECS environment variables with Chamber on GitHub