Is there any way to detect, in general, if your code is executing on an Azure or Amazon virtual machine. I am not referring to some sort of web or worker role in particular,
If your guest has networking up then you can probe the instance metadata by accessing http://169.254.169.254
For example:
$ curl http://169.254.169.254/1.0/meta-data/instance-id
i-87dc2f76
However, hitting the network is fairly heavy-weight.
On AWS you can also check by looking at dmidecode:
$ /usr/sbin/dmidecode -s bios-version | tr "[:upper:]" "[:lower:]" | grep -q "amazon"
dmidecode is light-weight since it only hits the memory of the guest OS. However, as pointed out in previous answers it is dependent on Amazon continuing to include the word "amazon" in their version strings.
On Azure, you can detect the hypervisor details but this doesn't allow you to discriminate between Azure and HyperV. Depending on your scenario this might not be necessary.
To detect Azure/HyperV using dmidecode check the following strings:
$ /usr/sbin/dmidecode -s system-manufacturer | tr "[:upper:]" "[:lower:]" | grep -q "microsoft corporation"
$ /usr/sbin/dmidecode -s system-product-name | tr "[:upper:]" "[:lower:]" | grep -q "virtual machine"
@Dan's answer no longer works for Azure, use the following URL to get a better list
http://msdn.microsoft.com/en-us/library/windowsazure/dn175718.aspx
If this url ever disappears here is a copy from today (August 12th 2013)
Europe West
65.52.128.0/19
213.199.128.0/20
168.63.0.0/19
168.63.96.0/19
137.116.192.0/19
137.117.128.0/17
168.61.56.0/21
Europe North
65.52.64.0/20
65.52.224.0/19
168.63.92.0/22
168.63.32.0/19
94.245.88.0/21
94.245.104.0/21
168.63.64.0/20
168.63.80.0/20
168.61.96.0/19
137.116.224.0/20
US East
168.62.32.0/19
157.56.176.0/21
168.62.160.0/19
168.61.32.0/20
168.61.48.0/21
137.117.64.0/18
137.135.64.0/18
138.91.96.0/19
137.116.112.0/20
US West
168.62.192.0/20
168.62.208.0/21
168.61.0.0/20
168.61.64.0/20
137.117.0.0/19
137.135.0.0/18
137.116.184.0/21
138.91.64.0/19
65.52.112.0/20
168.63.89.0/24
157.56.160.0/21
168.62.0.0/19
US North Central
65.52.0.0/19
65.52.0.0/20
65.52.16.0/20
65.52.192.0/19
65.52.48.0/20
157.55.24.0/21
157.55.64.0/20
157.55.160.0/20
157.55.136.0/21
157.55.208.0/20
157.56.8.0/21
157.55.252.0/22
168.62.96.0/19
157.55.248.0/22
168.62.224.0/19
US South Central
157.55.176.10/22
157.55.183.223/27
157.55.184.10/22
157.55.191.223/27
157.55.192.10/24
157.55.193.223/27
157.55.194.10/24
157.55.195.223/27
157.55.196.10/23
157.55.200.10/23
157.55.80.10/23
157.55.83.223/27
157.55.84.10/23
157.55.87.223/27
65.52.32.10/22
65.52.39.224/28
70.37.160.10/22
70.37.167.224/28
70.37.118.0/24
70.37.119.138/28
70.37.119.170/28
70.37.48.10/22
70.37.55.224/28
70.37.56.10/22
70.37.63.224/28
70.37.116.0/24
SE Asia
111.221.96.0/20
168.63.160.0/19
111.221.80.0/20
168.63.224.0/19
137.116.128.0/19
East Asia
65.52.160.0/19
111.221.78.0/23
168.63.128.0/19
168.63.192.0/19
137.116.160.0/20
You could look at the machine's ip address, and determine if it is in a particular cloud's ip address block.
For Azure, the published list of ip address ranges for each subregion is an xml file at:
http://download.microsoft.com/download/E/F/C/EFC5E4D8-E4EA-4EFE-9356-D8AEEBC85F50/Azure_IP_Ranges.xml
Amazon will post a blog entry when they add new ranges. They are currently:
US East (Northern Virginia):
US West (Oregon):
US West (Northern California):
EU (Ireland):
Asia Pacific (Singapore)
Asia Pacific (Tokyo)
South America (Sao Paulo)
This is an internal way to check if you machine instance is in amazon or not:
dmidecode | grep Version
version: 4.2.amazon <--- This is what you would want to key on
This would only work as long as Amazon maintains their signature in their VM's virtual BIOS settings. I have not worked with Azure, but I am sure you could extrapolate information using dmidecode
as well. I have done it with VMware, and VirtualBox.