How to identify EBS volumes vs local volumes on running EC2 instance

On a running EC2 instance, how do I identify EBS volumes and local disks ? I would like to identify them from shell.

fdisk, lsblk is not helping to pinpoint the EBS volumes only.

Lets say I have total 20 disks, out of 20 identify ebs stores.

Any suggestions?


Solution 1:

Every EC2 instance can access a REST endpoint at the link-local address http://169.254.169.254 that provides access to metadata about that instance.

Block device mapping of EBS and instance store volumes are one of several properties available there, and the data is easily accessed from the shell and scripts using a tool like "curl."

http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AESDG-chapter-instancedata.html

This is probably the "most correct" way of discovering what you're looking for.


Update: I hammered out a quick and extremely dirty one-liner to demonstrate this functionality. I don't intend to imply that this is production quality code, nor particularly well-documented, but it definitely works.

The endpoint above appears to offer several "versions" of its interface, most of which use the version release date, or you can use the "latest" version. So that this example code will continue to work even if the interface changes, I'll choose the version "2012-01-12."

We'll store a link in the shell variable $METAURL, retrieve the list of mappings available there with curl and then iterate though each mapping with a bash for/do/done loop (again with curl) to find the block device... then use perl to make it tidier and rewrite "sdX" as "xvdX" as my particular instance uses for its device names, and finally sort to put it in lexical order.

bash$ METAURL="http://169.254.169.254/2012-01-12/meta-data/block-device-mapping/"
bash$for bd in `curl -s $METAURL`; do curl -s $METAURL$bd | \
         perl -pe 'BEGIN { $d = shift } s/^(\/dev\/)?(sd)?(.*)$/\/dev\/xvd$3 is $d\n/' $bd; \
         done | sort

Example output:

/dev/xvda1 is ami
/dev/xvda1 is root
/dev/xvdb is ephemeral0
/dev/xvdf is ebs2
/dev/xvdg is ebs1
/dev/xvdh is ebs5

That was pretty slick and relatively painless.

But, there is one small problem with my answer.

block-device-mapping/ebsN

The virtual devices associated with Amazon EBS volumes, if any are present. This value is only available in metadata if it is present at launch time.

— http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AESDG-chapter-instancedata.html#instancedata-data-categories

This solution won't tell you about EBS volumes mounted after the instance was launched. That may be fine, because ephemeral volume information is always available, since ephemeral disks can only be added at launch time, not later... so if a volume is ephemeral, you should always be able to discover it via this method. If it's not here, it's not an ephemeral disk.

In light of this, the EC2 API or the aws cli utility (which calls the EC2 API) would be what you'd need to use if you really need to know all there is to know about what's attached to the instance. There's more data there, but it would be somewhat tricker to utilize in scripts. Classic tradeoff, I suppose.

Solution 2:

Michael’s answer shows that there doesn’t seem to be a way to distinguish instance disks from EBS volumes inside an AWS instance. In fact, the kernel info for instance and EBS disks, which you can compare with diff -r /sys/block/xvd{f,g}, is identical except for write stats and device name. And the disks don’t respond to smartctl.

However, I have noticed that:

  • New EBS volumes seem to come up without any partition table as all.

  • New ephemeral disks seem to be ext formatted, and have the “mount count” superblock parameter set to 0 to reflect the fact that they’ve never been mounted anywhere.

Using that, one way to do it is to run a script, when the machine boots for the first time, that looks for devices that are ext-formatted and for which

tune2fs -l $dev | grep "Mount count"

returns 0. Save a list of such disks somewhere on the instance, and treat all other disks as EBS.

Amazon is of course liable to change all of this at any time without notice. But it seems to work for now.