Using aws-vault with Linux
~/.aws/credentials sucks - but don't worry, you have options.
There are lots of purported "best practices" out there on the internet regarding AWS API keypairs. In this author's opinion, the term best practices is in many cases either a dubious claim or a concept that isn't actually real, since "best" is often subjective or situation dependent. However, with regard to AWS API keypairs and developer machines, I'll argue that there really is a best way.
I was recently introduced to aws-vault by an acquaintance from the HangOps slack team. Succinctly put, it solves two significant problems:
- Leaving a keypair lying around on disk, accessible in plain text from your ~/.aws/credentials file, really sucks. It's not necessarily terrible if you're enforcing role assumption and 2fa, and if your disk is encrypted at rest, and if you never walk away from your machine without locking it - but that's several ifs.
- The 1h timeout on credentials gained from assuming a role sucks.
Enter aws-vault - which stores credentials and session data in your keychain and is capable of handling renewal transparently. Usage is well documented for OSX and outside the scope of this article, which tells you how to do it with Gnome (or Cinnamon - which is what I use). I've used the same process on both Ubuntu 16.04 and Fedora 27 with success. While simply using an encrypted file works just fine, I prefer to use the keychain!
- Ensure that gnome-keyring is installed.
- Ensure that that
gnome-keyring-daemonis running - I put these lines in my ~/.bash_profile:
if [ -n "$DESKTOP_SESSION" ];then eval $(gnome-keyring-daemon --start) export SSH_AUTH_SOCK fi
Under Linux, aws-vault defaults to using encrypted files. Therefore, you'll need to specify a backend via env var. In
You're set to begin adding credentials:
aws-vault add $someprofilename- This will prompt you for an AWS Access Key ID and AWS Secret Access Key pair
You now have a keypair stored in aws-vault - however, a little more setup is required for assuming roles. This is done a bit like how the ~/.aws/credentials file normally functions, only it's done in ~/.aws/config - aws-vault adds the [profile someprofile], you just need to add profiles which use its keypair for assuming a role:
[profile someprofile] [profile ops] role_arn = arn:aws:iam::12345678910:role/some-role source_profile = someprofile mfa_serial = arn:aws:iam::23456789101:mfa/connor_rielly [profile k8s] role_arn = arn:aws:iam::34567891011:role/another-role source_profile = someprofile mfa_serial = arn:aws:iam::23456789101:mfa/connor_rielly [profile blog] role_arn = arn:aws:iam::456789101112:role/third-role source_profile = someprofile mfa_serial = arn:aws:iam::23456789101:mfa/connor_rielly
Now you can see that aws-vault retrieves any linked profiles:
$ aws-vault list Profile Credentials Sessions ======= =========== ======== someprofile someprofile - ops someprofile - k8s someprofile - blog someprofile -
And you're ready grab some credentials with a nice, long TTL:
$ aws-vault exec --server --session-ttl=8h ops Enter token for arn:aws:iam::23456789101:mfa/connor_rielly: 549236 $ aws-vault list Profile Credentials Sessions ======= =========== ======== someprofile someprofile 86743437993111653036 ops someprofile - k8s someprofile - blog someprofile - $ aws s3 ls 2017-12-15 20:49:38 some-bucket-1 2017-12-09 23:08:47 some-bucket-2 2017-07-18 22:59:37 some-bucket-3
Or to execute subprocesses with AWS credentials injected as Environment Variables:
aws-vault exec k8s -- ansible-playbook standup-asg-cluster.yml -i inventories/dev -e "namespace=tcdev" -e "region=us-west-2"
Or to login to the console (this opens a browser tab):
$ aws-vault --debug login tck8s 2018/03/08 13:01:34 Loading config file /home/crielly/.aws/config 2018/03/08 13:01:34 Parsing config file /home/crielly/.aws/config 2018/03/08 13:01:34 Skipping session token and using master credentials directly 2018/03/08 13:01:34 Looking up keyring for tc Enter token for arn:aws:iam::ACCTNUMBER:mfa/connor_rielly: 976384 2018/03/08 13:01:41 Assuming role arn:aws:iam::ACCTNUMBER:role/org-admin with iam credentials
You also now have no keypair stored in anything resembling a readable fashion on-disk.