View and query VM metadata


Every virtual machine (VM) stores its metadata in directories on a metadata server. Your VM automatically has access to this metadata server API without any additional authorization. You can use the methods explained in the following sections of this document to view and query VM metadata values:

Before you begin

  • For Windows Server VMs, use PowerShell 3.0 or later. We recommend that you use ctrl+v to paste the copied code blocks.
  • Review the basics of how VM metadata for Compute Engine is defined, categorized, and arranged. For more information, see About VM metadata.
  • If you haven't already, set up authentication. Authentication is the process by which your identity is verified for access to Google Cloud services and APIs. To run code or samples from a local development environment, you can authenticate to Compute Engine as follows.

    Select the tab for how you plan to use the samples on this page:

    Console

    When you use the Google Cloud console to access Google Cloud services and APIs, you don't need to set up authentication.

    gcloud

    1. Install the Google Cloud CLI, then initialize it by running the following command:

      gcloud init
    2. Set a default region and zone.

    Python

    To use the Python samples on this page from a local development environment, install and initialize the gcloud CLI, and then set up Application Default Credentials with your user credentials.

    1. Install the Google Cloud CLI.
    2. To initialize the gcloud CLI, run the following command:

      gcloud init
    3. Create local authentication credentials for your Google Account:

      gcloud auth application-default login

    For more information, see Set up authentication for a local development environment.

    REST

    To use the REST API samples on this page in a local development environment, you use the credentials you provide to the gcloud CLI.

      Install the Google Cloud CLI, then initialize it by running the following command:

      gcloud init

Required roles

The following roles and permissions are needed to view custom metadata from outside the VM by using the Google Cloud console, the Google Cloud CLI, or REST. If you are programmatically querying the metadata from within the VM, you only need the roles and permissions for connecting to the VM.

To get the permissions that you need to view custom metadata from outside the VM, ask your administrator to grant you the following IAM roles:

For more information about granting roles, see Manage access.

These predefined roles contain the permissions required to view custom metadata from outside the VM. To see the exact permissions that are required, expand the Required permissions section:

Required permissions

The following permissions are required to view custom metadata from outside the VM:

  • To view custom project-wide metadata: compute.projects.get on the project
  • To view custom project zonal metadata: compute.instanceSettings.get on the instance settings in the required zone in the project
  • To view custom metadata for a VM instance: compute.instances.get on the VM
  • If your VMs use service accounts: iam.serviceAccounts.actAs on the service accounts or project

You might also be able to get these permissions with custom roles or other predefined roles.

Programmatically query metadata

From within a VM, you can programmatically query either default or custom metadata values using tools such as curl tool on Linux or Invoke-RestMethod on Windows.

Parts of a metadata request

The following table summarizes the main parts of a metadata query request.

Components Description
Root URL

All metadata values are defined as sub-paths below the following root URLs:

  • http://metadata.google.internal/computeMetadata/v1
  • http://169.254.169.254/v1
  • http://metadata.goog/v1
Request header

This header indicates that the request was sent with the intention of retrieving metadata values, rather than unintentionally from an insecure source, and lets the metadata server return the data you requested. If you don't provide this header, the metadata server denies your request.

Metadata-Flavor: Google

Query a single metadata entry

Use the following commands to query a single metadata entry.

Linux

  1. Connect to your Linux VM.
  2. From your Linux VM, use the curl tool to make a query.

    • To query for a VM instance metadata entry, run the following command:

      curl "http://metadata.google.internal/computeMetadata/v1/instance/METADATA_KEY" -H "Metadata-Flavor: Google"
      
    • To query for a project metadata entry, run the following command:

      curl "http://metadata.google.internal/computeMetadata/v1/project/METADATA_KEY" -H "Metadata-Flavor: Google"
      

    Replace METADATA_KEY with the instance or project metadata key for which you want to query the value.

    For example, to query the boot image for the VM, run the following query:

    user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/image" -H "Metadata-Flavor: Google"
    

    The output is similar to the following:

    projects/rhel-cloud/global/images/rhel-8-v20210122

Windows

  1. Connect to your Windows VM.
  2. From your Windows VM, use the Invoke-RestMethod command to make a query.

    • To query for a VM instance metadata entry, run the following command:

      $value = (Invoke-RestMethod `
              -Headers @{'Metadata-Flavor' = 'Google'} `
              -Uri "http://metadata.google.internal/computeMetadata/v1/instance/METADATA_KEY")
      $value
      
    • To query for a project metadata entry, run the following command:

      $value = (Invoke-RestMethod `
              -Headers @{'Metadata-Flavor' = 'Google'} `
              -Uri "http://metadata.google.internal/computeMetadata/v1/project/METADATA_KEY")
      $value
      

    Replace METADATA_KEY with the instance or project metadata key for which you want to query the value.

    For example, to query the boot image for the VM, run the following query:

    PS C:\> 
    $value = (Invoke-RestMethod `
              -Headers @{'Metadata-Flavor' = 'Google'} `
              -Uri "http://metadata.google.internal/computeMetadata/v1/instance/image")
    $value
    

    The output is similar to the following:

    projects/windows-cloud/global/images/windows-server-2019-dc-v20210112

