There are many ways to use ‘secrets’ in ECS and ECS Fargate. Most of the time they are exposed using Environment variables, because a few years ago this was the only easy option. Today we have two improved options. You could add a tool to your docker container which retrieves and decrypts your secrets before parsing them to the application. The other one is to embed the retrieval and decryption in the application. Both approaches are covered in this blog post. This is what we are going to do:
- Put a secret in the SSM Parameter Store
- Add the ssm-env tool to your Dockerfile to replace secrets at ‘boot time’
- Add some logic to your application to retrieve secrets
- Add a reference to the secret in container environment variables using CloudFormation
1. Put a secret in the SSM Parameter Store
This time we add the secret manually, for example in case of a third party api key shared with you. You could also generate a secret using the CloudFormation extension, for example when you want to generate a secret which nobody should know, even you. (Do not forget to restrict access to the SSM Parameter Store.)
2. Add the ssm-env tool to your app
Now add the following code to your Dockerfile. It will download and validate the ssm-env
tool written in golang. To access the AWS APIs like SSM, you need to install certificates. Check out the complete dockerfile here.
It will iterate all environment variables and search for the ssm://
prefix. When found, it will use the IAM role of the container to retrieve the secret and replaces the value for the secret. For example:
3. Add some logic to your application to retrieve secrets
In this example the public Docker image: mvandongen/alittlesecret is used, which is just a very simple Python Flask application. The first section will retrieve the SSM secret using the SDK. The secret in the second part is already decrypted. This is probably used for (legacy) applications or applications that you cannot easily change.
4. Add a reference to the secret in container environment variables using CloudFormation
Let’s deploy this Fargate container using CloudFormation. It works well in any public VPC, also the default VPC.
Because of the few parameters which are easy to select, we deploy the stack using the console. You could also use the cli if you want.
Now find the public IP address of the Docker container running in Fargate, and use curl or a web browser to check out the decrypted secrets. Also try to find the secrets in the AWS Management Console. It is not visible in the CloudFormation console, not in the ECS Fargate console. It’s only visible in the SSM Parameter Store.
Conclusion
In this blog post we have created a secret in the AWS SSM parameter store and retrieved it in a Docker container, without exposing it anywhere in the Management Console. By using the SDK, the programmer makes sure the secret is only retrieved and used where needed, this is most secure.
In the second example, from the application perspective, it’s just an environment variable within the container. When you leak all env vars, you also leak your secret, making this less secure.
It now becomes really easy to rotate secrets. It even doesn’t require a deployment.