One of the best things about AWS, compared to other cloud service providers, are their command line tools. Because the command line tools use the same REST API as programming language SDK packages, you can make the same calls from the command line as from any other supported language. This means that absolutely all AWS API functionality works great from the command line. Everything you can do from the AWS web site, you can also achieve in the command line. This is great for ad-hoc tasks and inspecting your AWS assets.
Because the AWS command line tools follow the universal REST API, most operations also return a lot of data, typically in the JSON format. This makes them slightly difficult to chain for scripting more complex operations. Standard UNIX tools aren’t that great for processing JSON, so people often struggle to post-process command results.
However, the AWS command line tools also have a few hidden features that can save you a ton of time if you want to scripting common administrative tasks. In fact, pretty much all the post-processing you’d ever need to chain commands together is already build into the tools, just not that easy to find.
Extract just the data you really want
One quite common task is to pull out just a single piece of information you really need from the output. For example, to create an API Gateway and add resources to it, we need first to create a new gateway, get the ID, then get the automatically created root resource ID, and add another resource path to it. Creating a new API Gateway instance returns the ID we need to add resources to it, but it also returns other information we don’t really need:
You can extract just the bits you need by passing --query
to any AWS command line and pass the name of the field you want. For example:
Convert to plain text
JSON strings are always under quotes, so the API ID printed by the previous command isn’t that easy to directly pipe into other tools. Don’t jump into sed
just to delete those quotes. Use --output text
, and the results will be plain text, not JSON.
This is now ready for using in other commands. You can store the result directly into a shell variable:
Of course, we can now use --output
and --query
to get just the ID of the root resource out – that’s the only piece of information we really need. Use []
to index arrays. So, really useful version of the second command would be something like this:
You can also use --output text
without specifying --query
. This will flatten the JSON structures into tabular text, which is easy to process with standard UNIX tools.
Search through collections
The --query
argument is actually a JMES Path expression, so you can also filter and search collections. JMES Path is mostly logical for anyone used to JSON, apart from strings. Use the backtick (`) to enclose strings. You can also specify a condition starting with a question mark, instead of a numerical index. For example, here’s how to find the REST API we previously created by name:
You can also specify more complex conditions, such as a search by substring. For example, here’s how to find all the APIs in your account that start with the word test
:
You can filter the results further by adding a field name. For example, here’s how to get just the IDs out:
Finally, use --output text
to convert this into a set of plain-text values that your shell can easily iterate on.
A useful example
Let’s put all that together now into a convenient function to delete AWS IAM roles. I often have to clean up IAM roles after experimenting, but AWS refuses to delete a role if it has any attached policies. So we first look for all the test roles, then remove all the policies inside them, and then finally remove the roles themselves. Here’s a nice little shell script that does all that: