IBM Cloud Docs
Use the instance metadata service

Use the instance metadata service

After you obtained an instance identity access token, you can access the metadata service and retrieve metadata about a virtual server instance. This topic describes how to make calls to the API to access instance metadata such as initialization data, network interfaces, volume attachments, public SSH keys, and placement groups.

When you make API calls to the instance metadata service, events are triggered in the Activity Tracker. For more information, see Instance Metadata service events.

Before you begin

To access metadata service, you must have an instance identity access token. If you don't have one, see Acquire an instance identity access token.

The metadata service is disabled by default. To enable it, see Enable or disable the metadata service.

For more information about these API calls and examples, see the Metadata service API reference.

Windows users have extra requirements to access and use the metadata service. For more information, see Setting up windows servers for using the metadata service.

Accessing the metadata service by using the instance identity access token service

To access the instance metadata service, you must first obtain an instance identity access token. You can later generate IAM tokens from the instance identity access token and then use them to access IAM-enabled services.

Windows users have extra requirements to set up the metadata service. For more information, see Setting up Windows servers for using the metadata service.

Instance identity access token concepts

An instance identity access token provides a security credential for accessing the metadata service. It's a signed token with a set of claims based on information about the instance and information that is passed in the token request.

To access the instance identity, make a PUT "http://api.metadata.cloud.ibm.com/instance_identity/v1/token call by using the Metadata service API that invokes the instance host name. Communication between the instance and metadata service never leaves the host, you acquire the token from within the instance. If secure access to the instance metadata service is enabled on your instance use, the "https" protocol instead of the "http" protocol.

In the request, you specify an expiration time for the token. The default is 5 minutes, but you can specify that it expires sooner or later (5 seconds to 1 hour).

The response (a JSON payload) contains the instance identity access token. Use this token to access the metadata service.

You can also generate an IAM token from this token and use the RIAS API to call IAM-enabled services. For more information, see Generate an IAM token from an instance identity access token.

Acquire an instance identity access token

Using the Metadata service API, make PUT "http://api.metadata.cloud.ibm.com/instance_identity/v1/token call to get an instance identity access token. The following example uses jq to parse the JSON API response and then extract the instance identity access token value. You can use your preferred JSON parser.

In the example, the return value of the cURL command is the instance identity access token, which is extracted by jq and placed in the instance_identity_token environment variable. You use specify this variable in a GET call to the metadata service to reach the metadata endpoint. For more information, see Retrieve metadata from your running instances.

The example uses jq as a parser, a third-party tool licensed under the MIT license. jq might not come preinstalled on all VPC images available when you create an instance. You might need to install jq before use or use any parser of your choice.

instance_identity_token=`curl -X PUT "http://api.metadata.cloud.ibm.com/instance_identity/v1/token?version=2022-08-08"\
  -H "Metadata-Flavor: ibm"\
  -d '{
        "expires_in": 3600
      }' | jq -r '(.access_token)'`

The following JSON response shows the instance identity access token character string, date, and time that it was created, date, and time that it expires, and expiration time you set. Keep in mind that the token expires in 5 minutes.

{
  "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IlZTSS1DUl91cy1lYXN0X2I5...",
  "created_at": "2022-08-08T11:08:39.363Z",
  "expires_at": "2022-08-08T11:13:39.363Z",
  "expires_in": 3600
}

Generate an IAM token from an instance identity access token

To access IBM Cloud IAM-enabled services in the account, you can generate an IAM token from the instance identity access token by using trusted profile information. After you generate the IAM token, you can use it to access IAM-enabled services, such as IBM Cloud Object Storage, Cloud Database Service, and the VPC APIs. You can reuse the token multiple times.

Make a POST /instance_identity/v1/iam_token call and specify the ID of the trusted profile. This request uses the instance identity access token and a trusted profile that is linked to a virtual server instance to generate an IAM access token. The trusted profile can be linked either when you create the instance or provided in the request body.

The IAM API used to pass the instance identity access token and generate an IAM token is being deprecated. Beta users must migrate to the metadata service API to generate an IAM token by using POST /instance_identity/v1/iam_token.

Example request:

iam_token=`curl -X POST "http://api.metadata.cloud.ibm.com/instance_identity/v1/iam_token?version=2022-08-08"\
   -H "Authorization: Bearer $instance_identity_token"\
   -d '{
       "trusted_profile": {
          "id": "Profile-8dd84246-7df4-4667-94e4-8cede51d5ac5"
       }
      }' | jq -r '(.access_token)'`

The JSON response shows the IAM token.

