Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Azure Instance Metadata and Scheduled Events

DZone's Guide to

Azure Instance Metadata and Scheduled Events

Azure now lets you to query information about your Azure VM from within the VM itself. Come check out the public preview, as well as how this service can be of use to you.

· Cloud Zone
Free Resource

Site24x7 - Full stack It Infrastructure Monitoring from the cloud. Sign up for free trial.

Earlier last week, Microsoft announced the public preview of the VM Instance Metadata service. This service allows you to query information about a VM — from inside the VM itself. It's something that has been available on AWS for a long time and has some really interesting uses for users or code running inside your virtual machines. In this post, we'll dig a bit deeper into the service and how it can be used.

The Preview of this service is currently only available in the West US Central Region

Getting the instance metadata is done by calling a URI from inside the VM. This is on a non-rotatable IP, so you can only get this information from inside the VM itself. The URL that you need to call is:

http://169.254.169.254/metadata/instance?api-version=2017-03-01


However, if you just call that URL directly, you'll get an error, as it is also expecting some information in the header of your request, namely a property of "metadata" with a value of "true". So to call this from PowerShell on Windows, you would not something like:

curl -H @{'Metadata'='true'} http://169.254.169.254/metadata/instance?api-version=2017-03-01

Note "curl" in PowerShell is just an alias for "Invoke-Webrequest"

The content of the response is JSON, which contains two objects:

{
    "compute":  {
    "location":  "westcentralus",
    "name":  "MetaData",
    "offer":  "WindowsServer",
    "osType":  "Windows",
    "platformFaultDomain":  "0",
    "platformUpdateDomain":  "0",
    "publisher":  "MicrosoftWindowsServer",
    "sku":  "2012-R2-Datacenter",
    "version":  "4.127.20170406",
    "vmId":  "efd3aced-81c4-4521-bbe7-154bcb11e816",
    "vmSize":  "Standard_DS2_v2"
    },
    "network":  {
    "interface":  [
      "@{ipv4=; ipv6=; mac=000D3AF8563C}"
      ]
    }
}

Compute

The Compute object provides basic information about the VM you're running this command on. This information can be useful in a variety of scenarios:

  • Getting a unique VM ID for the VM you're running on to uniquely identify the machine you are running on.
  • Getting the VM size to determine whether scaling up or down is something you want to do, or to report the VM size to your custom billing or cost tracking solution.
  • Checking the version of the VM's OS image to determine whether it needs an update.
  • Checking the VM fault and upgrade domain. This is particularly important for clusters and HA, and this data can be used to check whether your nodes are all in separate faults and upgrade domains.

The data is pulled in as JSON, so you can easily convert this into a PowerShell object, which can be manipulated as required:

$rawMetaData=$(curl -H @{'Metadata'='true'} http://169.254.169.254/metadata/instance?api-version=2017-03-01).content
$metaData= convertFrom-JSON $rawMetaData
write-host "VM ID is $($metaData.compute.vmID)"


You can also get a specific value from the metadata by including this in your URL. For example, for the VMID, your URL would look like this:

http://169.254.169.254/metadata/instance/compute/vmId?api-version=2017-03-01&format=text

Network

The Network object provides some basic information about the VM's network configuration. This is broken down into multiple objects, so it's a bit more complicated than the Compute object, but we can retrieve:

  • MAC address
  • IPv4 configuration including the VM's public and private IP
  • IPv6 configuration if in use

This information can be very useful when running code to allow access to remote resources, obtain licenses from a license service, etc.

For example, to retrieve the MAC and public IP:

$rawMetaData=$(curl -H @{'Metadata'='true'} http:
$metaData= convertFrom-JSON $rawMetaData

$MAC=$metaData.network.interface.mac
$publicIP=$metaData.network.interface.ipv4.ipaddress.publicIP

Scheduled Events

There is also another metadata service available for your VMs. This has been available for a little while now, and it works similarly to instance metadata — scheduled events. The scheduled events service is available on a similar URL from inside the VM and, when called, will give you information on any scheduled maintenance events that are planned for this VM. The scheduled events service can only provide details of an event when it knows it is planned, so you may find that some while events only appear a few minutes before they occur, others may be present for longer. Obviously, unplanned maintenance is unlikely to be shown.

To get this data, you're again going to hit the 169.254.169.254 URL, but with some different data, using PowerShell, your request would look like:

curl -H @{'Metadata'='true'} http://169.254.169.254/metadata/latest/scheduledevents``


The content of the response will include an "Events" array. If there are no events scheduled, this will be empty. If there are events planned, the array will contain an object with information on the event, similar to:

 "Events":[
      {
        "EventId":{eventID},
        "EventType":"Reboot",
        "ResourceType":"VirtualMachine",
        "Resources":[{resourceName}],
        "EventStatus":"Scheduled",
        "NotBefore":{timeInUTC},  
     }
 ]


The EventType will describe what event is going to take place and will be one of three options:

  • Freeze: The VM is scheduled to pause for few seconds. There is no impact on memory, open files, or network connections
  • Reboot: The VM is scheduled for reboot (memory is wiped).
  • Redeploy: The VM is scheduled to move to another node (ephemeral disks are lost).

The EventStatus will indicate whether the event is "Scheduled", going to happen in the future, or "InProgress", indicating it is happening now.

If the event is scheduled, a NotBeforeTime will indicate the earliest time the event will occur.

Expediting an Event

If an event is scheduled for the future, you can make a request to trigger the event earlier than the NotBefore time. This is done by making a POST request back to the scheduled event service. Azure will then expedite the event where possible, but there is no guarantee it will occur early.

To submit a request for expediting, you need to send an array of StartRequests to the API using the EventID you were provided in the event message:

$startRequests = [array]@{"EventId" = <eventID>}
$scheduledEventsApproval = @{"StartRequests" = $startRequests} 
$approvalString = ConvertTo-Json $scheduledEventsApproval
Invoke-RestMethod -Uri http://169.254.169.254/metadata/latest/scheduledevents -Headers @{"Metadata"="true"} -Method POST -Body $approvalString

Site24x7 - Full stack It Infrastructure Monitoring from the cloud. Sign up for free trial.

Topics:
cloud ,microsoft azure ,virtual machine ,metadata ,tutorial

Published at DZone with permission of Sam Cogan, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}