问题
What I'm trying to achieve
I want to extract the volume ID for the root block device using describe-instances
.
What I tried so far
aws ec2 describe-instances --filters "Name=tag:Backup,Values=True" --query 'Reservations[].Instances[].{Name: Tags[?Key==`Name`].Value | [0], Id: InstanceId, Block: BlockDeviceMappings[?DeviceName==RootDeviceName].Ebs.VolumeId, Test: RootDeviceName}'
What's not working
Several things:
Ebs.VolumeId
is not the direct descendant ofDeviceName
, it is descending fromBlockDeviceMappings
.RootDeviceName
is not a descendant ofBlockDeviceMappings
.
So when I'm trying to pull the RootDeviceName
and search the VolumeId
accordingly I'm getting a blank field (Block: is for testing and irrelevant to the case).
The first 2 fields are correct.
Thanks in advance!
回答1:
Yes, that is quite an ask!
The closest I got working was to specify the actual value for DeviceName
:
aws ec2 describe-instances --query 'Reservations[].Instances[].[InstanceId, BlockDeviceMappings[?DeviceName==`/dev/xvda`].Ebs.VolumeId]'
(This syntax worked on a Mac.)
Frankly, I'd recommend using a language to make the call (eg Python) and then apply your own logic, rather than trying to convince JMESPath to extract the correct values.
It would be something like this:
import boto3
ec2_client = boto3.client('ec2', region_name = 'ap-southeast-2')
response = ec2_client.describe_instances(
Filters=[
{
'Name': 'tag:Backup',
'Values': ['True']
}
]
)
for r in response['Reservations']:
for i in r['Instances']:
name = [t['Value'] for t in i['Tags'] if t['Key'] == 'Name'][0]
for b in i['BlockDeviceMappings']:
if b['DeviceName'] == i['RootDeviceName']:
print (i['InstanceId'], name, b['Ebs']['VolumeId'])
来源:https://stackoverflow.com/questions/53943306/jmespath-descend-in-tree-for-filter