AWS cli: quering multiple accounts

At skyscrapers we manage the aws infrastructure for multiple clients. We automated accessing the different aws consoles with a pretty cool script. It gives our federated user automatically a login url and opens a browser accessing this url. It uses 2FA and the access is only temporary to add more security. Maybe this is a writeup on itself 😉

But switching between these consoles takes time. Especially just to get a private ip of a server or query some basic information. Last time I was working on a production and staging environment for 1 client. I needed to switch every 5 minutes between environment to get some information.

It was slow especially on my slow Thai 3G line it took very long just to load the console.

I wanted to simplify switching between accounts and queuing data. After some investigation I learned that the aws cli had all I ever needed.

Installing the aws cli

I started with installing the aws cli. Don’t forget to setup the command completion. This is a huge timesaver! Instead of looking up the exact syntax the completer will help you narrowing down the options. As a shell I use oh-my-zsh and there is a plugin to use the aws command completion.

If you tab after the describe- you get all the describe options for the ec2 command.

Setting up read only access to all the different aws accounts.

To make it a bit more secure and I use this only to query aws we’ll setup an read-only account. We use terraform and puppet to setup and install instances.

There are suffcient google search sources like this one on how to do this.

Extract your aws_access_key_id and aws_secret_access_key.

Setup multiple accounts for aws cli

Create in your home directory a .aws folder if not already exists. This folder need to contain 2 files: config and credentials.

In the credentials file you just have to add your keys:

[default]
aws_access_key_id = XXX
aws_secret_access_key=XXX
[staging]
aws_access_key_id = XXX
aws_secret_access_key = XXX
[prod]
aws_access_key_id = XXX
aws_secret_access_key = XXX
[staging2]
aws_access_key_id = XXX
aws_secret_access_key = XXX

The option I keep switching in this file will be the output. When I want it readable to me I put table when I want to do some funky filtering I usejson.

Let's test this:

› aws ec2 describe-instances
{
"Reservations": []
}

This queried the staging credentials and the config said table style. As you can see quite handy.

Adding --filter

As I told before in this article I most of the time I query private and public ip addresses. I only need to know this for a particular type or set of servers.

Let's query all the staging webservers:

› aws ec2 describe-instances --filter Name=tag:class,Values=web Name=tag:Env,Values=staging --profile staging2

what's next?

This example can be extended to a more complete bash script. Accepting different variables for class or env or to switch between staging and production.

You can use your imagination and try to find other use cases. The aws cli has a large set of options which can be applied to all kinds of use cases. If you find some don't hesitate to post in the comments.

What can be improved

The credentials in my .aws/credentials are not best practice. The script I talked about in the beginning that generates an url to the correct console also generates temporary aws_access_key_id and aws_secret_access_key. Which are only temporary usable so more secure! My next step is to edit this script so I can easily switch between environments using the more safe temporary aws_keys. Switching using this script means using my phone for 2FA... But security always has a cost 🙂

This is a cross post from the blog of Geert Theys.