Azure Instance Metadata

There is a great feature Azure provides, called Azure Instance Metadata. It gives you information about the metadata of a VM from within the VM. Azure Instance Metadata was recently updated, so a lot more fueatures are provided by this service. Let’s see how it works…

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

curl -H Metadata:true "http://169.254.169.254/metadata/instance?api-version=2018-10-01"

We are using curl here, feel free to use any other command line browser. In Windows you can use a PowerShell and also use curl (or Invoke-RestMethod) with slightly modified syntax, like this:

Invoke-RestMethod -Headers @{"Metadata"="true"} `
  -URI http://169.254.169.254/metadata/instance?api-version=2018-10-01

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

  • The request must include the header Metadata:true(or "Metadata"="true" for Windows)
  • The address is always the non-routable IP address 169.254.169.254 and is accessible only from within the VM.
  • Metadata format is versioned, here we use version 2018-10-01, available in most Azure regions. Newer versions are published frequently.

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. If you want to format the output, you can use for example jq. The output looks like this:

{
  "compute": {
    "azEnvironment": "AZUREPUBLICCLOUD",
    "location": "northeurope",
    "name": "dockertest01",
    "offer": "UbuntuServer",
    "osType": "Linux",
    "placementGroupId": "",
    "plan": {
      "name": "",
      "product": "",
      "publisher": ""
    },
    "platformFaultDomain": "0",
    "platformUpdateDomain": "0",
    "provider": "Microsoft.Compute",
    "publicKeys": [
      {
        "keyData": "ssh-rsa ...",
        "path": "/home/testuser/.ssh/authorized_keys"
      }
    ],
    "publisher": "Canonical",
    "resourceGroupName": "rgdockertest",
    "sku": "18.04-LTS",
    "subscriptionId": "xxxxxxxxxxxxxxxxxxxxxxxxx",
    "tags": "",
    "version": "18.04.201902121",
    "vmId": "1db2e95e-xxxxxxxxxxxxxxxxx-55b9ab2020ad",
    "vmScaleSetName": "",
    "vmSize": "Standard_D2s_v3",
    "zone": ""
  },
  "network": {
    "interface": [
      {
        "ipv4": {
          "ipAddress": [
            {
              "privateIpAddress": "10.0.0.4",
              "publicIpAddress": ""
            }
          ],
          "subnet": [
            {
              "address": "10.0.0.0",
              "prefix": "24"
            }
          ]
        },
        "ipv6": {
          "ipAddress": []
        },
        "macAddress": "000D3AB8AF32"
      }
    ]
  }
}

The meaning of the most of the fields should be clear, I just want to mention some of them here.

  • azEnvironment tells you in which environment the VM is deployed.
  • vmSize might help you to manage capacity better from within the VM (install packages depending the type of VM for example).
  • Clearly the example VM does not belong to an availability set, since UpdateDomain and FaultDomain is empty

See the complete description on the Azure Documentation website. You can access parts of this output in different ways, here are some examples for Windows and PowerShell…

(Invoke-RestMethod -Headers @{"Metadata"="true"} `
  -URI "http://169.254.169.254/metadata/instance?api-version=2018-10-01).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:

northeurope

Or save the output to a variable first and then access the properties for the same result

$md = Invoke-RestMethod -Headers @{"Metadata"="true"} `
  -URI "http://169.254.169.254/metadata/instance?api-version=2018-10-01"
$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“):

Invoke-RestMethod -Headers @{"Metadata"="true"} `
  -URI "http://169.254.169.254/metadata/instance/compute/location?api-version=2018-10-01&format=text"

Scheduled Events

Furthermore, metadata service not only provides information about the environment, but also about upcoming maintenance events. Simply replace „instance“ with „scheduledevents“:

Invoke-RestMethod -Headers @{"Metadata"="true"} `
  -URI "http://169.254.169.254/metadata/scheduledevents?api-version=2018-10-01"

Don’t get in panic when calling this URI the first time, it can take up to 2 min to enable the service. A common way to use this information is to react in time to an upcoming event, like performing a graceful shutdown or insert a log entry.

Attested Data

To be sure that the answer to the request is authentic and was not tempered by somebody, attested data can be used. You’ll get a signed document as an answer.

curl -H Metadata:True http://169.254.169.254/metadata/attested/document?api-version=2018-10-01

The encoded information is very basic:

{
  "nonce": "20190310-163938",
  "plan": {
    "name": "",
    "product": "",
    "publisher": ""
  },
  "timeStamp": {
    "createdOn": "03/10/19 16:39:38 -0000",
    "expiresOn": "03/10/19 22:39:38 -0000"
  },
  "vmId": "1db2e95e-xxxx-4e70-bfd3-55b9ab2020ad"
}

This is useful for support calls since it proves that the VM is really running on Azure. And the „plan“ fields will be populated for articles in Azure Marketplace.

2 Kommentare zu „Azure Instance Metadata

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden /  Ändern )

Google Foto

Du kommentierst mit Deinem Google-Konto. Abmelden /  Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden /  Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden /  Ändern )

Verbinde mit %s