Every instance stores its metadata on a metadata server. You can query this metadata server programmatically, from within the instance and from the Compute Engine API. You can query for information about the instance, such as the instance's host name, instance ID, startup and shutdown scripts, custom metadata, and service account information. Your instance automatically has access to the metadata server API without any additional authorization.
The metadata server is particularly useful when used in combination with startup and shutdown scripts because you can use the metadata server to programmatically get unique information about an instance, without additional authorization. For example, you can write a startup script that gets the metadata key-value pair for an instance's external IP and use that IP in your script to set up a database. Because the default metadata keys are the same on every instance, you can reuse your script without having to update it for each instance. This helps you create less brittle code for your applications.
Metadata is stored in the format key:value
. There is a default set of
metadata entries that every instance has access to. You can also set
custom metadata.
To access the metadata server, you can query the metadata URL.
For information about how to check the version of your metadata server endpoint, see Checking the version of your server endpoint.
Before you begin
- If you want to use the command-line examples in this guide:
- Install or update to the latest version of the gcloud command-line tool.
- Set a default region and zone.
- If you want to use the API examples in this guide, set up API access.
Permissions required for this task
To perform this task, you must have the following permissions:
compute.instances.setMetadata
on the instance if setting instance metadatacompute.projects.setCommonInstanceMetadata
on the project if setting project-wide metadatacompute.projects.get
on the project if just getting metadatacompute.instances.get
on the instance if just getting metadata
Project and instance metadata
Metadata can be assigned to both projects and instances. Project metadata propagates to all virtual machine (VM) instances within the project, while instance metadata only impacts that instance.
Default metadata keys
For a list of default metadata values that you can query, see Default VM metadata values.
Getting metadata
You can query the contents of the metadata server by making a request to the
following root URLs from within a virtual machine instance. Use the
http://metadata.google.internal/computeMetadata/v1/
URL to make requests to the metadata server.
All metadata values are defined as sub-paths below these root URLs.
You can query for default metadata
values only from within the associated instance. You cannot query an instance's
default metadata from another instance or directly from your local computer. You
can use standard tools like curl
or wget
from the instance to its metadata
server.
When you query for metadata, you must provide the following header in all of your requests:
Metadata-Flavor: Google
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.
X-Forwarded-For header
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.
Limitations
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 | @ |
Is metadata information secure?
When you make a request to get information from the metadata server, your request and the subsequent metadata response never leave the physical host that is running the virtual machine instance.
Querying directory listings
The metadata server uses directories to organize certain metadata keys. Any
metadata entry ending in a trailing slash is a directory. For example, the
disks/
entry is a directory of disks attached to that instance:
user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/disks/" -H "Metadata-Flavor: Google" 0/ 1/ 2/
Similarly, if you wanted more information about the disk 0/
directory, you can
query the specific URL for that directory:
user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/disks/0/" -H "Metadata-Flavor: Google" device-name index mode type
Querying endpoints
If a metadata key is not a directory, then it is an endpoint that returns one or more values. For example, to query the mode of a specific disk, query the following endpoint:
user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/disks/0/mode" -H "Metadata-Flavor: Google" READ_WRITE
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 plaintext 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:
user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/tags" -H "Metadata-Flavor: Google" ["bread","butter","cheese","cream","lettuce"]
user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/tags?alt=text" -H "Metadata-Flavor: Google" bread butter cheese cream lettuce
Recursively querying metadata
If you want to return all contents under a directory, use the
recursive=true
query parameter with your request:
user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/disks/?recursive=true" -H "Metadata-Flavor: Google" [{"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" 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
Setting boolean values
For fields that accept boolean values, TRUE
or FALSE
, the following values
can also be used:
Status | Alternative values |
---|---|
TRUE | Y, Yes, 1 |
FALSE | N, No, 0 |
Boolean values are not case-sensitive. For example, you can use False
, false
,
or FALSE
to disable a feature.
Setting custom metadata
You can set custom metadata for an instance or project from the
Google Cloud Console
, the gcloud
command-line tool, or the Compute Engine API. Custom
metadata is useful for passing in arbitrary values to your project or instance,
and for setting startup and
shutdown scripts.
Custom metadata size limitations
Compute Engine enforces a combined total limit of 512 KB for all metadata
entries. Maximum size limits are also applied to each key
and value
as
follows:
- Each metadata
key
has a maximum limit of 128 bytes - Each metadata
value
has a maximum limit of 256 KB
In particular, SSH keys are stored as custom metadata under the ssh-keys
key. If your metadata content for this key exceeds the 256 KB limit,
you won't be able add more SSH keys. If you run into this limit, consider
removing unused keys
to free up metadata space for new keys.
Startup and shutdown script contents might also be stored as custom metadata and count toward these size limitations, if you provide the startup or shutdown script contents directly. To avoid this, store your startup or shutdown script as a file hosted at an external location, such as Cloud Storage, and provide the startup script URL when creating an instance. These files are downloaded onto the VM instance, rather than stored in the metadata server.
Setting instance metadata
Set custom metadata for an instance in the
Cloud Console
, the
gcloud
tool, or the
API. Instance metadata applies only
to a specific instance.
Setting metadata during instance creation
Console
- In the Cloud Console, go to the VM instances page.
- Click Create instance.
- On the Create a new instance page, fill in the properties for your instance.
- In the Metadata section, fill in as many key-value pairs for your custom metadata as you need.
- Click Create to create the instance.
gcloud
Using the gcloud
command-line tool, use the --metadata
flag to set custom metadata.
gcloud compute instances create example-instance \ --metadata foo=bar
API
In the API, provide custom metadata as part of the metadata property in your request:
POST https://compute.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/instances { "... } ] } ], "metadata": { "items": [ { "key": "foo", "value": "bar" } ] }, .. }
Updating metadata on a running instance
Console
In the Google Cloud Console, go to the VM instances page.
Click the instance for which you want to update metadata.
Click the Edit button at the top of the page.
Under Custom metadata, click Add item or edit the existing metadata entries.
Save your changes.
gcloud
Updating instance metadata with the gcloud
tool is an additive
action. Specify only the metadata keys that you want to add or change. If
a key that you provided already exists, the value for that key is updated
with the new value.
Using the gcloud
command-line tool, use the
instances add-metadata
command:
gcloud compute instances add-metadata instance-name \ --metadata bread=mayo,cheese=cheddar,lettuce=romaine
If you want to change the lettuce=romaine
entry to lettuce=green
, use:
gcloud compute instances add-metadata instance-name \ --metadata lettuce=green
If you want to remove the lettuce=romaine
entry, specify the existing key
and exclude the value.
gcloud compute instances remove-metadata instance-name \ --keys lettuce
API
In the API, make a request to the instances().setMetadata
method. Provide
a list of the new metadata values and the current fingerprint
value.
A fingerprint is a random string of characters generated by Compute Engine and is used to perform optimistic locking. Provide the matching fingerprint value to perform your request. The fingerprint changes after each request, and if you provide a mismatched fingerprint, your request is rejected. In this way, only one update can be made at a time, preventing collisions.
To get the current fingerprint of an instance and see any existing key-value
pairs for the instance. Send a instances().get
request:
GET https://compute.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/instances/example-instance { ... "name": "example-instance", "metadata": { "kind": "compute#metadata", "fingerprint": "zhma6O1w2l8=" "items": [ { "key": "foo", "value": "bar" } ] }, ... }
Next, make a request to the instances().setMetadata
method and set your
custom metadata key-value pairs. If the instance has existing key-value
pairs that you want to keep, you must include them in this request with the
new key-value pairs:
POST https://compute.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/instances/example-instance/setMetadata { "fingerprint": "zhma6O1w2l8=", "items": [ { "key": "foo", "value": "bar" }, { "key": "baz", "value": "bat" } ] }
To remove all metadata key-value pairs from an instance, specify an
instances().setMetadata
request and exclude the items
property. Note
that you must still include the current metadata fingerprint property for
an instances().setMetadata
request to succeed:
POST https://compute.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/instances/example-instance/setMetadata { "fingerprint": "5rC_DXxBUZw=" }
Setting project-wide custom metadata
Set project-wide metadata to apply the metadata to all instances in the project.
For example, if you define a project-wide metadata pair of baz=bat
,
that metadata pair is automatically applied to all instances in the project.
Console
In the Google Cloud Console, go to the Metadata page.
Click Edit.
Add or edit a metadata entry.
Save your changes.
gcloud
Using the gcloud
command-line tool, use the
project-info add-metadata
command. For example:
gcloud compute project-info add-metadata \ --metadata foo=bar,baz=bat
See the metadata using the describe
command:
gcloud compute project-info describe
For example, you might get a response similar to the following:
... commonInstanceMetadata: fingerprint: RfOFY_-eS64= items: - key: baz value: bat - key: foo value: bar - key: ssh-keys ...One metadata key-value pair is specified with an equals sign, for example,
key=value
. Multiple key-value pairs are separated with spaces.
You can optionally specify one or more files from which to read
metadata by using the --metadata-from-file
flag. You can remove
metadata values with the
project-info remove-metadata
command.
API
In the API, make a request to the projects().setCommonInstanceMetadata
method, providing all of the new metadata values.
To perform optimistic locking, you can optionally provide a fingerprint. A fingerprint is a random string of characters generated by Compute Engine. The fingerprint changes after each request, and if you provide a mismatched fingerprint, your request is rejected.
If you do not provide a fingerprint, no check for consistency is performed,
and the projects().setCommonInstanceMetadata
request succeeds. This
behaviour is different from instances().setMetadata
, where a fingerprint
is always required.
To get the current fingerprint of an instance, perform a project().get
request and copy the fingerprint value:
GET https://compute.googleapis.com/compute/v1/projects/myproject { "name": "myproject", "commonInstanceMetadata": { "kind": "compute#metadata", "fingerprint": "FikclA7UBC0=", ... }
Next, make a request to the projects().setCommonInstanceMetadata
method
and set your custom metadata key-value pairs:
POST https://compute.googleapis.com/compute/v1/projects/myproject/setCommonInstanceMetadata { "fingerprint": "FikclA7UBC0=", "items": [ { "key": "foo", "value": "bar" } ] }
Querying custom metadata
Query custom instance or project metadata through the Cloud Console,
the gcloud
command-line tool, or the API.
Console
To see project-wide custom metadata, go to the the Metadata page.
To see an instance's custom metadata:
- Go to the VM instances page.
- Click the instance for which you want to view metadata.
- Under Custom metadata, view the instance's custom metadata.
gcloud
Query project metadata:
gcloud compute project-info describe \ --flatten="commonInstanceMetadata[]"
Query instance metadata:
gcloud compute instances describe example-instance \ --flatten="metadata[]"
Use the --flatten
flag to
scope the output to a relevant metadata key. For example, the following
instance has a custom metadata key-value pair of foo:bar
.
$ gcloud compute instances describe example-instance ... metadata: fingerprint: Cad2L9eKNR0= items: - key: foo value: bar kind: compute#metadata ...
To query the value of key foo
, run:
gcloud compute instances describe example-instance \
--flatten="metadata[foo]"
---
bar
API
To query for a project's metadata, perform an empty request to the
projects().get
method:
GET https://compute.googleapis.com/compute/v1/projects/myproject
To query for an instance's metadata, perform an empty request to the
instance().get
method:
GET https://compute.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/instances/example-instance
Setting and querying guest attributes
Guest attributes are a specific type of custom metadata that your applications can write to while running on your instance. Any application or user on your instance can both read and write data to these guest attribute metadata values.
When to use guest attributes
Use guest attributes only for use cases that require small amounts of data that don't change frequently. The best use cases for guest attributes have the following characteristics:
- The number of queries are limited to a maximum of 10 queries per minute per VM instance.
- Queries don't exceed a burst of 3 queries per second. If this maximum rate is exceeded, Compute Engine might arbitrarily remove guest attributes that are in the process of being written. This data removal is needed to ensure that other critical system data can be written to the server.
Guest attributes work well for situations where you must publish infrequent and low volume data. For example, guest attributes work well for the following use cases:
- Startup scripts that can signal successful initialization by setting a custom status value in guest attributes.
- Configuration management agents that can publish a guest OS name and version to guest attributes.
- Inventory management agents that can publish list of packages installed in the VM instance to guest attributes.
- Workload orchestration software that can signal completion of an operation in the guest to the software control plane by setting a custom status value in guest attributes.
Guest attributes aren't a replacement for event streaming, Pub/Sub, or other forms of data storage and configuration repositories.
For reads and writes from within an instance, the metadata server provides
automatic instance-level authentication and authorization. Each instance can
read or write only to its own metadata server. Other instances cannot access the
metadata server of another instance. Users and service accounts can read an
instance's guest attributes from outside the instance only if they have an
Identity and Access Management (IAM) role that provides the
compute.instances.getGuestAttributes
permission.
Enabling guest attributes on your instance
By default, guest attributes are disabled. To enable guest attributes, set the necessary metadata values on either your individual instances or in project-wide metadata:
Console
Set enable-guest-attributes
in instance metadata when you create an instance:
In the Google Cloud Console, go to the VM instances page.
Click Create instance.
On the Create a new instance page, fill in the desired properties for your instance.
In the Metadata section, add a metadata entry where the key is
enable-guest-attributes
and the value isTRUE
.Click Create to create the instance.
Set enable-guest-attributes
in project-wide metadata so that it applies to
all of the instances in your project:
In the Google Cloud Console, go to the Metadata page.
Click Edit.
Add a metadata entry where the key is
enable-guest-attributes
and the value isTRUE
. Alternatively, set the value toFALSE
to disable the feature.Click Save to apply the changes.
Set enable-guest-attributes
in metadata of an existing instance:
In the Google Cloud Console, go to the VM instances page.
Click the name of the instance on which you want to set the metadata value.
At the top of the instance details page, click Edit to edit the instance settings.
Under Custom metadata, add a metadata entry where the key is
enable-guest-attributes
and the value isTRUE
. Alternatively, set the value toFALSE
to exclude the instance from the feature.At the bottom of the instance details page, click Save to apply your changes to the instance.
gcloud
Set enable-guest-attributes
in instance metadata when you create an instance:
Use the
gcloud compute instances create
command in the gcloud
command-line tool and set
enable-guest-attributes=TRUE
to enable guest attributes. Replace
instance-name
with the name of your instance.
gcloud compute instances create instance-name \ --metadata enable-guest-attributes=TRUE
Set enable-guest-attributes
in project-wide metadata so that it
applies to all of the instances in your project:
Use the
project-info add-metadata
command in the gcloud
command-line tool and set
enable-guest-attributes=TRUE
to enable guest attributes:
gcloud compute project-info add-metadata \ --metadata enable-guest-attributes=TRUE
Alternatively, you can set enable-guest-attributes
to FALSE
to disable
guest attributes.
Set enable-guest-attributes
in metadata of an existing instance:
Use the
instances add-metadata
command in the gcloud
command-line tool and set
enable-guest-attributes=TRUE
to enable guest attributes. Replace
instance-name
with the name of your instance.
gcloud compute instances add-metadata instance-name \ --metadata enable-guest-attributes=TRUE
Alternatively, you can set enable-guest-attributes
to FALSE
to
exclude your instance from using guest attributes.
Setting guest attributes
Any process running in the virtual machine instance can write to the guest attributes values including scripts and applications that don't have sudo or administrator level privileges. Users or service accounts outside of the instance cannot write to guest attributes metadata values.
For example, you might use a curl
request
from within your instance to write a value to the guest-attributes
metadata
path:
curl -X PUT --data "value" http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/namespace/key -H "Metadata-Flavor: Google"
Replace the following:
namespace
: A logical grouping for yourkey
. Guest attributes must have a namespace.value
: The value that you want to write.key
: The metadata path withinguest-attributes
where the value is stored.
Use only letters, numerals, underscores (_
), and hyphens (-
) for the
namespace
and key
fields.
Getting guest attributes
Users or service accounts can read guest attributes if they have an
IAM role that provides the compute.instances.getGuestAttributes
permission. Alternatively, any user or application within the instance can read
the metadata values for that specific instance.
Any process running in the virtual machine can write to the guest attributes
value, which include scripts and applications that don't have sudo or
administrator level privileges. For example, you might use a curl
request
from within your instance to read a value from the guest-attributes
metadata
path:
curl http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/namespace/key -H "Metadata-Flavor: Google"
Replace the following:
namespace
: The namespace for theguest-attributes
key that you want to query.key
: The path withinguest-attributes
from which you want to read the metadata value.
Alternatively, you can return all of the guest attribute values in one request.
Replace namespace
with the namespace for the
guest-attributes
key that you want to query.
curl http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/namespace/ -H "Metadata-Flavor: Google"
gcloud
Use the gcloud
command-line tool to read guest attribute metadata
values from an instance. For example, you can retrieve all of the values
for the instance:
gcloud compute instances get-guest-attributes instance-name \ --zone zone
To retrieve all of the values under a specific namespace, include the
--query-path
flag and the namespace that you defined:
gcloud compute instances get-guest-attributes instance-name \ --query-path=namespace \ --zone zone
To retrieve all of the values under a specific namespace, include the
--query-path
flag, the namespace, and the key for the value that you
defined:
gcloud compute instances get-guest-attributes instance-name \ --query-path=namespace/key \ --zone zone
Replace the following:
instance-name
: The name of the instance from which you want to read the guest attribute metadata value.namespace
: The namespace for theguest-attributes
key that you want to query.key
: The path withinguest-attributes
metadata where the value is stored.zone
: The zone where the instance is located.
API
Use the
compute.instances.getguestattributes
API method:
GET https://compute.googleapis.com/compute/v1/projects/project-id/zones/zone/instances/instance-name/getGuestAttributes?queryPath=namespace/key
Replace the following:
project-id
: Your project ID.zone
: The zone where your instance is located.instance-name
: The name of the instance from which you want to read the guest attribute metadata value.namespace
: The namespace for theguest-attributes
key that you want to query.key
: The path withinguest-attributes
metadata where the value is stored.
To retrieve all of the keys for a namespace
, omit the key
:
GET https://compute.googleapis.com/compute/v1/projects/project-id/zones/zone/instances/instance-name/getGuestAttributes?queryPath=namespace
To retrieve all of the keys in each namespace on the instance, omit the
namespace
and queryPath
entirely:
GET https://compute.googleapis.com/compute/v1/projects/project-id/zones/zone/instances/instance-name/getGuestAttributes
Alternatively, if you have an OAuth token, you can use curl
:
curl -H "Authorization: Bearer oauth-token" https://compute.googleapis.com/compute/v1/projects/project-id/zones/zone/instances/instance-name/getGuestAttributes?queryPath=namespace/key
Replace the following:
oauth-token
: Your OAuth token.project-id
: Your project ID.zone
: The zone where your instance is located.instance-name
: The name of the instance from which you want to read the guest attribute metadata value.namespace
: The namespace for theguest-attributes
key that you want to query.key
: The path withinguest-attributes
metadata where the value is stored.
Deleting guest attributes
You can also delete guest attributes. For example, use curl
to delete a
specific key:
curl -X DELETE http://metadata.google.internal/computeMetadata/v1/instance/guest-attributes/namespace/key -H "Metadata-Flavor: Google"
Replace the following:
namespace
: The namespace for theguest-attributes
key that you want to delete.key
: The path withinguest-attributes
where the value is stored.
Disabling guest attributes on your organization or folder
If you don't want any of the instances in your organization or folder to enable guest attributes, you can override and disable the feature completely.
Set the constraints/compute.disableGuestAttributesAccess
constraint on your
organization or folder, replacing project-id
with the name of your
project:
gcloud resource-manager org-policies enable-enforce \ constraints/compute.disableGuestAttributesAccess \ --project project-id
Read Using constraints to learn more about how to set and manage constraints on your organizations.
Waiting for updates
Given that metadata values can change while your instance is running, the
metadata server can be notified of metadata changes by using the
wait-for-change feature. This feature lets you perform hanging HTTP GET
requests that only return when your specified metadata has changed. You can use
this feature on custom metadata or server-defined metadata, so if anything
changes about your instance 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.
To perform a wait-for-change request, query a metadata key and append the
?wait_for_change=true
query parameter:
user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/tags?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. 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" cheese lettuce
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:
user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/attributes/?recursive=true&wait_for_change=true" -H "Metadata-Flavor: Google" {"cheese":"lettuce","cookies":"cream"}
The wait-for-change feature also lets you match with your request and set timeouts.
Using 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.
To get the current ETag value for a metadata key, make a request to that key
and print the headers. In curl
, you can do this by using the -v
flag:
user@myinst:~$ curl -v "http://metadata.google.internal/computeMetadata/v1/instance/tags" -H "Metadata-Flavor: Google"
* 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 < cheese lettuce
You can then use that ETag value in your wait-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.
The following Python sample shows how to programmatically watch the metadata server for changes:
Setting 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=<timeout-in-seconds>
query
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. Here is an example of 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"
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.
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. |
Getting live migration notices
The metadata server provides information about an instance's
scheduling options and settings,
through the scheduling/
directory and the maintenance-event
attribute. You
can use these attributes to learn about a virtual machine instance's scheduling
options, and use this metadata to notify you when a maintenance event
is about to happen through the maintenance-event
attribute. By default,
all virtual machine instances are set to
live migrate so the metadata server
receives maintenance event notices before a VM instance is live migrated.
If you opted to have your VM instance stopped during maintenance, then
Compute Engine automatically stops and optionally restarts
your VM instance if the automaticRestart
attribute is set. To learn more
about maintenance events and instance behavior during the events, read about
scheduling options and settings.
You can learn when a maintenance event will happen by querying the
maintenance-event
attribute periodically. The value of this attribute
changes 60 seconds before a maintenance event starts, giving your application
code a way to trigger any tasks you want to perform prior to a maintenance event,
such as backing up data or updating logs. Compute Engine also offers a
sample Python script to demonstrate how to check
for maintenance event notices.
Compute Engine gives the 60-second warning only if:
You have set the instance's availability options to live migrate during a maintenance event.
You have queried the
maintenance-event
attribute at least once since the last maintenance event. If you have never queried themaintenance-event
attribute or have not queried the attribute since the last migration, Compute Engine assumes that the instance doesn't require advance warning of maintenance events. The maintenance event initiates immediately instead, skipping the 60-second warning. If you don't want to skip the 60-second warning, make sure your client code queries themaintenance-event
attribute at least once between migration events.
To query the maintenance-event
attribute:
user@myinst:~$ curl http://metadata.google.internal/computeMetadata/v1/instance/maintenance-event -H "Metadata-Flavor: Google" NONE
The initial and default value of the maintenance-event
attribute is NONE
.
For GPU instances, during a maintenance event the attribute changes from
NONE
toTERMINATE_ON_HOST_MAINTENANCE
. This attribute is updated 60 minutes before the stopping event starts.For non-GPU instances with a scheduling option of
migrate
, themaintenance-event
attribute changes as follows:- At the start of the migration event, the value changes from
NONE
toMIGRATE_ON_HOST_MAINTENANCE
. This attribute is updated 60 seconds before the stopping event starts. - Throughout the duration of the event and while your VM instance is being
live migrated, the value remains as
MIGRATE_ON_HOST_MAINTENANCE
. - After the maintenance event ends, the value returns to
NONE
.
- At the start of the migration event, the value changes from
You can use the maintenance-event
attribute with the
waiting for updates feature to notify your scripts and
applications when a maintenance event is about to start and end. This lets you
automate any actions that you might want to run before or after the event. The
following Python sample provides an example of how you might implement these two
features together.
Sample Python script for querying maintenance events
Checking the version of your server endpoint
Current version: v1
Compute Engine might offer more than one metadata version, but we recommend that you always use the newest metadata server version available. At any time, Compute Engine can add new entries to the metadata server and add new fields to responses. Check back periodically for changes.
To check the version of your metadata server endpoint, review the URI that you are using to make requests to the server.
Metadata endpoint version | URI |
---|---|
v0.1 (Deprecated) | http://metadata.google.internal/0.1/meta-data/… |
v1beta1 (Deprecated) | http://metadata.google.internal/computeMetadata/v1beta1/… |
v1 | http://metadata.google.internal/computeMetadata/v1/… |
Disabling legacy endpoints
You can disable these endpoints at the project or instance level.
To disable the v0.1 and v1beta1 metadata server endpoints, follow the
instructions for setting a custom metadata and set
disable-legacy-endpoints=TRUE
.
For example, to disable the metadata server endpoint, at the project level using
the gcloud
command-line tool, run the following command:
gcloud compute project-info add-metadata \ --metadata disable-legacy-endpoints=TRUE
Transitioning to the v1 metadata server endpoint
For information about transitioning from v0.1 or v1beta1 to the v1 endpoint, see Migrating to v1 metadata server endpoint.
What's next
- Learn more about running startup scripts or shutdown scripts in the metadata server.
- Learn more about live migration.