Query metadata directory listings

Use the following commands to query metadata directory listings. Directory listings are metadata entries that contain other metadata keys. Any metadata entry ending in a trailing slash is a directory listing

Linux

  1. Connect to your Linux VM.

  2. From your Linux VM, run the following commands:

    • To query for a VM instance metadata directory, run the following command:

      curl "http://metadata.google.internal/computeMetadata/v1/instance/METADATA_DIRECTORY_NAME/" -H "Metadata-Flavor: Google"
      
    • To query for a project metadata directory, run the following command:

      curl "http://metadata.google.internal/computeMetadata/v1/project/METADATA_DIRECTORY_NAME/" -H "Metadata-Flavor: Google"
      

    Replace METADATA_DIRECTORY_NAME with the name of the instance or project metadata directory for which you want to query the listings.

    For example, consider the disks/ entry, which is a directory of disks that is attached to the VM. To query the disks/ entry, complete the following steps:

    1. Run the curl tool command on the disks directory.

      user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/disks/" -H "Metadata-Flavor: Google"
      

      The output is similar to the following:

      0/
      1/
      2/
      
    2. If you want more information about disk 0/ directory, you can then query the specific URL for that directory:

      user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/disks/0/" -H "Metadata-Flavor: Google"
      

      The output is similar to the following:

      device-name
      index
      mode
      type
      
    3. Then to query the disk type (type) for disks 0/, you can run the following:

      user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/disks/0/type" -H "Metadata-Flavor: Google"
      

      The output is similar to the following:

      PERSISTENT
      

Windows

The disks/ entry is a directory of disks that is attached to the VM. To query the disks entry, complete the following steps:

  1. Connect to your Windows VM.

  2. From your Windows VM, run the following commands:

    • To query for a VM instance metadata directory, run the following command:

      $value = (Invoke-RestMethod `
              -Headers @{'Metadata-Flavor' = 'Google'} `
              -Uri "http://metadata.google.internal/computeMetadata/v1/instance/METADATA_DIRECTORY_NAME/")
      $value
      
    • To query for a project metadata directory, run the following command:

      $value = (Invoke-RestMethod `
              -Headers @{'Metadata-Flavor' = 'Google'} `
              -Uri "http://metadata.google.internal/computeMetadata/v1/project/METADATA_DIRECTORY_NAME/")
      $value
      

    Replace METADATA_DIRECTORY_NAME with the name of the instance or project metadata directory for which you want to query the listings.

    For example, consider the disks/ entry, which is a directory of disks that is attached to the VM. To query the disks/ entry, complete the following steps:

    1. Use the Invoke-RestMethod command on the disks directory.

      PS C:\> 
      $value = (Invoke-RestMethod `
                -Headers @{'Metadata-Flavor' = 'Google'} `
                -Uri "http://metadata.google.internal/computeMetadata/v1/instance/disks/")
      $value
      

      The output is similar to the following:

      0/
      1/
      2/
      
    2. If you want more information about disk 0/ directory, you can query the specific URL for that directory:

      PS C:\> 
      $value = (Invoke-RestMethod `
                -Headers @{'Metadata-Flavor' = 'Google'} `
                -Uri "http://metadata.google.internal/computeMetadata/v1/instance/disks/0/")
      $value
      

      The output is similar to the following:

      device-name
      index
      mode
      type
      
    3. Then to query the disk type (type) for disks 0/, you can run the following:

      PS C:\> 
      $value = (Invoke-RestMethod `
                -Headers @{'Metadata-Flavor' = 'Google'} `
                -Uri "http://metadata.google.internal/computeMetadata/v1/instance/disks/0/type")
      $value
      

      The output is similar to the following:

      PERSISTENT
      

Recursively query directory listings

If you want to return all contents under a directory, use the recursive=true query parameter with your request:

