3

I need to write a bash script to attach Amazon EBS volumes to a given instance based on the Name tag of the volume. The tag is in the format of "device on servername" e.g. "/dev/xvdf on linuxserver"

I can easily perform the following command to retrieve all the relevant instances, but I am having trouble iterating through each object in the json array to get VolumeId and Name tag.

aws ec2 describe-volumes --region $region --filter Name=tag-key,Values="Name" Name=tag-value,Values="*$servername" --filter Name="status",Values="available" | jq '.Volumes[]'

an example output is:

 [
  {
    "AvailabilityZone": "us-east-1d",
    "Attachments": [],
    "Tags": [
      {
        "Value": "/dev/xvdg on linuxserver",
        "Key": "Name"
      }
    ],
    "Encrypted": false,
    "VolumeType": "io1",
    "VolumeId": "vol-0233d8ec",
    "State": "available",
    "Iops": 120,
    "SnapshotId": "",
    "CreateTime": "2015-08-21T04:29:10.157Z",
    "Size": 4
  },
  {
    "AvailabilityZone": "us-east-1d",
    "Attachments": [],
    "Tags": [
      {
        "Value": "/dev/xvdf on linuxserver",
        "Key": "Name"
      }
    ],
    "Encrypted": false,
    "VolumeType": "io1",
    "VolumeId": "vol-433bc8ae",
    "State": "available",
    "Iops": 120,
    "SnapshotId": "",
    "CreateTime": "2015-08-21T04:28:23.819Z",
    "Size": 4
  }
]

Ideally, I'd like to do the following:

for object in $(aws ec2 describe-volumes --region $region --filter Name=tag-key,Values="Name" Name=tag-value,Values="*$servername" --filter Name="status",Values="available" | jq '.Volumes[]')
do
    echo $object.VolumeId
done 

But bash treats each line as an object in the array.

I'd be very appreciative of some suggestions on a better way to approach this.

Thanks

0

1 Answer 1

1

The jq package might help you here. It was created to fill the void of ability to parse JSON with bash scripts.

An example for how to get the volume IDs from your sample data:

aws ec2 describe-volumes --region $region --filter Name=tag-key,Values="Name"\
    Name=tag-value,Values="*$servername" --filter Name="status",Values="available"\
    | jq .[].VolumeId

Output:

"vol-0233d8ec"
"vol-433bc8ae"

You could split it to iterate over it as an array like so:

#!/bin/bash

volumeIds=$(aws ec2 describe-volumes --region $region --filter Name=tag-key,Values="Name"\
    Name=tag-value,Values="*$servername" --filter Name="status",Values="available"\
    | jq .[].VolumeId)

for i in `echo "$volumeIds"`
do
  echo "$i is a volume ID"
done

# "vol-0233d8ec" is a volume ID
# "vol-433bc8ae" is a volume ID
Sign up to request clarification or add additional context in comments.

1 Comment

It seems it no longer works: [ec2-user@ip-10-0-0-113 tmp]$ aws ec2 describe-volumes --region $REGION | jq .[].VolumeId jq: error (at <stdin>:90): Cannot index array with string "VolumeId"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.