{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aGVfYmVzdCI6I8...",
  "created_at": "2022-08-08T14:10:15Z",
  "expires_at": "2022-08-08T15:10:15Z",
  "expires_in": 3600
}

For more information about trusted profiles, see Using a trusted profile to call IAM-enabled services.

Create a trusted profile for the instance

Trusted profiles for compute resource identities help you assign an IBM Cloud® IAM identity to an IBM Cloud® resource, such as a virtual server instance. You can call any IAM-enabled service from an instance without having to manage and distribute IAM secrets to the instance. You can create a trusted profile when you generate an IAM token from an instance identity access token and link it to the instance. For more information, see Using a trusted profile to call IAM-enabled services.

Retrieve instance metadata from your running virtual server instance

Use the instance metadata service to get metadata about the instance, initialization information, SSH keys, and placement groups.

Retrieve instance initialization information

Make a GET "http://169.254.169.254/metadata/v1/instance/initialization" call to retrieve initialization information for the instance.

This request:

  • Calls the API to retrieve the instance identity access token.
  • Uses the token to access the metadata service.
  • Extracts the user data from the JSON payload by using jq.

You're making an unsecured request that is then secured by a proxy. The proxy intercepts the request by watching for the instance IP.

In the example, the return value of the cURL command is the user data, which is extracted by jq and placed in the user_data environment variable.

curl -X GET "http://169.254.169.254/metadata/v1/instance/initialization?version=2021-10-12"\
  -H "Accept: application/json"\
  -H "Authorization: Bearer $access_token" | jq -r

The response lists public SSH keys that were used at instance initialization and extracts any other user data made available when the instance was provisioned. The response includes the SHA256 value that identifies the SSH key.

{
  "keys": [
    {
      "crn": "crn:[...]",
      "fingerprint": "SHA256:RJ+YWs3rupwGFiJuLqY43tvmdeLOUjcIc9cA6IR8n8E",
      "id": "dadae729-1d81-4a13-966e-f5d92699f103",
      "name": "my-key1",
      "resource_type": "key"
    }
  ],
  "user_data": "Content-Type: multipart/form-data; boundary=3efa30189c9e0e8ebc24a4decbbf4c2be7b26120c1cdd7cb7bc2ecb0c07c\nMIME-Version: 1.0\n\n--3efa30189c9e0e8ebc24a4decbbf4c2be7b26120c1cdd7cb7bc2ecb0c07c\nContent-Type: text/cloud-config\n\n#cloud-config\ndisable_root: false\nchpasswd:\n  list: |\n    root:genes1s\n  expire: false\nusers:\n- default\n- name: root\n  lock-passwd: false\n  ssh_pwauth: true\n\n--3efa30189c9e0e8ebc24a4decbbf4c2be7b26120c1cdd7cb7bc2ecb0c07c--"
}

Retrieve instance information

Make a GET "http://169.254.169.254/metadata/v1/instance" call to retrieve detailed information about the instance. To tailor information for specific instance details, such as network interfaces, see Extra instance metadata endpoints.

curl -X GET "http://169.254.169.254/metadata/v1/instance?version=2021-10-12"\
  -H "Accept:application/json"\
  -H "Authorization: Bearer $access_token"

The response lists all details for an instance, including network interfaces, compute profile, and volume attachments.

