Storing and Retrieving Instance Metadata

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, 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.
Since 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, query the http://metadata.google.internal/computeMetadata/v1/ URL.
For more information, see querying metadata.

Current version: v1

Compute Engine might offer more than one metadata version at a single
time, but we recommend that you always use the newest metadata server
version available. At any time, Google Compute Engine can add new entries to the
metadata server and add new fields to responses. Check back periodically for
changes!

Permissions required for this task

compute.instances.setMetadata on the instance if setting
instance metadata

compute.projects.setCommonInstanceMetadata on the project if
setting project-wide metadata

compute.projects.get on the project if just getting
metadata

compute.instances.get on the instance if just getting
metadata

Project and instance metadata

Metadata can be assigned at both the project and instance level. Project level
metadata propagates to all virtual machine instances within the project, while
instance level metadata only impacts that instance.

Default metadata keys

Google Compute Engine defines a set of default metadata entries that provide
information about your instance or project. Default metadata is always defined
and set by the server. You cannot manually edit any of these metadata pairs.

The following is a list of default metadata available to a project. 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 keys, while
numeric-project-id is a metadata key that maps to a value.

Relative to http://metadata.google.internal/computeMetadata/v1/project/

The free-text description of an instance, assigned using the
--description flag, or set in the API.

disks/

A directory of disks attached to this instance.

hostname

The host name of the instance.

id

The ID of the instance. This is a unique, numerical ID that is generated
by Google Compute Engine. This is useful for identifying instances if you do
not want to use instance names.

machine-type

The fully-qualified machine type name of the instance's host machine.

name

The instance name.

network-interfaces/

A directory of network interfaces for the instance.

network-interfaces/<index>/forwarded-ips/

A directory of any external IPs that are currently pointing to this
virtual machine instance, for the network interface at
<index>. Specifically, provides a list of
external IPs served by forwarding
rules that direct packets to this instance.

A JSON Web Token that is unique to the instance. You must
include the `audience` parameter in your request for this instance
metadata value. For example, `?audience=http://www.example.com`. Read
Verifying
the Identity of Instances to learn how to request and verify
instance identity tokens.

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 allows
the metadata server to return the data you requested. If you do not provide this
header, the metadata server denies your request.

Note: Previously, the X-Google-Metadata-Request: True header was required in
requests. Both of these headers are still supported but it is recommended that
you use the Metadata-Flavor header rather than the
X-Google-Metadata-Request: True header.

X-Forwarded-For header

Any requests that contain the header X-Forwarded-For will
automatically be 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.

Is metadata information secure?

When you make a request to get information from the metadata server, your
request and the subsequent metadata response never leaves the physical host
running the virtual machine instance. Metadata information is also encrypted on
the way to the virtual machine host, so you can be sure that your metadata
information is always secure.

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:

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 returns 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:

Setting custom metadata

You can set custom metadata for an instance or project from the Google Cloud Platform 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 also useful for setting
startup and shutdown
scripts.

Custom metadata size limitations

Google Compute Engine enforces the following limits on the length of your custom
metadata values:

256 KB for each individual metadata entry

512 KB combined total for all metadata entries per instance

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 will not 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 towards 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 Google Cloud Storage, and provide the
startup script URL when creating an instance. These files will be downloaded
onto the VM instance, rather than stored in the metadata server.

Setting instance metadata

Set custom metadata for an instance in the GCP Console, the
gcloud tool, or the
API. Instance metadata applies only
to a specific instance.

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.

If you want to remove the lettuce=romaine entry, specify the existing key
and exclude the value.

gcloud compute instances remove-metadata INSTANCE --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 in order 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:

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:

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
this request to succeed:

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.

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 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 and a 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 in order 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, perform a project().get
request and copy the fingerprint value:

API

To query for a project's metadata, perform an empty request to the
projects().get method:

GET https://www.googleapis.com/compute/v1/projects/myproject

To query for an instance's metadata, perform an empty request to the
instance().get method:

GET https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/instances/example-instance

Waiting for updates

Given that metadata values can change while your instance is running, the
metadata server offers the ability to be notified of metadata changes using the
wait-for-change feature. This feature allows you to 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.

Note: You can only perform a wait-for-change request on a
metadata endpoint or recursively on the contents of a directory. It is not
possible to perform a wait-for-change request on a directory listing and the
metadata server fails your request if you try to do so.

It is also not possible to 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.

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:

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 is 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 will be 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 grab the current ETag value for a metadata key, make a request to that key
and print the headers. In CURL, you can do this with the -v flag:

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

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:

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.

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 will receive
maintenance event notices before a VM instance is live migrated. If you opted
to have your VM instance terminated during maintenance, then Compute Engine
will automatically terminate and optionally restart 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 will
change 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.

Note: For instances with GPUs, the attribute changes 60 minutes before the instances
are terminated to give you time to shutdown and restart again on another host.
Instances with GPUs are not live migrated and are instead terminated and
optionally restarted. To learn more, read
Handling host maintenance
on the GPUs documentation.

You have queried the maintenance-event attribute at least once since the
last maintenance event. If you have never queried the maintenance-event
attribute or have not queried the attribute since the last migration,
Compute Engine assumes that the instance does not 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 the maintenance-event
attribute at least once between migration events.

Note: You must query the maintenance-event attribute directly for
Compute Engine to determine that you are watching this attribute.
Querying a higher level metadata does not trigger the advance notice.

The initial and default value of the maintenance-event attribute is NONE.
Before a transparent maintenance event begins, the maintenance-event value:

Changes from NONE to MIGRATE_ON_HOST_MAINTENANCE.

Throughout the duration of event and while your VM is being live migrated,
the value remains as MIGRATE_ON_HOST_MAINTENANCE.

After the maintenance event ends, the value returns to NONE.

Caution: The maintenance-event attribute will be populated for
maintenance events only if you have set your instance's scheduling option to
migrate or if your instance has a GPU attached. Virtual machine instances
without GPUs that are set to terminate will experience a power button push
and won't be notified of maintenance events through this attribute.

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.

Note: During the maintenance event, the metadata server might briefly return a
503 Service Unavailable code. If your application receives a 503 error code,
you should retry your request.

Transitioning to v1

The v1 metadata server functions slightly differently that
the previous v1beta1 server. Here are some of the changes that need to be made
for the new metadata server:

Update metadata requests to include the Metadata-Flavor: Google
header

The new metadata server requires that all requests provide the
Metadata-Flavor: Google header, which indicates that the request was made
with the intention of retrieving metadata values, Update your requests to
include this new header. For example, a request to the disks/ attribute
now looks like the following: