jq Cheat Sheet: Process AWS CLI and kubectl JSON Output

· 1 min read · AWS Tutorials

What is jq #

jq is a command line JSON processor. The AWS CLI and kubectl can print JSON, and jq turns that output into exactly the values or tables you need.

sudo apt install -y jq      # macOS: brew install jq
jq --version

The basics #

echo '{"name":"web","port":80,"tags":["a","b"]}' > sample.json
jq . sample.json                 # pretty print
jq .name sample.json             # "web"
jq -r .name sample.json          # web (raw, no quotes)
jq '.tags[0]' sample.json        # "a"
jq '.tags | length' sample.json  # 2
jq 'keys' sample.json

AWS CLI examples #

aws ec2 describe-instances | jq '.Reservations[].Instances[] | {id: .InstanceId, type: .InstanceType, state: .State.Name}'

.Reservations[] iterates the array, the second [] iterates the instances, and {...} builds a smaller object.

# only running instances, one id per line
aws ec2 describe-instances | jq -r '.Reservations[].Instances[] | select(.State.Name=="running") | .InstanceId'

# tags as a map: {"Name":"web","Env":"dev"}
aws ec2 describe-instances | jq '.Reservations[].Instances[] | {id: .InstanceId, tags: ((.Tags // []) | map({(.Key): .Value}) | add)}'

# the Name tag
aws ec2 describe-instances | jq -r '.Reservations[].Instances[] | [.InstanceId, (.Tags[]? | select(.Key=="Name") | .Value)] | @tsv'

# count instances by state
aws ec2 describe-instances | jq '[.Reservations[].Instances[].State.Name] | group_by(.) | map({state: .[0], count: length})'

# S3 buckets older than a date
aws s3api list-buckets | jq -r '.Buckets[] | select(.CreationDate < "2025-01-01") | .Name'

The AWS CLI also has its own filter, --query, written in JMESPath: aws ec2 describe-instances --query 'Reservations[].Instances[].InstanceId' --output text. Use --query for simple extractions and jq when you need to reshape, group or combine.

kubectl examples #

kubectl get pods -o json | jq -r '.items[].metadata.name'
kubectl get pods -A -o json | jq -r '.items[] | select(.status.phase!="Running") | "\(.metadata.namespace)/\(.metadata.name) \(.status.phase)"'
kubectl get nodes -o json | jq '.items[] | {name: .metadata.name, cpu: .status.capacity.cpu, memory: .status.capacity.memory}'
kubectl get deploy -o json | jq '.items[] | {name: .metadata.name, image: .spec.template.spec.containers[].image}'

"\(...)" is string interpolation. Restart counts per pod:

kubectl get pods -o json | jq -r '.items[] | [.metadata.name, ([.status.containerStatuses[]?.restartCount] | add)] | @tsv'

Operators to remember #

Filter Meaning
.a.b, .a[], .a[0] Field, every element, first element
select(cond) Keep what matches
map(f) Apply f to every element
{a, b: .c} Build an object
.x // "default" Default when null
.x? Ignore errors if missing
group_by(.k), sort_by(.k), unique Group, sort, deduplicate
to_entries, from_entries Object to key/value list and back
@csv, @tsv, @json, @base64 Output formats

Shell variables and files #

env=prod
jq --arg env "$env" '.[] | select(.Env==$env)' data.json     # pass a string
jq --argjson n 3 '.[:$n]' data.json                            # pass a number
jq -s 'add' a.json b.json                                      # merge files
jq -c '.items[]' data.json                                     # one object per line

Edit a JSON file safely by writing to a new file: jq '.port = 8080' in.json > out.json && mv out.json in.json.

#Jq #AWS #Kubectl