{
  "boot_volume_attachment": {
    "id": "a8a15363-a6f7-4f01-af60-715e85b28141",
    "name": "my-boot-volume-attachment",
    "volume": {
      "crn": "crn:[...]",
      "id": "49c5d61b-41e7-4c01-9b7a-1a97366c6916",
      "name": "my-boot-volume"
    }
  },
  "created_at": "2021-10-19T16:11:57Z",
  "crn": "crn:[...]",
  "disks": [],
  "id": "eb1b7391-2ca2-4ab5-84a8-b92157a633b0",
  "image": {
    "crn": "crn:[...]",
    "id": "9aaf3bcb-dcd7-4de7-bb60-24e39ff9d366",
    "name": "my-image"
  },
  "memory": 8,
  "name": "my-instance",
  "network_interfaces": [
    {
      "id": "7ca88dfb-8962-469d-b1de-1dd56f4c3275",
      "name": "my-network-interface",
      "primary_ipv4_address": "10.0.0.32",
      "resource_type": "network_interface",
      "subnet": {
        "crn": "crn:[...]",
        "id": "bea6a632-5e13-42a4-b4b8-31dc877abfe4",
        "name": "my-subnet",
        "resource_type": "subnet"
      }
    }
  ],
  "primary_network_interface": {
    "id": "7ca88dfb-8962-469d-b1de-1dd56f4c3275",
    "name": "my-network-interface",
    "primary_ipv4_address": "10.0.0.32",
    "resource_type": "network_interface",
    "subnet": {
      "crn": "crn:[...]",
      "id": "bea6a632-5e13-42a4-b4b8-31dc877abfe4",
      "name": "my-subnet",
      "resource_type": "subnet"
    }
  },
  "profile": {
    "name": "bx2-2x8"
  },
  "resource_type": "instance",
  "vcpu": {
    "architecture": "amd64",
    "count": 2
  },
  "volume_attachments": [
    {
      "id": "a8a15363-a6f7-4f01-af60-715e85b28141",
      "name": "my-boot-volume-attachment",
      "volume": {
        "crn": "crn:[...]",
        "id": "49c5d61b-41e7-4c01-9b7a-1a97366c6916",
        "name": "my-boot-volume"
      }
    },
    {
      "id": "e77125cb-4df0-4988-a878-531ae0ae0b70",
      "name": "my-volume-attachment-1",
      "volume": {
        "crn": "crn:[...]",
        "id": "2cc091f5-4d46-48f3-99b7-3527ae3f4392",
        "name": "my-data-volume"
      }
    }
  ],
  "vpc": {
    "crn": "crn:[...]",
    "id": "f0aae929-7047-46d1-92e1-9102b07a7f6f",
    "name": "my-vpc",
    "resource_type": "vpc"
  },
  "zone": {
    "name": "us-south-1"
  }
}

Extra instance metadata endpoints

Table 1 shows more endpoints for API GET calls that you can make to get specific metadata for an instance. (The well-known URL is omitted in the list.)

Table 1. Instance metadata endpoints
API endpoint Description
/metadata/v1/instance/network_interfaces List metadata for all network interfaces for an instance.
/metadata/v1/instance/network_interfaces/{id} Retrieve metadata for a network interface by ID.
/metadata/v1/instance/volume_attachments List metadata for all volume attachments for an instance.
/metadata/v1/instance/volume_attachment/{id} Retrieve metadata for a volume attachment by ID.

For more information about these APIs, including required parameters and examples, see the Metadata service API reference guide.

Retrieve metadata about SSH keys

Make a GET "http://169.254.169.254/metadata/v1/keys" call to retrieve information about all SSH keys configured for the instance. The output is parsed by jq.

curl -X GET "http://169.254.169.254/metadata/v1/keys?version=2021-10-12"\
  -H "Accept:application/json"\
  -H "Authorization: Bearer $access_token" | jq -r

Example output shows one SSH key.

{
  "keys": [
    {
      "created_at": "2021-10-19T16:39:23.000Z",
      "crn": "crn:v1:bluemix:public:is:us-south:a/a1234567::key:r006-44e5e06b-9450-4f5f-a9be-96feebf770d8",
      "fingerprint": "SHA256:lZmocJFsWfJcIl8Jdp8r6Ak8gzMqxrFb9UtwWCk27CM",
      "id": "r006-44e5e06b-9450-4f5f-a9be-96feebf770d8",
      "length": 4096,
      "name": "my-key1",
      "public_key": "ssh-rsa AAAAB...n",
      "resource_type": "key",
      "type": "rsa"
    }
  ]
}

If you have more than one SSH key, you can make a GET "http://169.254.169.254/metadata/v1/keys/{id}" call and provide the SSH key ID.

Retrieve metadata about placement groups

Make a GET "http://169.254.169.254/metadata/v1/placement_groups" call to retrieve information about placement groups configured for the instance. In the example, the return value of the cURL command is a list of placement groups, beginning with the first and up to 50. The output is parsed by jq.

curl -X GET "http://169.254.169.254/metadata/v1/placement_groups?version=2021-10-12"\
  -H "Accept:application/json"\
  -H "Authorization: Bearer $access_token"\
  --data-urlencode "version=2021-10-12"\
  -d '{
        "start": "first",
        "limit": 50
     }' | jq -r

Example return:

{
  "first": {
    "href": "http://169.254.169.254/v1/placement_groups?limit=50"
  },
  "limit": 50,
  "placement_groups": [
    {
      "created_at": "2021-10-12T19:55:00Z",
      "crn": "crn:[...]",
      "id": "r018-418fe842-a3e9-47b9-a938-1aa5bd632871",
      "lifecycle_state": "stable",
      "name": "my-placement-group",
      "resource_type": "placement_group",
      "strategy": "host_spread"
    }
  ],
  "total_count": 1
}

You can also specify details for a single placement group that is used by the instance by making a GET "http://169.254.169.254/metadata/v1/placement_groups/{id}" call and providing the placement group ID.

Next steps