Linux

  1. Connect to your Linux VM.

  2. From your Linux VM, use the curl tool to make a query.

    • To recursively query the listings for a VM instance metadata directory, run the following command:

      curl "http://metadata.google.internal/computeMetadata/v1/instance/METADATA_DIRECTORY_NAME/?recursive=true" -H "Metadata-Flavor: Google"
      
    • To recursively query the listings for a project metadata directory, run the following command:

      curl "http://metadata.google.internal/computeMetadata/v1/project/METADATA_DIRECTORY_NAME/?recursive=true" -H "Metadata-Flavor: Google"
      

    Replace METADATA_DIRECTORY_NAME with the name of the instance or project metadata directory for which you want to recursively query the listings.

    For example, the following command recursively queries the instance metadata listings for the disks/ directory.

      user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/disks/?recursive=true" -H "Metadata-Flavor: Google"
      

    The output is similar to the following:

      [{"deviceName":"boot","index":0,"mode":"READ_WRITE","type":"PERSISTENT"},
      {"deviceName":"persistent-disk-1","index":1,"mode":"READ_WRITE","type":"PERSISTENT"},
      {"deviceName":"persistent-disk-2","index":2,"mode":"READ_ONLY","type":"PERSISTENT"}]
      

    By default, recursive contents are returned in JSON format. If you want to return these contents in text format, append the alt=text query parameter:

      user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/disks/?recursive=true&alt=text" -H "Metadata-Flavor: Google"
      

    The output is similar to the following:

      0/device-name boot
      0/index 0
      0/mode READ_WRITE
      0/type PERSISTENT
      1/device-name persistent-disk-1
      1/index 1
      1/mode READ_WRITE
      1/type PERSISTENT
      2/device-name persistent-disk-1
      2/index 2
      2/mode READ_ONLY
      2/type PERSISTENT
      

Windows

  1. Connect to your Windows VM.

  2. From your Windows VM, use the Invoke-RestMethod command to make a query.

    • To recursively query the listings for a VM instance metadata directory, run the following command:

      $value = (Invoke-RestMethod `
                -Headers @{'Metadata-Flavor' = 'Google'} `
                -Uri "http://metadata.google.internal/computeMetadata/v1/instance/METADATA_DIRECTORY_NAME/?recursive=true")
      $value
      
    • To recursively query the listings for a project metadata directory, run the following command:

      $value = (Invoke-RestMethod `
                -Headers @{'Metadata-Flavor' = 'Google'} `
                -Uri "http://metadata.google.internal/computeMetadata/v1/project/METADATA_DIRECTORY_NAME/?recursive=true")
      $value
      

    Replace METADATA_DIRECTORY_NAME with the name of the instance or project metadata directory for which you want to recursively query the listings.

    For example, the following command recursively queries the instance metadata listings for the disks/ directory.

    PS C:\> 
    $value = (Invoke-RestMethod `
              -Headers @{'Metadata-Flavor' = 'Google'} `
              -Uri "http://metadata.google.internal/computeMetadata/v1/instance/disks/?recursive=true")
    $value
    

    The output is similar to the following:

    [{"deviceName":"boot","index":0,"mode":"READ_WRITE","type":"PERSISTENT"},
    {"deviceName":"persistent-disk-1","index":1,"mode":"READ_WRITE","type":"PERSISTENT"},
    {"deviceName":"persistent-disk-2","index":2,"mode":"READ_ONLY","type":"PERSISTENT"}]
    

    By default, recursive contents are returned in JSON format. If you want to return these contents in text format, append the alt=text query parameter:

    PS C:\> 
    $value = (Invoke-RestMethod `
              -Headers @{'Metadata-Flavor' = 'Google'} `
              -Uri "http://metadata.google.internal/computeMetadata/v1/instance/disks/?recursive=true&alt=text")
    $value
    

    The output is similar to the following:

    0/device-name boot
    0/index 0
    0/mode READ_WRITE
    0/type PERSISTENT
    1/device-name persistent-disk-1
    1/index 1
    1/mode READ_WRITE
    1/type PERSISTENT
    2/device-name persistent-disk-1
    2/index 2
    2/mode READ_ONLY
    2/type PERSISTENT
    

Format query output

By default, each endpoint has a predefined format for the response. Some endpoints might return data in JSON format by default, while other endpoints might return data as a string. You can override the default data format specification by using the alt=json or alt=text query parameters, which return data in JSON string format or as a plain text representation, respectively.

Linux

  1. Connect to your Linux VM.
  2. From your Linux VM, use the curl tool to make a query.

    • To change the query response data format for a VM instance metadata entry, run the following command:

      curl "http://metadata.google.internal/computeMetadata/v1/instance/METADATA_KEY?alt=DATA_FORMAT" -H "Metadata-Flavor: Google"
      
    • To change the query response data format for a project metadata entry, run the following command:

      curl "http://metadata.google.internal/computeMetadata/v1/project/METADATA_KEY?alt=DATA_FORMAT" -H "Metadata-Flavor: Google"
      

    Replace the following:

    • METADATA_KEY: the instance or project metadata key for which you want to query the value.
    • DATA_FORMAT: the format in which you want the query response data—for example, text or json.

