JMESPath queries make AWS CLI output easier to read and safer to reuse. Pulling only the needed fields keeps interactive checks shorter in the terminal and gives later shell steps one exact scalar, filtered list, or labeled object instead of an entire API payload.
The --query option applies a JMESPath expression after the AWS CLI receives the service response. That expression can project values out of lists, build new objects with custom labels, filter items with comparisons, and run functions such as sort_by() or length() before the chosen output format is rendered.
The examples below use a Linux or macOS shell, so the whole query stays inside single quotes while JMESPath string and numeric literals inside filters use backticks. While shaping or debugging an expression, prefer json or yaml output because current AWS CLI documentation warns that --output text paginates first and then evaluates the query once per page, which can produce repeated or unexpected matches on larger responses.
$ aws ec2 describe-regions --generate-cli-skeleton output
{
"Regions": [
{
"OptInStatus": "OptInStatus",
"Geography": [
{
"Name": "Name"
}
],
"RegionName": "RegionName",
"Endpoint": "Endpoint"
}
]
}
--generate-cli-skeleton output renders a sample response locally without signing a live service request, which is useful for learning the response layout before running a real query.
$ aws ec2 describe-regions \
--query 'Regions[].RegionName' \
--output json
[
"us-east-1",
"us-east-2",
"us-west-1",
"us-west-2"
]
The list[].field pattern is the fastest way to turn a list of large objects into a simple list of identifiers. The live Region list varies by account and by which Regions are enabled.
$ aws ec2 describe-regions --generate-cli-skeleton output \
--query 'Regions[].{Region:RegionName,OptIn:OptInStatus}' \
--output json
[
{
"Region": "RegionName",
"OptIn": "OptInStatus"
}
]
Multi-select hashes such as {Region:RegionName,OptIn:OptInStatus} keep only the chosen fields and rename them into keys that are easier to reuse in scripts, notes, or follow-up commands.
$ aws ec2 describe-regions --all-regions \
--query 'Regions[?OptInStatus==`opt-in-not-required`].RegionName' \
--output json
[
"us-east-1",
"us-east-2",
"us-west-1",
"us-west-2"
]
String and numeric literals inside a filter use backticks such as `opt-in-not-required` or `50`. Keep the entire query in single quotes on Linux and macOS so the shell passes those characters through unchanged.
$ aws ec2 describe-regions --generate-cli-skeleton output \ --query 'Regions[].RegionName | [0]' \ --output text RegionName
The pipe operator | stops the first projection and hands its result to the next expression, which is useful for taking one item, slicing a sorted list, or applying a final shape after filtering.
$ aws ec2 describe-volumes \ --filters "Name=status,Values=available" \ --query 'length(Volumes[?Iops > `1000`])' \ --output json 3
length() is useful for quick inventory checks, thresholds, and scripts that only need one number back. The returned total depends on the current account inventory.
$ aws ec2 describe-images \ --owners amazon \ --filters "Name=name,Values=amzn*gp2" "Name=virtualization-type,Values=hvm" "Name=root-device-type,Values=ebs" \ --query 'sort_by(Images, &CreationDate)[-1].ImageId' \ --output text ami-00ced3122871a4921
The &CreationDate expression tells sort_by() which field to compare. The final AMI ID varies as the published image catalog changes.
$ aws ec2 describe-volumes \
--filters "Name=availability-zone,Values=us-west-2a" "Name=status,Values=attached" \
--query 'Volumes[?Size > `50`].{Id:VolumeId,Size:Size,Type:VolumeType}' \
--output json
[
{
"Id": "vol-0be9bb0bf12345678",
"Size": 80,
"Type": "gp2"
}
]
Current AWS CLI guidance states that server-side filters run first and --query performs the client-side shaping afterward, which reduces the response size before the JMESPath pass.
$ aws sts get-caller-identity \ --query Account \ --output text 123456789012
With --output text, the AWS CLI paginates first and evaluates the query once per page, so use json or yaml while developing the expression and reserve text output for the final narrowed result.