First, I felt the need to post a new answer because of the following subtle problems with the existing answers, and after receiving a question about my comment on @qwertzguy's answer. Here are the problems with the current answers:
- The accepted answer from @MatthieuCerda definitely does not work reliably, at least not on any VPC instances I checked against. (On my instances, I get a VPC name for
hostname -d, which is used for internal DNS, not anything with "amazonaws.com" in it.)
- The highest-voted answer from @qwertzguy does not work on new m5 or c5 instances, which do not have this file. Amazon neglects to document this behavior change AFAIK, although the doc page on this subject does say "... If /sys/hypervisor/uuid exists ...". I asked AWS support whether this change was intentional, see below †.
- The answer from @Jer does not necessarily work everywhere because the
instance-data.ec2.internal DNS lookup may not work. On an Ubuntu EC2 VPC instance I just tested on, I see:
$ curl http://instance-data.ec2.internal
curl: (6) Could not resolve host: instance-data.ec2.internal
which would cause code relying on this method to falsely conclude it is not on EC2!
- The answer to use
dmidecode from @tamale may work, but relies on you a.) having
dmidecode available on your instance, and b.) having root or
sudo password-less ability from within your code.
- The answer to check /sys/devices/virtual/dmi/id/bios_version from @spkane is dangerously misleading! I checked one Ubuntu 14.04 m5 instance, and got a
1.0. This file is not documented at all on Amazon's doc, so I would really not rely on it.
- The first part of the answer from @Chris-Montanaro to check an unreliable 3rd-party URL and use
whois on the result is problematic on several levels. Note the URL suggested in that answer is a 404 page right now! Even if you did find a 3rd-party service that did work, it would be comparatively very slow (compared to checking a file locally) and possibly run into rate-limiting issues or network issues, or possibly your EC2 instance doesn't even have outside network access.
- The second suggestion in the answer from @Chris-Montanaro to check http://169.254.169.254/ is a little better, but another commenter notes that other cloud providers make this instance metadata URL available, so you have to be careful to avoid false positives. Also it will still be much slower than a local file, I have seen this check be especially slow (several seconds to return) on heavily loaded instances. Also, you should remember to pass a
--max-time argument to curl to avoid it hanging for a very long time, especially on a non-EC2 instance where this address may lead to nowhere and hang (as in @algal's answer).
Also, I don't see that anyone has mentioned Amazon's documented fallback of checking for the (possible) file
Who knew that determining whether you are running on EC2 could be so complicated?! OK, now that we have (most) of the problems with listed approaches listed, here is a suggested bash snippet to check whether you are running on EC2. I think this should work generally on almost any Linux instances, Windows instances are an exercise for the reader.
# This first, simple check will work for many older instance types.
if [ -f /sys/hypervisor/uuid ]; then
# File should be readable by non-root users.
if [ `head -c 3 /sys/hypervisor/uuid` == "ec2" ]; then
# This check will work on newer m5/c5 instances, but only if you have root!
elif [ -r /sys/devices/virtual/dmi/id/product_uuid ]; then
# If the file exists AND is readable by us, we can rely on it.
if [ `head -c 3 /sys/devices/virtual/dmi/id/product_uuid` == "EC2" ]; then
# Fallback check of http://169.254.169.254/. If we wanted to be REALLY
# authoritative, we could follow Amazon's suggestions for cryptographically
# verifying their signature, see here:
# but this is almost certainly overkill for this purpose (and the above
# checks of "EC2" prefixes have a higher false positive potential, anyway).
if $(curl -s -m 5 http://169.254.169.254/latest/dynamic/instance-identity/document | grep -q availabilityZone) ; then
Obviously, you could expand this with even more fallback checks, and include paranoia about handling e.g. a false positive from
/sys/hypervisor/uuid happening to start with "ec2" by chance and so on. But this is a good-enough solution for illustration purposes and probably nearly all non-pathological use-cases.
[†] Got back this explanation from AWS support about the change for c5/m5 instances:
The C5 and M5 instances use a new hypervisor stack and the associated kernel drivers do not create files in sysfs (which is mounted at /sys) as the Xen drivers used by the other/older instance types do. The best way to detect whether the operating system is running on an EC2 instance is to account for the different possibilities listed in the documentation you linked.