Example

For example, the tags key automatically returns data in JSON format. You can return data in text format instead, by specifying the alt=text query parameter.

Default query

  user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/tags" -H "Metadata-Flavor: Google"
  

The output is similar to the following:

  ["http-server", "db-client", "app-server", "mysql-server"]
  

Query with formatting

  user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/tags?alt=text" -H "Metadata-Flavor: Google"
  

The output is similar to the following:

  http-server
  db-client
  app-server
  mysql-server

Windows

  1. Connect to your Windows VM.
  2. From your Windows VM, use the Invoke-RestMethod command to make a query.

    • To change the query response data format for a VM instance metadata entry, run the following command:

      $value = (Invoke-RestMethod `
                -Headers @{'Metadata-Flavor' = 'Google'} `
                -Uri "http://metadata.google.internal/computeMetadata/v1/instance/METADATA_KEY?alt=DATA_FORMAT")
      $value
      
    • To change the query response data format for a project metadata entry, run the following command:

      $value = (Invoke-RestMethod `
                -Headers @{'Metadata-Flavor' = 'Google'} `
                -Uri "http://metadata.google.internal/computeMetadata/v1/project/METADATA_KEY?alt=DATA_FORMAT")
      $value
      

    Replace the following:

    • METADATA_KEY: the instance or project metadata key for which you want to query the value.
    • DATA_FORMAT: the format in which you want the query response data—for example, text or json.

Example

For example, the tags key automatically returns data in JSON format. You can return data in text format instead, by specifying the alt=text query parameter.

Default query

  PS C:> 
  $value = (Invoke-RestMethod -Headers @{'Metadata-Flavor' = 'Google'}
            -Uri "http://metadata.google.internal/computeMetadata/v1/instance/tags")
  $value
  

The output is similar to the following:

  ["http-server", "db-client", "app-server", "mysql-server"]
  

Query with formatting

  PS C:> 
  $value = (Invoke-RestMethod -Headers @{'Metadata-Flavor' = 'Google'}
            -Uri "http://metadata.google.internal/computeMetadata/v1/instance/tags?alt=text")
  $value
  

The output is similar to the following:

  http-server
  db-client
  app-server
  mysql-server

Query metadata changes using the wait-for-change feature

Given that metadata values can change while your VM is running, the metadata server can be notified of metadata changes by using the wait-for-change feature. With this option, the request only returns an output when your specified metadata has changed.

You can use this feature on custom metadata or server-defined metadata, so if anything changes about your VM or project, or if someone updates a custom metadata entry, you can programmatically react to the change.

For example, you can perform a request on the tags key so that the request only returns if the contents of the tags metadata has changed. When the request returns, it provides the new value of that metadata key.

The wait-for-change feature also lets you match with your request and set timeouts.

When working with thewait-for-change feature, consider the following:

  • You can only perform a wait-for-change request on a metadata endpoint or recursively on the contents of a directory. You cannot perform a wait-for-change request on a directory listing. If you try to do this, the metadata server fails your request and returns a 400 Invalid Request error.

  • You cannot perform a wait-for-change request for a service account token. If you try to make a wait-for-change request to the service account token URL, the request fails immediately and returns a 400 Invalid Request error.

To perform a wait-for-change request, query a metadata key and append the ?wait_for_change=true query parameter:

Linux

  1. Connect to your Linux VM.
  2. From your Linux VM, use the curl tool to make a query.

    • To perform a wait-for-change request for a VM instance metadata entry, run the following command:

      curl "http://metadata.google.internal/computeMetadata/v1/instance/METADATA_KEY?wait_for_change=true" -H "Metadata-Flavor: Google"
      
    • To perform a wait-for-change request for a project metadata entry, run the following command:

      curl "http://metadata.google.internal/computeMetadata/v1/project/METADATA_KEY" -H "Metadata-Flavor: Google"
      

    Replace METADATA_KEY with the instance or project metadata key for which you want to query the value.

    After there is a change to the specified metadata key, the query returns with the new value.

Examples

In this example, if a request is made to the setInstanceTags method, the request returns with the new values:

  user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/tags?wait_for_change=true" -H "Metadata-Flavor: Google"
  

The output is similar to the following:

  http-server
  db-client
  

You can also perform a wait-for-change request recursively on the contents of a directory:

  user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/attributes/?recursive=true&wait_for_change=true" -H "Metadata-Flavor: Google"
  

The metadata server returns the new contents if there is any change:

  {"foo":"bar","baz":"bat"}
  

