Anybody who knows me knows that I’m a CloudFormation zealot. I love the way it helps me to provision resources in a repeatable way and easily manage those resources during the lifetime of the CloudFormation stack. Since I was introduced to it several years ago at a re:Invent bootcamp, it has become a core part in everything I do from a Ops/DevOps perspective.
One of the features that CloudFormation has is the ability to define a “NoEcho” parameter. This allows you to supply a value for a parameter, but keep it hidden from both the interface and subsequent API calls that describe the stack and its resources. This helps to keep sensitive values from being accessed, whether by prying eyes or something a little more innocent.
That’s all well and good and great, but it also makes using these values extremely problematic. To supply the needed value for things like configuration management, you’ll need to use a mechanism other than querying the CloudFormation stack itself, and that usually involves some other system to keep track of things. Furthermore, in most use cases that I’ve encountered, even using the value inside the template itself (e.g. in user data scripts or metadata) bypasses the NoEcho protection because the value is then exposed to the API.
An extremely common example of this is templates that have a parameter for the master password of an RDS instance (or any other password, really). The RDS instance gets created just fine, but then what are we to do later? A record of that password must be kept elsewhere because you can’t get it back out by describing the stack at a later time. That’s messy. That’s more steps. That’s extra communication. That’s people not doing or forgetting about things because who wants to be bothered with paperwork?
“You musn’t be afraid to dream a little bigger, darling.” - Eames, Inception
In this series, we’re going to solve that problem by using a Lambda backed custom resource. This custom resource uses the AWS Key Management Service (KMS) to encrypt those sensitive values, and it makes the encrypted form available to both the CloudFormation API and the template itself for use in things like outputs and metadata. That keeps things protected, but it also allows the value to be recovered for use by those with permission to do so.
The code for the Lambda-backed custom resource and an example CloudFormation template used in this series can be found at GitHub. This repository’s README has a much more succinct set of documentation that may be sufficient if you are already pretty familiar with this kind of stuff.
Let’s get started.