How to store secrets with Chamber

April 22, 2019

Let’s learn how to tie secrets to IAM roles with Chamber!

Tired of managing environment variables across your team/machines/whatever? Wish they were distributed and tied to IAM roles? Let’s try to do that with chamber.

Chamber Setup

Note: these install instructions apply to macOS. chamber installation should be the same on Linux, though AWS vault will vary depending on your system. Check the readmes for instructions.

Before we start with chamber, you need to create a KMS key with the alias parameter_store_key for chamber to use.

If you use Terraform, you can just use these resource blocks:

https://gist.github.com/slaughtr/f319ed5e30bf5fc750e530284dd39763#file-block1-terraform_kms_key

  
"aws_kms_key" "parameter_store" {
  description             = "Parameter store kms master key"
  deletion_window_in_days = 10
  enable_key_rotation     = true
}

resource "aws_kms_alias" "parameter_store_alias" {
  name          = "alias/parameter_store_key"
  target_key_id = "${aws_kms_key.parameter_store.id}"
}
  

Download chamber (there are many issues using go to install as is outlined in the readme).

  
$: curl -LOs https://github.com/segmentio/chamber/releases/download/v2.3.2/chamber-v2.3.2-darwin-amd64
  

Rename the binary with mv:

  
$: mv chamber-v2.3.2-darwin-amd64 chamber
  

And then make it executable:

  
$: chmod 755 chamber
  

You may need sudo to copy the file, and you may possibly need to chown -R ${whoami}:admin /usr/local/bin beforehand, depending on your version of macOS or the version you originally had installed on your machine. I had to on my work machine, but not on my personal laptop. I don’t remember which versions each started on, unfortunately.

Copy the file to your bin folder:

  
$: cp chamber /usr/local/bin
  

You may need to reload your terminal now, and then which chamber should return /usr/local/bin/chamber.

Now, we need to Install aws-vault, which passes the proper profile into chamber (amongst some other cool features you should check out).

  
$: brew cask install aws-vault
  

Add your default profile to aws-vault — or whichever profile you use as your “root” profile. You can also change default to whatever value you’d like to call this profile in aws-vault:

  
$: aws-vault add default
  

Insert your AWS access and secret access keys in the prompts, then it’s time to test that bad boy! I’m using another AWS profile with an assumed role, though you can also just use your default profile here.

  
$: aws-vault exec otherProfile —- aws s3 ls
  

Should list buckets in otherProfile. If you don’t have any S3 buckets, you can try something like aws iam list-roles

Feel free to replace otherProfile with whichever other role_arn like profile you have in your credentials file, it will Just Work.

And now you can write a secret:

  
$: aws-vault exec otherProfile —- chamber write $SERVICE $KEY $VALUE
  

Where $SERVICE is an arbitrary identifier (IE dw for data warehouse or webfor website related things), $KEY is what you want the secret to be called and referenced by (more on that later), and $VALUE is the actual value of the secret.

Example:

  
$: aws-vault exec otherProfile —- chamber write dw TF_VAR_DATABASE_USERNAME myUsername
  

So now I can read that value:

  
$: aws-vault exec otherProfile —- chamber read dw TF_VAR_DATABASE_USERNAME
Key Value Version LastModified User
tf_var_database_username myUsername 1 04–18 14:29:47 arn:aws:sts::12345….
  

One thing to note from the above: the secret name (key) will be stored lowercase. When you pull it out, it will be converted to upper case. Don’t use case-sensitve secret keys!

Actually Using the Thing

https://flic.kr/p/2bYLk9P
I originally found chamber while looking for a nice way to handle Terraform variables across a team, and it solved that problem very nicely. Some of this is a bit specific to Terraform (well, Terragrunt) but it shows how you actually use chamber, so don’t skip it!

You’ll notice the TF_VAR in the above example. This is because Terraform reads variables from the environment if available, and denotes those via the TF_VAR_ prefix.

So if you have this in your variables.tf:

  
variable “DATABASE_USERNAME” {}
  

Terraform would attempt to read the environment variable TF_VAR_DATABASE_USERNAME when executing a plan or apply.

The thing that chamber helps us out with here is that we don’t need to set the environment variables in our local env for this. chamber will load them in temporarily if we run our command through it:

  
$: aws-vault exec otherProfile —- chamber exec dw —- terragrunt plan
  

This passes our otherProfile profile into chamber, which loads our chamber variables in (from AWS Parameter Store in the otherProfile account) during the execution of terragrunt plan. And very importantly: they do not exist on the host machine after. This means your .zshrc doesn’t have to be 200 lines of miscellaneous API keys for that React app you were trying to help debug last year, and neither does your teammate’s. And when that API key updates, there’s one centralized update for the whole team. And access is restricted. And the data is encrypted. So much better than sending things via Slack!

You should also probably set some aliases for your profiles, so you don’t have to type out that big long command every time.

  
$: alias chmbrop='aws-vault exec otherProfile —- chamber'
  

Then you’d just do chmbrop exec dw —- terragrunt plan. Or maybe you alias the whole thing 🤷‍♀

Serverless Handbook
Access free book

The dream team

At Serverless Guru, we're a collective of proactive solution finders. We prioritize genuineness, forward-thinking vision, and above all, we commit to diligently serving our members each and every day.

See open positions

Looking for skilled architects & developers?

Join businesses around the globe that trust our services. Let's start your serverless journey. Get in touch today!
Ryan Jones
Founder
Book a meeting
arrow
Founder
Eduardo Marcos
Chief Technology Officer
Chief Technology Officer
Book a meeting
arrow

Join the Community

Gather, share, and learn about AWS and serverless with enthusiasts worldwide in our open and free community.