Windows

  1. Connect to your Windows VM.
  2. From your Windows VM, use the Invoke-RestMethod command to make a query.

      PS C:> 
      $value = (Invoke-RestMethod -Headers @{'Metadata-Flavor' = 'Google'}
                -Uri "http://metadata.google.internal/computeMetadata/v1/METADATA_KEY?wait_for_change=true")
      $value
      

    • To perform a wait-for-change request for a VM instance metadata entry, run the following command:

      $value = (Invoke-RestMethod `
              -Headers @{'Metadata-Flavor' = 'Google'} `
              -Uri "http://metadata.google.internal/computeMetadata/v1/instance/METADATA_KEY?wait_for_change=true")
      $value
      
    • To perform a wait-for-change request for a project metadata entry, run the following command:

      $value = (Invoke-RestMethod `
              -Headers @{'Metadata-Flavor' = 'Google'} `
              -Uri "http://metadata.google.internal/computeMetadata/v1/project/METADATA_KEY?wait_for_change=true")
      $value
      

    Replace METADATA_KEY with the instance or project metadata key for which you want to perform a wait-for-change request.

    After there is a change to the specified metadata key, the query returns with the new value.

Examples

After there is a change to the specified metadata key, the query returns with the new value. In this example, if a request is made to the setInstanceTags method, the request returns with the new values:

  PS C:> 
  $value = (Invoke-RestMethod -Headers @{'Metadata-Flavor' = 'Google'}
            -Uri "http://metadata.google.internal/computeMetadata/v1/instance/tags?wait_for_change=true")
  $value
  

The output is similar to the following:

  http-server
  db-client
  

You can also perform a wait-for-change request recursively on the contents of a directory:

  PS C:> 
  $value = (Invoke-RestMethod -Headers @{'Metadata-Flavor' = 'Google'}
            -Uri "http://metadata.google.internal/computeMetadata/v1/instance/attributes?recursive=true&wait_for_change=true")
  $value
  

The metadata server returns the new contents if there is any change:

  {"foo":"bar","baz":"bat"}
  

Use ETags

When you submit a simple wait-for-change query, the metadata server returns a response if anything has changed in the contents of that metadata. However, there is an inherent race condition between a metadata update and a wait-for-change request being issued, so it's useful to have a reliable way to know you are getting the latest metadata value.

To help with this, you can use the last_etag query parameter, which compares the ETag value you provide with the ETag value saved on the metadata server. If the ETag values match, then the wait-for-change request is accepted. If the ETag values do not match, this indicates that the contents of the metadata has changed since the last time you retrieved the ETag value, and the metadata server returns immediately with this latest value.

Linux VMs

