Every VM stores its metadata on a metadata server. Use these instructions to access these metadata values. For more information about metadata, see VM metadata.
This document shows how you can access metadata using the following methods:
You can access all metadata, both default and custom, by querying metadata value entries programmatically from within a VM. You can programmatically query the following metadata entries from a Linux or Windows VM:
- Query a single metadata entry
- Query a metadata directory listing
- Query metadata changes using the
wait-for-change
feature
You can also access custom metadata by viewing it using either the Google Cloud console or Google Cloud CLI.
Before you begin
- If you want to use the command-line examples in this guide, do the following:
- Install or update to the latest version of the Google Cloud CLI.
- Set a default region and zone.
- If you want to use the API examples in this guide, set up API access.
- For Windows Server VMs, use
PowerShell 3.0 or later.
We recommend that you use
ctrl+v
to paste the copied code blocks. - Review limitations when running a query.
- Review the parts of a metadata request.
Permissions
To access VM metadata, the following minimum permissions are required:
compute.projects.get
on the projectcompute.instances.get
on the VM
You can also use a predefined role. To find predefined roles that contain these permissions, see Compute Engine IAM Roles.
How metadata values are arranged
Project and instance metadata: Metadata can be assigned to both projects and VMs. Project metadata propagates to all VMs within a project, while instance metadata only applies to a single VM.
Directory listings: Some metadata entries are directories that contain other metadata keys. This difference is marked by a trailing slash in the metadata name. For example,
attributes/
is a directory that contains other metadata keys.
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.
Query a single metadata entry
Linux
- Connect to your Linux VM.
From your Linux VM, use the
curl
tool to make a query.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
- Connect to your Windows VM.
From your Windows VM, use the
Invoke-RestMethod
command to make a query.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
The metadata server uses directories to organize certain metadata keys. Any metadata entry ending in a trailing slash is a directory.
Linux
The disks/
entry is a directory of disks that is attached to the VM.
To query the disks entry, complete the following steps:
Connect to your Linux VM.
From your Linux VM, run the following commands:
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/
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
Then to query the disk type (
type
) for disks0/
, 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:
Connect to your Windows VM.
From your Windows VM, run the following commands:
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/
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
Then to query the disk type (
type
) for disks0/
, 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
Connect to your Linux VM.
From your Linux VM, use the
curl
tool to make a query.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
Connect to your Windows VM.
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/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.
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.
Linux
- Connect to your Linux VM.
From your Linux VM, use the
curl
tool to make a query.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
- Connect to your Windows VM.
From your Windows VM, use the
Invoke-RestMethod
command to make a query.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, 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 await-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 await-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
- Connect to your Linux VM.
From your Linux VM, use the
curl
tool to make a query.user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/METADATA_KEY?wait_for_change=true" -H "Metadata-Flavor: Google"
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
- Connect to your Windows VM.
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
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:
- Connect to your Linux VM.
Make a request to that key and print the headers. To do this, use the
curl
tool with the-v
flag: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
You can then use that ETag value with the
curl
tool command in yourwait-for-change
request: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:
- Connect to your Windows VM.
Make a request to that key and print the headers. On Windows, use the
Invoke-WebRequest
command.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
You can then use that ETag value in your
wait-for-change
request: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.
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.
Here is an example of a wait-for-change
request that is set to time out after
360 seconds:
Linux
- Connect to your Linux VM.
From your Linux VM, use the
curl
tool to make a query.user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/tags?wait_for_change=true&timeout_sec=360" -H "Metadata-Flavor: Google"
Windows
- Connect to your Windows VM.
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/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. |
Use the Google Cloud console or gcloud CLI to view custom metadata
View custom project metadata
To view custom metadata that applies to all VMs in your project, you can use the Google Cloud console or gcloud CLI.
Console
In the Google Cloud console, go to the Metadata page.
- 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 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
This shows the custom metadata that applies to all VMs in your project.
View custom instance metadata
To view custom metadata that applies to a single VM in your project, you can use the Google Cloud console or gcloud CLI.
Console
- In the Google Cloud console, go to the VM instances page.
Click the name of the VM for which you want to view metadata.
SSH keys for this instance. 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 keyblock-project-ssh-keys
isTRUE
in instance metadata.A value of
Off
indicates that the value of the metadata keyblock-project-ssh-keys
isFALSE
, 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
This shows the custom metadata that applies to the VM.
What's next
- Learn more about VM metadata.
- Set custom metadata.
- Learn how to set and query guest attributes.