Terraform security with aws-vault

I really like Terraform.

It’s a HashiCorp tool that enables us to treat infrastructure as code and smile more. I can’t speak to the other supported cloud providers but it works really well with AWS. Being an AWS heavy shop with close to 20 separate accounts, we wanted to figure out a good way to securely run terraform without having a ton of keys with admin access floating around on laptops.

That’s where aws-vault comes into play. It stores your AWS keys into your OS keystore (KeyChain on Macs) and then generates temporary credentials from those keys to expose to your shell. The keychain file is password protected and requires your password after a 5 minute timeout. It works really well with the aws-cli and is also aware of your ~/.aws/config file. Best practice is to use IAM roles to temporarily assume to a role that has admin access. You can setup a base IAM user that has the ability to assume role:

Then you can create a terraform admin IAM role that has the AdministratorAccess policy attached along with a trust policy that allows specific users to assume to it.

If you’re managing multiple AWS accounts, you’ll want to add the terraform admin role and trust policy to each account.


Back on your local machine, you want to add your base user keys with aws-vault:

aws-vault add mainUser

Then you can add the various AWS accounts to your ~/.aws/config file:

[profile account1]
source_profile = mainUser
role_arn = arn:aws:iam::accountNumber1:role/terraformadmin_role_name
[profile account2]
source_profile = mainUser
role_arn = arn:aws:iam::accountNumber2:role/terraformadmin_role_name

Once that’s in place you can run:

aws-vault exec <profileName> -- terraform plan

and it should use your temporary AWS keys to assume role to the profile you specify.

Congratulations, now you can run any of the terraform or aws cli commands in a security conscious way!