To get the current ETag value for a metadata key, complete the following steps:

  1. Connect to your Linux VM.
  2. Make a request to that key and print the headers. To do this, use the curl tool with the -v flag:

    • To get the current ETag for a VM instance metadata entry, run the following command:

      curl -v "http://metadata.google.internal/computeMetadata/v1/instance/METADATA_KEY" -H "Metadata-Flavor: Google"
      
    • To get the current ETag for a project metadata entry, run the following command:

      curl -v "http://metadata.google.internal/computeMetadata/v1/project/METADATA_KEY" -H "Metadata-Flavor: Google"
      

    Replace METADATA_KEY with the instance or project metadata key for which you want to query the value.

    For example, the following command gets the current ETag value for the tags instance metadata key.

      user@myinst:~$ curl -v "http://metadata.google.internal/computeMetadata/v1/instance/tags" -H "Metadata-Flavor: Google"
      

    The output is similar to the following:

    * About to connect() to metadata port 80 (#0)
    * Trying 169.254.169.254... connected
    * Connected to metadata (169.254.169.254) port 80 (#0)
    > GET /computeMetadata/v1/instance/tags HTTP/1.1
    > User-Agent: curl/7.19.7 (x86_64-pc-linux-gnu) libcurl/7.19.7 OpenSSL/0.9.8k zlib/1.2.3.3 libidn/1.15
    > Host: metadata
    > Accept: */*
    >
    < HTTP/1.1 200 OK
    < Content-Type: application/text
    < ETag: 411261ca6c9e654e
    < Date: Wed, 13 Feb 2013 22:43:45 GMT
    < Server: Metadata Server for VM
    < Content-Length: 26
    < X-XSS-Protection: 1; mode=block
    < X-Frame-Options: SAMEORIGIN
    <
    http-server
    db-client
  3. You can then use that ETag value with the curl tool command in your wait-for-change request:

    • To use the ETag value for the wait-for-change request of instance metadata, run the following command:

      curl "http://metadata.google.internal/computeMetadata/v1/instance/METADATA_KEY?wait_for_change=true&last_etag=ETAG" -H "Metadata-Flavor: Google"
      
    • To use the ETag value for the wait-for-change request of project metadata, run the following command:

      curl "http://metadata.google.internal/computeMetadata/v1/project/METADATA_KEY?wait_for_change=true&last_etag=ETAG" -H "Metadata-Flavor: Google"
      

    Replace the following:

    • METADATA_KEY: the instance or project metadata key for which you want to query the value.
    • ETAG: the ETag value for the metadata key.

    In this example, the following command uses the ETag value for the tags key and queries for the instance metadata entry.

      user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/tags?wait_for_change=true&last_etag=411261ca6c9e654e" -H "Metadata-Flavor: Google"
      

    The metadata server matches your specified ETag value, and if that value changes, the request returns with the new contents of your metadata key.

Windows VMs

To get the current ETag value for a metadata key, complete the following steps:

  1. Connect to your Windows VM.
  2. Make a request to that key and print the headers. On Windows, use the Invoke-WebRequest command.

    • To get the current ETag for a VM instance metadata entry, run the following command:

      $value = (Invoke-WebRequest -Headers @{'Metadata-Flavor' = 'Google'} `
      -Uri http://metadata.google.internal/computeMetadata/v1/instance/METADATA_KEY)
      
      $value.Headers.ETag
      
    • To get the current ETag for a project metadata entry, run the following command:

      $value = (Invoke-WebRequest -Headers @{'Metadata-Flavor' = 'Google'} `
      -Uri http://metadata.google.internal/computeMetadata/v1/project/METADATA_KEY)
      
      $value.Headers.ETag
      

    Replace METADATA_KEY with the instance or project metadata key for which you want to query the value.

    For example, the following command gets the current ETag value for the tags instance metadata key.

      PS C:> 
      $value = (Invoke-WebRequest -Headers @{'Metadata-Flavor' = 'Google'} `
      -Uri http://metadata.google.internal/computeMetadata/v1/instance/tags)

    $value.Headers.ETag

    The output is similar to the following:

      * About to connect() to metadata port 80 (#0)
      * Trying 169.254.169.254... connected
      * Connected to metadata (169.254.169.254) port 80 (#0)
      > GET /computeMetadata/v1/instance/tags HTTP/1.1
      > User-Agent: curl/7.19.7 (x86_64-pc-linux-gnu) libcurl/7.19.7 OpenSSL/0.9.8k zlib/1.2.3.3 libidn/1.15
      > Host: metadata
      > Accept: /
      >
      < HTTP/1.1 200 OK
      < Content-Type: application/text
      < ETag: 411261ca6c9e654e
      < Date: Wed, 13 Feb 2013 22:43:45 GMT
      < Server: Metadata Server for VM
      < Content-Length: 26
      < X-XSS-Protection: 1; mode=block
      < X-Frame-Options: SAMEORIGIN
      <
      http-server
      db-client

  3. You can then use that ETag value in your wait-for-change request:

    • To use the ETag value for the wait-for-change request of instance metadata, run the following command:

      $value = (Invoke-RestMethod `
              -Headers @{'Metadata-Flavor' = 'Google'} `
              -Uri "http://metadata.google.internal/computeMetadata/v1/instance/METADATA_KEY?wait_for_change=true&last_etag=ETAG")
      $value
      
    • To use the ETag value for the wait-for-change request of project metadata, run the following command:

      $value = (Invoke-RestMethod `
              -Headers @{'Metadata-Flavor' = 'Google'} `
              -Uri "http://metadata.google.internal/computeMetadata/v1/project/METADATA_KEY?wait_for_change=true&last_etag=ETAG")
      $value
      

    Replace the following:

    • METADATA_KEY: the instance or project metadata key for which you want to query the value.
    • ETAG: the ETag value for the metadata key.

    In this example, the following command uses the ETag value for the tags key and queries for the instance metadata entry.

      PS C:> 
      $value = (Invoke-RestMethod -Headers @{'Metadata-Flavor' = 'Google'}
                -Uri "http://metadata.google.internal/computeMetadata/v1/instance/tags?wait_for_change=true&last_etag=411261ca6c9e654e")
      $value
      

    The metadata server matches your specified ETag value, and if that value changes, the request returns with the new contents of your metadata key.

Python

The following Python sample shows how to programmatically watch the metadata server for changes.

This sample sets the initial ETag to 0. The metadata server will not return a response with 0 as the ETag value. When 0 is specified as the last ETag in a request, the metadata server responds with the current value and ETag. This saves a bit of the code needed to get the initial value and ETag.

last_etag = "0"

while True:
    r = requests.get(
        url,
        params={"last_etag": last_etag, "wait_for_change": True},
        headers=METADATA_HEADERS,
    )

    # During maintenance the service can return a 503, so these should
    # be retried.
    if r.status_code == 503:
        time.sleep(1)
        continue
    r.raise_for_status()

    last_etag = r.headers["etag"]

Set timeouts

If you would like your wait-for-change request to time out after a certain number of seconds, you can set the timeout_sec parameter. The timeout_sec parameter limits the wait time of your request to the number of seconds you specified, and when the request reaches that limit, it returns the current contents of the metadata key.

When you set the timeout_sec parameter, the request always returns after the specified number of seconds, whether or not the metadata value has actually changed. It is only possible to set an integer value for your timeout.

Linux

  1. Connect to your Linux VM.
  2. From your Linux VM, use the curl tool to make a query.

    • To perform a wait-for-change request with a time out value for a VM instance metadata entry, run the following command:

      curl "http://metadata.google.internal/computeMetadata/v1/instance/METADATA_KEY?wait_for_change=true&timeout_sec=TIMEOUT" -H "Metadata-Flavor: Google"
      
    • To perform a wait-for-change request with a time out value for a project metadata entry, run the following command:

      curl "http://metadata.google.internal/computeMetadata/v1/project/METADATA_KEY?wait_for_change=true&timeout_sec=TIMEOUT" -H "Metadata-Flavor: Google"
      

    Replace the following:

    • METADATA_KEY: the instance or project metadata key for which you want to query the value.
    • TIMEOUT: the time out value.

For example, the following command performs a wait-for-change request that is set to time out after 360 seconds:

  user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/tags?wait_for_change=true&timeout_sec=360" -H "Metadata-Flavor: Google"
  

Windows

  1. Connect to your Windows VM.
  2. From your Windows VM, use the Invoke-RestMethod command to make a query.

    • To perform a wait-for-change request with a time out value for a VM instance metadata entry, run the following command:

      $value = (Invoke-RestMethod `
              -Headers @{'Metadata-Flavor' = 'Google'} `
              -Uri "http://metadata.google.internal/computeMetadata/v1/instance/METADATA_KEY?wait_for_change=true&timeout_sec=TIMEOUT")
      $value
      
    • To perform a wait-for-change request with a time out value for a project metadata entry, run the following command:

      $value = (Invoke-RestMethod `
              -Headers @{'Metadata-Flavor' = 'Google'} `
              -Uri "http://metadata.google.internal/computeMetadata/v1/project/METADATA_KEY?wait_for_change=true&timeout_sec=TIMEOUT")
      $value
      

    Replace the following:

    • METADATA_KEY: the instance or project metadata key for which you want to query the value.
    • TIMEOUT: the time out value.

For example, the following command performs a wait-for-change request that is set to time out after 360 seconds:

  PS C:> 
  $value = (Invoke-RestMethod -Headers @{'Metadata-Flavor' = 'Google'}
            -Uri "http://metadata.google.internal/computeMetadata/v1/instance/tags?wait_for_change=true&timeout_sec=360")
  $value
  

Status codes

When you perform a wait-for-change request, the metadata server returns standard HTTP status codes to indicate success or failure. In the case of errors, network conditions can cause the metadata server to fail your request and return an error code. In these cases, you should design your application to be fault-tolerant and to be able to recognize and handle these errors.

The possible statuses that the metadata server returns are:

Status Description
HTTP 200 Success! A value was changed, or you reached your specified timeout_sec and the request returned successfully.
Error 400 Your request was invalid. Please fix your query and retry the request.
Error 404 The metadata value you specified no longer exists. The metadata server also returns this error if your metadata is deleted while you are waiting on a change.
Error 503 There was a temporary server error or a temporary maintenance event. Retry the request.

Limitations

  • Any requests that contain the header X-Forwarded-For are automatically rejected by the metadata server. This header generally indicates that the request was proxied and might not be a request made by an authorized user. For security reasons, all such requests are rejected.

  • When you use the curl command to retrieve metadata from the server, note that some encoded characters aren't supported in the request path. Encoded characters are only supported in the query path.

    For example, the following request might not work:

    curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/123456789-compute%40developer.gserviceaccount.com/?query_path=https%3A%2F%2Flocalhost%3A8200%2Fexample%2Fquery&another_param=true" -H "Metadata-Flavor: Google"

    For this request to work, you must replace the unsupported encoded character in the request path (%40) with the equivalent accepted value (@).

    curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/1234567898-compute@developer.gserviceaccount.com/?query_path=https%3A%2F%2Flocalhost%3A8200%2Fexample%2Fquery&another_param=true" -H "Metadata-Flavor: Google"

    The following table summarises the encoded characters that aren't supported in a request path.

    Encoded character Accepted value
    %21
    !
    %24
    $
    %27
    '
    %28
    (
    %29
    )
    %2A
    *
    %2C
    ,
    %40
    @

View the custom metadata for your VMs

You can view the custom metadata values for your Compute Engine VMs in one of the following ways:

View project-wide metadata

To view custom metadata that applies to all VMs in your project, use one of the following methods.

Console

  1. In the Google Cloud console, go to the Metadata page.

    Go to Metadata

    • From the Metadata tab, you can review most of your custom project metadata with the exception of SSH key metadata.
    • From the SSH keys tab, you can review all your project-level SSH key metadata.

gcloud

Use the gcloud compute project-info describe command to query project-wide metadata:

gcloud compute project-info describe --flatten="commonInstanceMetadata[]"

The output is similar to the following:

---
fingerprint: HcSFdS_1_1I=
items:
- key: ssh-keys
  value: USERNAME:ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDWZ...
kind: compute#metadata

REST

To query project metadata, create a GET request to the project.get method.

Replace PROJECT_ID with your project ID.

GET https://compute.googleapis.com/compute/v1/projects/PROJECT_ID

The output is similar to the following:

"kind": "compute#project",
"id": "XXXXXXX",
"creationTimestamp": "2018-12-10T08:34:33.616-08:00",
"name": "YOUR_PROJECT",
"commonInstanceMetadata": {
  "kind": "compute#metadata",
  "fingerprint": "XXXXXCdg=",
  "items": [
    {
      "key": "enable-guest-attributes",
      "value": "TRUE"
    },
    {
      "key": "enable-os-inventory",
      "value": "true"
    },
    {
      "key": "enable-osconfig",
      "value": "TRUE"
    },
    {
      "key": "enable-oslogin",
      "value": "TRUE"
    },
    {
      "key": "sshKeys",
      "value": "XXXXX"
    }
  ]
}, ...

View project zonal metadata

To view custom metadata that applies to all VM instances in a specific zone in a project, use one of the following methods.

gcloud

To query the custom project zonal metadata, use the gcloud beta compute project-zonal-metadata describe command.

gcloud beta compute project-zonal-metadata describe \
    --zone=ZONE \
    --project=PROJECT_ID

Replace the following:

  • PROJECT_ID: your project ID
  • ZONE: the zone for which you want to view the project zonal metadata.

The output is similar to the following:

{
  "fingerprint": "VlRIl8dx9vk=",
  "metadata": {
    items: {
      "key-1": "value-1",
      "key-2": "value-2"
    }
  }
}

REST

To query the custom project zonal metadata, make a GET request to the instanceSettings().get method

GET https://compute.googleapis.com/compute/beta/projects/PROJECT_ID/zones/ZONE/instanceSettings

Replace the following:

  • PROJECT_ID: your project ID
  • ZONE: the zone for which you want to view the project zonal metadata.

The output is similar to the following:

{
  "fingerprint": "VlRIl8dx9vk=",
  "metadata": {
    items: {
      "key-1": "value-1",
      "key-2": "value-2"
    }
  }
}

View instance metadata

To view metadata that applies to a single VM in your project, use one of the following methods.

Console

  1. In the Google Cloud console, go to the VM instances page.

    Go to VM instances

  2. Click the name of the VM for which you want to view metadata.

    • SSH keys for this VM. In the Security and access section, view the SSH keys field.

      • A value of None indicates there are no SSH keys stored in instance metadata.

      • Any other value indicates that there are SSH keys stored in instance metadata.

    • SSH keys for a project. In the Security and access section, view the Block project-wide SSH keys field.

      • A value of On indicates that the value of the metadata key block-project-ssh-keys is TRUE in instance metadata.

      • A value of Off indicates that the value of the metadata key block-project-ssh-keys is FALSE, or that the key isn't set.

    • All other custom metadata. View the Custom metadata section. You see all custom metadata keys and values, other than SSH key metadata.

gcloud

Use the gcloud compute instances describe command to query instance metadata:

gcloud compute instances describe VM_NAME --flatten="metadata[]"

Replace VM_NAME with the name of the VM you want to find metadata for.

The output is similar to the following:

---
fingerprint: MTgTJ5m-Cjs=
items:
- key: enable-oslogin
  value: 'true'
kind: compute#metadata

REST

To query metadata for a specific VM, send a GET request to the instances.get method.

GET https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME

The output is similar to the following:

......
"metadata": {
"kind": "compute#metadata",
"fingerprint": "XXXXXXVo=",
"items": [
  {
    "key": "enable-oslogin",
    "value": "true"
  }
]
},....

Replace the following:

  • PROJECT_ID: your project ID
  • ZONE: the zone where the VM is located
  • VM_NAME: the name of the VM

What's next