Michael J
Michael J

Reputation: 1553

Retrieve All Volume IDs for All Instances that Match a Tag Using AWS CLI

StackOverflow! I’m looking for a more efficient way to calculate the total size of EBS volumes attached to instances that match a tag. Note that I’m interested in the /dev/sda1 root volume only!

Presently, I’m using the following approach to get all instances that match a tag. I loop over that output to get the size of the volume attached.

# Calculate the total amount of storage needed for all volumes attached to production EC2 instances (based on 'prod' in the Name tag)
for i in $(aws ec2 describe-instances --query 'Reservations[].Instances[][].{Id: InstanceId}' --filters "Name=tag:Name,Values=*prod*" --output=text);
do
    size=$(aws ec2 describe-volumes --query="Volumes[].Size | [0]" --filters Name=attachment.instance-id,Values=${i} --output=text)
    total=$((total+size))
    echo "$total    $size"
done
echo "Total: $total"

This works but I know its not efficient because I am using one CLI call to get the instances (substitute this as N) and then a call for each instance to get the volume sizes.

This results in a total of N+1 commands.

I know that the describe-instances command can return the volumes that are attached to an instance and then I can make a call using describe-volumes with all of the volumes as a parameter.

This would result in only 2 CLI calls!

total=0
VOLUMES=$(aws ec2 describe-instances --query … --filter ...)
SIZES=$(aws ec2 describe-volumes --volume-ids ${VOLUMES} --query 'Volumes[].Size' --output=text)
for size in ${SIZES};
do
    total=$((total+size))
    echo "$total    $size"
done
echo "Total: $total"

However, I can’t get the query working to return the volumes.

I’m using the following as a starting point:

aws ec2 describe-instances --query 'Reservations[].Instances[][].BlockDeviceMappings[]' --filters "Name=tag:Name,Values=*prod*"

And it gives me this:

[
    {
        "DeviceName": "/dev/sda1",
        "Ebs": {
            "AttachTime": "2019-07-02T21:17:50.000Z",
            "DeleteOnTermination": true,
            "Status": "attached",
            "VolumeId": "vol-abcdef1234567890"
        }
    },
...
]

But I can’t get the right query on the describe-instances call to return just the VolumeIds.

Any suggestions?

Upvotes: 2

Views: 2055

Answers (1)

Michael J
Michael J

Reputation: 1553

After some hacking while I was posting this, I came up with the correct query:

aws ec2 describe-instances \
    --query 'Reservations[].Instances[][].BlockDeviceMappings[].Ebs[].VolumeId' \
    --filters "Name=tag:Name,Values=*prod*" \
    --output=text

Upvotes: 4

Related Questions