Azure Instance Metadata

There is a great new feature Azure provides, called Azure Instance Metadata. It gives you information about the metadata of a VM from within the VM. And here is how...

At the time of this writing Azure Instance Metadata is GA already in global Azure, and it's in preview in all the other clouds (and therefore available). Let's see how it works by using one of those others, the Azure German Cloud in this case.

Log into your VM (Windows or Linux is both supported, I'm using a Windows VM here). Now start a PowerShell, and enter:

[code light="true" autolinks="false"]
curl –H @{‘Metadata’=’true’} https://169.254.169.254/metadata/instance?api-version=2017-04-02

We are using curl here (which is by the way an alias for Invoke-WebRequest). You might also use this syntax:

[code light="true" autolinks="false"]
Invoke-RestMethod -Headers @{"Metadata"="true"} `
-URI https://169.254.169.254/metadata/instance?api-version=2017-04-02

There are a couple of things in this request. Let's see them one by one:

  • The request must include the header "Metadata"="true"
  • The address is always 169.254.169.254 and is accessible only from within the VM. There is no need to assign that address to your VM, this is done automatically.
  • Metadata format is versioned, here we use version 2017-04-02. Other version will come, but you can still use the older versions

The output has a "Content" field with a json string containing the metadata. Json is the default output format, text is also possible, example see further down.

[code autolinks="false"]
{
"compute":{
"location":"GermanyCentral",
"name":"myVM",
"offer":"WindowsServer",
"osType":"Windows",
"platformFaultDomain":"0",
"platformUpdateDomain":"0",
"publisher":"MicrosoftWindowsServer",
"sku":"2016-Datacenter",
"version":"2016.127.20170630",
"vmId":"ef2aa96c-e3a7-5432-b42f-d31fc94a3cec",
"vmSize":"Standard_DS2_v2"
},
"network":{
"interface":[
{
"ipv4":{
"ipAddress":[
{
"privateIpAddress":"192.168.1.4",
"publicIpAddress":"51.4.201.56"
}
],
"subnet":[
{
"address":"192.168.1.0",
"prefix":"24"
}
]
},
"ipv6":{
"ipAddress":[]
},
"macAddress":"0017FA104DA4"
}
]
}
}

The meaning of the most of the fields should be clear, see the complete description on the Azure Documentation website. You can access parts of this output in different ways, here are some examples...

[code light="true" autolinks="false"]
(Invoke-RestMethod -Headers @{"Metadata"="true"} `
-URI "https://169.254.169.254/metadata/instance?api-version=2017-04-02).compute.location"

This will retrieve the metadata as an object and access the nodes "Compute" and "Location" under it directly. So the output is as expected:

[code light="true" autolinks="false"]
GermanyCentral

Or save the output to a variable first and then access the properties for the same result
[code]
$md = Invoke-RestMethod -Headers @{"Metadata"="true"} `
-URI "https://169.254.169.254/metadata/instance?api-version=2017-04-02"
$md.Compute.Location

Or put it directly in the request (when you expect a single property you have to use the "text" format by appending "format=text"):
[code light="true" autolinks="false"]
Invoke-RestMethod -Headers @{"Metadata"="true"} `
-URI "https://169.254.169.254/metadata/instance/compute/location?api-version=2017-04-02&format=text"

Furthermore, there is not only metadata about the environment, but also about upcoming maintenance events. Simply replace "instance" with "scheduledevents":
[code light="true" autolinks="false"]
Invoke-RestMethod -Headers @{"Metadata"="true"} `
-URI "https://169.254.169.254/metadata/scheduledevents?api-version=2017-04-02"

Please remember that in some regions this service is still in preview, and watch out for announcements for example in the Azure Germany Teamblog (see link on the right menue) or in the Azure blog.

If you want to test it in Azure Germany, why not sign up for a free trial account?