Giter Club home page Giter Club logo

azure_instance_metadata_service_simulator's Introduction

A small utility to simulate the Azure Instance Metadata Service on a dev box

The 'Azure Instance Metadata Service' (IMDS) is a REST endpoint, available at a well-known non-routable IP address (169.254.169.254), on a variety of Azure compute resources, such as Virtual Machines or also on Azure Container Instances. You can find various samples or articles how to call that service.

The problem however is that developing 'locally' can be cumbersome, because the service is not available. The simple Go utility here essentially mimics IMDS.

The 'magic' IP 169.254.169.254

For that to work, you need to bind that special IP address to one of your network interfaces. For example, on Windows, I run an administrative command prompt, and run this:

Windows:

netsh.exe interface ipv4 add address ^
    name="vEthernet (Default Switch)" ^
    address="169.254.169.254"

Linux (Ubuntu):

ifconfig:

sudo ifconfig eth0:1 169.254.169.254 netmask 255.255.255.0

ip:

sudo ip address add 169.254.169.254/255.255.255.0 dev eth0:1

To remove that binding, you can run this:

Windows:

netsh.exe interface ipv4 delete address ^
    name="vEthernet (Default Switch)" ^
    address="169.254.169.254"

Linux (Ubuntu):

ifconfig

sudo ifconfig eth0:1 del 169.254.169.254

ip

sudo ip address del 169.254.169.254/255.255.255.0 dev eth0:1

Configure the service

The application looks at a small config file, and exposes the file's information via REST:

{
    "tenantID": "sometenant.onmicrosoft.com",
    "servicePrincipals": {
        "deadbeef-efa9-42ea-9ac3-28a920370be6": "ewewM/OblEL/WOJweC0="
    },
    "metadata": {
        "compute": {
            "provider":"Microsoft.Compute",
            "tags":"tag1:val2",
            "azEnvironment":"AzurePublicCloud",
            "location":"westeurope",
            "subscriptionId":"deadbeef-bee4-484b-bf13-d6a5505d2b51",
            "resourceGroupName":"spring",
            "vmId":"c7619932-27e3-4a63-988c-460bd290ca55",
            "name":"somevm",
            "vmSize":"Standard_D2s_v3",
            "customData":"",
            "placementGroupId":"", "platformFaultDomain":"0", "platformUpdateDomain":"0",
            "osType":"Linux",
            "publisher":"Canonical", "offer":"UbuntuServer", "sku":"18.04-LTS", "version":"18.04.201905290",
            "vmScaleSetName":"",
            "zone":""
        }
    }
}

Essentially, the .metadata part is exposed on 'http://169.254.169.254/metadata/instance/compute'...

Managed user-assigned Identity

One of the funky capabilities of IMDS is that it can fetch Azure AD tokens on behalf of the application, without exposing credentials such as service principal keys to the application. For example, this script expects to fetch a token for Azure KeyVault:

#!/bin/bash

apiVersion="2018-02-01"

curl --request GET \
    --silent \
    -H Metadata:true \
    "http://169.254.169.254/metadata/identity/oauth2/token?api-version=${apiVersion}&client_id=${service_principal_application_id}&resource=https%3A%2F%2Fvault.azure.net"

Managed Identities can, by design, not be directly reachable on your developer laptop (unless we would proxy that REST call to a real Azure compute resource). To mimic that token endoint (/metadata/identity/oauth2/token), you can configure service principal credentials in the config file as well.

Build

To build:

Windows:

go build -o .\bin\server.exe server.go

Linux:

go build -o ./bin/server server.go

Run

Windows:

.\bind_imds_ip.cmd && .\bin\server.exe

Linux:

sudo -- sh -c './bind_imds_ip.sh && ./bin/server'

Test

To validate that the service is running correctly:

Linux:

curl -H Metadata:true --noproxy "*" "http://169.254.169.254/metadata/instance?api-version=2020-09-01"

Stop

To stop, stop the running process, then:

.\release_imds_ip.cmd

Linux:

sudo ./release_imds_ip.sh

azure_instance_metadata_service_simulator's People

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.