How to Retrieve Attached EBS Volume IDs from an EC2 Instance Using AWS CLI


2 views

When working with AWS infrastructure, developers often need to programmatically identify storage volumes attached to their EC2 instances. While instance metadata provides the instance ID through http://169.254.169.254/latest/meta-data/instance-id, retrieving attached EBS volumes requires a different approach using AWS CLI.

The most reliable method involves querying AWS EC2 describe-instances API with proper filtering. Here's the complete solution:

# First get the instance ID
INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)

# Then query attached volumes
aws ec2 describe-instances \
  --instance-ids $INSTANCE_ID \
  --query 'Reservations[].Instances[].BlockDeviceMappings[].Ebs.VolumeId' \
  --output text

For more complex scenarios, you might want to filter specific volumes:

# Get root volume only
aws ec2 describe-instances \
  --instance-ids $INSTANCE_ID \
  --query 'Reservations[].Instances[].RootDeviceName' \
  --output text

# Get all volumes with device names
aws ec2 describe-instances \
  --instance-ids $INSTANCE_ID \
  --query 'Reservations[].Instances[].BlockDeviceMappings[].[DeviceName,Ebs.VolumeId]' \
  --output text

These commands become particularly useful when:

  • Automating backup scripts
  • Implementing storage monitoring solutions
  • Building self-healing architectures
  • Developing deployment automation

Always include proper error handling in production scripts:

#!/bin/bash

INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
if [ -z "$INSTANCE_ID" ]; then
  echo "Failed to retrieve instance ID" >&2
  exit 1
fi

VOLUMES=$(aws ec2 describe-instances \
  --instance-ids $INSTANCE_ID \
  --query 'Reservations[].Instances[].BlockDeviceMappings[].Ebs.VolumeId' \
  --output text)

if [ $? -ne 0 ]; then
  echo "AWS CLI command failed" >&2
  exit 1
fi

echo "Attached volumes: $VOLUMES"

For frequent queries, consider caching the results or using AWS Systems Manager for more efficient instance metadata access.


When working with AWS EC2 instances, you often need to programmatically identify the EBS volumes attached to your instance. While getting the instance ID from metadata is straightforward, retrieving attached volume information requires a different approach.

The EC2 instance metadata service (accessible at 169.254.169.254) provides basic instance information, but doesn't directly expose attached volume IDs. Here's how we can combine metadata with AWS CLI:

# Get instance ID from metadata
INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)

# Use AWS CLI to get attached volumes
aws ec2 describe-volumes \
  --filters Name=attachment.instance-id,Values=$INSTANCE_ID \
  --query "Volumes[*].VolumeId" \
  --output text

Using describe-instances

You can also get this information directly from describe-instances:

aws ec2 describe-instances \
  --instance-ids $INSTANCE_ID \
  --query "Reservations[].Instances[].BlockDeviceMappings[].Ebs.VolumeId" \
  --output text

From Within the Instance

If you need to identify volumes from within the instance without AWS CLI:

# For Linux instances
lsblk -d -o NAME,SERIAL | grep "vol" | awk '{print $2}' | sed 's/vol/vol-/'

When your instance has multiple volumes attached, you might want to process them individually:

VOLUME_IDS=$(aws ec2 describe-volumes \
  --filters Name=attachment.instance-id,Values=$INSTANCE_ID \
  --query "Volumes[*].VolumeId" \
  --output text)

for VOLUME_ID in $VOLUME_IDS; do
  echo "Processing volume: $VOLUME_ID"
  # Your volume handling logic here
done

For applications that frequently need this information, consider:

  • Caching the results (with appropriate TTL)
  • Using Instance Metadata Service Version 2 (IMDSv2) for better security
  • Setting proper IAM permissions to restrict volume queries

Always include proper error handling in your scripts:

INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
if [ -z "$INSTANCE_ID" ]; then
  echo "Error: Could not retrieve instance ID" >&2
  exit 1
fi

VOLUME_IDS=$(aws ec2 describe-volumes \
  --filters Name=attachment.instance-id,Values=$INSTANCE_ID \
  --query "Volumes[*].VolumeId" \
  --output text)

if [ -z "$VOLUME_IDS" ]; then
  echo "Warning: No volumes found attached to instance $INSTANCE_ID" >&2
fi