tessl install tessl/golang-cloud-google-com--go--compute@1.53.0Go client library for Google Cloud Compute Engine API providing programmatic access to manage virtual machines, disks, networks, and other compute resources
The cloud.google.com/go/compute/metadata package provides a client library for accessing the GCE metadata service from within running instances. The metadata service provides information about the current instance, project, network configuration, and service accounts.
import "cloud.google.com/go/compute/metadata"// OnGCE reports whether the code is running on Google Compute Engine
func OnGCE() bool
// OnGCEWithContext reports whether the code is running on Google Compute Engine with context support
func OnGCEWithContext(ctx context.Context) boolExample:
import "cloud.google.com/go/compute/metadata"
if metadata.OnGCE() {
fmt.Println("Running on GCE")
// Use metadata service
} else {
fmt.Println("Not running on GCE")
// Use alternative configuration
}// ProjectID returns the project ID
func ProjectID() (string, error)
// ProjectIDWithContext returns the project ID with context support
func ProjectIDWithContext(ctx context.Context) (string, error)
// NumericProjectID returns the numeric project ID
func NumericProjectID() (string, error)
// NumericProjectIDWithContext returns the numeric project ID with context support
func NumericProjectIDWithContext(ctx context.Context) (string, error)Example:
import (
"context"
"cloud.google.com/go/compute/metadata"
)
ctx := context.Background()
projectID, err := metadata.ProjectIDWithContext(ctx)
if err != nil {
// handle error
}
fmt.Printf("Project ID: %s\n", projectID)
numericProjectID, err := metadata.NumericProjectIDWithContext(ctx)
if err != nil {
// handle error
}
fmt.Printf("Numeric Project ID: %s\n", numericProjectID)// ProjectAttributes returns the list of project-level custom metadata keys
func ProjectAttributes() ([]string, error)
// ProjectAttributesWithContext returns the list of project-level custom metadata keys with context support
func ProjectAttributesWithContext(ctx context.Context) ([]string, error)
// ProjectAttributeValue returns the value of a project-level custom metadata attribute
func ProjectAttributeValue(key string) (string, error)
// ProjectAttributeValueWithContext returns the value of a project-level custom metadata attribute with context support
func ProjectAttributeValueWithContext(ctx context.Context, key string) (string, error)Example:
ctx := context.Background()
// Get project-level custom metadata value
sshKeys, err := metadata.ProjectAttributeValueWithContext(ctx, "ssh-keys")
if err != nil {
// handle error (attribute may not exist)
}
if sshKeys != "" {
fmt.Printf("Project SSH keys: %s\n", sshKeys)
}
// List all project-level custom attributes
attrs, err := metadata.ProjectAttributesWithContext(ctx)
if err != nil {
// handle error
}
fmt.Printf("Project-level custom attributes: %v\n", attrs)// InstanceID returns the instance ID
func InstanceID() (string, error)
// InstanceIDWithContext returns the instance ID with context support
func InstanceIDWithContext(ctx context.Context) (string, error)
// InstanceName returns the instance name
func InstanceName() (string, error)
// InstanceNameWithContext returns the instance name with context support
func InstanceNameWithContext(ctx context.Context) (string, error)
// Hostname returns the instance hostname
func Hostname() (string, error)
// HostnameWithContext returns the instance hostname with context support
func HostnameWithContext(ctx context.Context) (string, error)
// Zone returns the zone name (e.g., "us-central1-a")
func Zone() (string, error)
// ZoneWithContext returns the zone name with context support
func ZoneWithContext(ctx context.Context) (string, error)Example:
ctx := context.Background()
instanceID, err := metadata.InstanceIDWithContext(ctx)
if err != nil {
// handle error
}
instanceName, err := metadata.InstanceNameWithContext(ctx)
if err != nil {
// handle error
}
zone, err := metadata.ZoneWithContext(ctx)
if err != nil {
// handle error
}
fmt.Printf("Instance: %s (ID: %s) in zone %s\n", instanceName, instanceID, zone)// InternalIP returns the instance's internal IP address
func InternalIP() (string, error)
// InternalIPWithContext returns the instance's internal IP with context support
func InternalIPWithContext(ctx context.Context) (string, error)
// ExternalIP returns the instance's external IP address
func ExternalIP() (string, error)
// ExternalIPWithContext returns the instance's external IP with context support
func ExternalIPWithContext(ctx context.Context) (string, error)Example:
ctx := context.Background()
internalIP, err := metadata.InternalIPWithContext(ctx)
if err != nil {
// handle error
}
fmt.Printf("Internal IP: %s\n", internalIP)
externalIP, err := metadata.ExternalIPWithContext(ctx)
if err != nil {
// handle error (instance may not have external IP)
}
if externalIP != "" {
fmt.Printf("External IP: %s\n", externalIP)
}// InstanceTags returns the instance's tags
func InstanceTags() ([]string, error)
// InstanceTagsWithContext returns the instance's tags with context support
func InstanceTagsWithContext(ctx context.Context) ([]string, error)
// InstanceAttributes returns the list of custom metadata keys
func InstanceAttributes() ([]string, error)
// InstanceAttributesWithContext returns the list of custom metadata keys with context support
func InstanceAttributesWithContext(ctx context.Context) ([]string, error)
// InstanceAttributeValue returns the value of a custom metadata attribute
func InstanceAttributeValue(key string) (string, error)
// InstanceAttributeValueWithContext returns the value of a custom metadata attribute with context support
func InstanceAttributeValueWithContext(ctx context.Context, key string) (string, error)Example:
ctx := context.Background()
// Get all tags
tags, err := metadata.InstanceTagsWithContext(ctx)
if err != nil {
// handle error
}
fmt.Printf("Tags: %v\n", tags)
// Get custom metadata value
startupScript, err := metadata.InstanceAttributeValueWithContext(ctx, "startup-script")
if err != nil {
// handle error (attribute may not exist)
}
if startupScript != "" {
fmt.Printf("Startup script: %s\n", startupScript)
}
// List all custom attributes
attrs, err := metadata.InstanceAttributesWithContext(ctx)
if err != nil {
// handle error
}
fmt.Printf("Custom attributes: %v\n", attrs)// Scopes returns the OAuth2 scopes for a service account
func Scopes(serviceAccount string) ([]string, error)
// ScopesWithContext returns the OAuth2 scopes for a service account with context support
func ScopesWithContext(ctx context.Context, serviceAccount string) ([]string, error)
// Email returns the email address for a service account
func Email(serviceAccount string) (string, error)
// EmailWithContext returns the email address for a service account with context support
func EmailWithContext(ctx context.Context, serviceAccount string) (string, error)Example:
ctx := context.Background()
// Use "default" for the default service account
email, err := metadata.EmailWithContext(ctx, "default")
if err != nil {
// handle error
}
fmt.Printf("Service account email: %s\n", email)
scopes, err := metadata.ScopesWithContext(ctx, "default")
if err != nil {
// handle error
}
fmt.Printf("Service account scopes: %v\n", scopes)// Get retrieves arbitrary metadata by path suffix
func Get(suffix string) (string, error)
// GetWithContext retrieves arbitrary metadata by path suffix with context support
func GetWithContext(ctx context.Context, suffix string) (string, error)Example:
ctx := context.Background()
// Get machine type
machineType, err := metadata.GetWithContext(ctx, "instance/machine-type")
if err != nil {
// handle error
}
fmt.Printf("Machine type: %s\n", machineType)
// Get CPU platform
cpuPlatform, err := metadata.GetWithContext(ctx, "instance/cpu-platform")
if err != nil {
// handle error
}
fmt.Printf("CPU platform: %s\n", cpuPlatform)
// Get network interface info
networkInterface, err := metadata.GetWithContext(ctx, "instance/network-interfaces/0/ip")
if err != nil {
// handle error
}
fmt.Printf("Network interface IP: %s\n", networkInterface)// Subscribe watches for changes to a metadata value and calls the provided function
func Subscribe(suffix string, fn func(v string, ok bool) error) error
// SubscribeWithContext watches for changes to a metadata value with context support
func SubscribeWithContext(ctx context.Context, suffix string, fn func(ctx context.Context, v string, ok bool) error) errorExample:
import (
"context"
"time"
)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
defer cancel()
// Watch for changes to custom metadata
err := metadata.SubscribeWithContext(ctx, "instance/attributes/config", func(ctx context.Context, value string, ok bool) error {
if ok {
fmt.Printf("Config updated: %s\n", value)
// React to configuration change
} else {
fmt.Println("Config attribute removed")
}
return nil
})
if err != nil {
// handle error
}The Client type allows creating a custom metadata client with a specific HTTP client.
// Client represents a metadata client with custom configuration
type Client struct {
// contains filtered or unexported fields
}
// NewClient creates a new metadata client with a custom HTTP client
func NewClient(c *http.Client) *Client
// NewWithOptions creates a new metadata client with custom options
func NewWithOptions(opts *Options) *ClientAll package-level functions are available as methods on the Client:
// Client methods (mirrors package functions)
func (c *Client) OnGCEWithContext(ctx context.Context) bool
func (c *Client) ProjectID() (string, error)
func (c *Client) ProjectIDWithContext(ctx context.Context) (string, error)
func (c *Client) NumericProjectID() (string, error)
func (c *Client) NumericProjectIDWithContext(ctx context.Context) (string, error)
func (c *Client) ProjectAttributes() ([]string, error)
func (c *Client) ProjectAttributesWithContext(ctx context.Context) ([]string, error)
func (c *Client) ProjectAttributeValue(key string) (string, error)
func (c *Client) ProjectAttributeValueWithContext(ctx context.Context, key string) (string, error)
func (c *Client) InstanceID() (string, error)
func (c *Client) InstanceIDWithContext(ctx context.Context) (string, error)
func (c *Client) InstanceName() (string, error)
func (c *Client) InstanceNameWithContext(ctx context.Context) (string, error)
func (c *Client) Hostname() (string, error)
func (c *Client) HostnameWithContext(ctx context.Context) (string, error)
func (c *Client) Zone() (string, error)
func (c *Client) ZoneWithContext(ctx context.Context) (string, error)
func (c *Client) InternalIP() (string, error)
func (c *Client) InternalIPWithContext(ctx context.Context) (string, error)
func (c *Client) ExternalIP() (string, error)
func (c *Client) ExternalIPWithContext(ctx context.Context) (string, error)
func (c *Client) InstanceTags() ([]string, error)
func (c *Client) InstanceTagsWithContext(ctx context.Context) ([]string, error)
func (c *Client) InstanceAttributes() ([]string, error)
func (c *Client) InstanceAttributesWithContext(ctx context.Context) ([]string, error)
func (c *Client) InstanceAttributeValue(key string) (string, error)
func (c *Client) InstanceAttributeValueWithContext(ctx context.Context, key string) (string, error)
func (c *Client) Scopes(serviceAccount string) ([]string, error)
func (c *Client) ScopesWithContext(ctx context.Context, serviceAccount string) ([]string, error)
func (c *Client) Email(serviceAccount string) (string, error)
func (c *Client) EmailWithContext(ctx context.Context, serviceAccount string) (string, error)
func (c *Client) Get(suffix string) (string, error)
func (c *Client) GetWithContext(ctx context.Context, suffix string) (string, error)
func (c *Client) Subscribe(suffix string, fn func(v string, ok bool) error) error
func (c *Client) SubscribeWithContext(ctx context.Context, suffix string, fn func(ctx context.Context, v string, ok bool) error) errorExample - Custom Client:
import (
"net/http"
"time"
)
// Create custom HTTP client with timeout
httpClient := &http.Client{
Timeout: 5 * time.Second,
}
// Create metadata client
metadataClient := metadata.NewClient(httpClient)
// Use client methods
projectID, err := metadataClient.ProjectID()
if err != nil {
// handle error
}
instanceName, err := metadataClient.InstanceName()
if err != nil {
// handle error
}// Options configures a metadata client
type Options struct {
// Retry is a custom retry function
Retry func(resp *http.Response) bool
// Timeout is the request timeout duration
Timeout time.Duration
}Example - Client with Options:
import "time"
opts := &metadata.Options{
Timeout: 10 * time.Second,
Retry: func(resp *http.Response) bool {
// Custom retry logic
return resp.StatusCode == 503 || resp.StatusCode == 504
},
}
client := metadata.NewWithOptions(opts)The metadata service provides access to various information via different paths:
project/project-id - Project IDproject/numeric-project-id - Numeric project IDproject/attributes/ - Project-level custom metadatainstance/id - Instance IDinstance/name - Instance nameinstance/hostname - Instance hostnameinstance/zone - Zone (full path)instance/machine-type - Machine type (full path)instance/cpu-platform - CPU platforminstance/tags - Instance tagsinstance/attributes/ - Instance-level custom metadatainstance/network-interfaces/0/ip - Primary internal IPinstance/network-interfaces/0/access-configs/0/external-ip - External IPinstance/network-interfaces/0/network - VPC networkinstance/network-interfaces/0/subnetwork - Subnetinstance/service-accounts/default/email - Service account emailinstance/service-accounts/default/scopes - OAuth2 scopesinstance/service-accounts/default/token - Access token// NotDefinedError is returned when a metadata key is not defined
type NotDefinedError string
func (suffix NotDefinedError) Error() string
// Error represents an HTTP error from the metadata service
type Error struct {
Code int // HTTP response status code
Message string // Server response message
}
func (e *Error) Error() stringMetadata functions return errors when:
Example:
externalIP, err := metadata.ExternalIP()
if err != nil {
// Check if it's a NotDefinedError
if _, ok := err.(metadata.NotDefinedError); ok {
fmt.Println("Instance has no external IP")
} else if metaErr, ok := err.(*metadata.Error); ok {
fmt.Printf("Metadata service error: %d - %s\n", metaErr.Code, metaErr.Message)
} else {
fmt.Printf("Error: %v\n", err)
}
}Always use the WithContext variants in production:
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
projectID, err := metadata.ProjectIDWithContext(ctx)Verify code is running on GCE before using metadata:
if !metadata.OnGCE() {
// Use alternative configuration
return
}
// Proceed with metadata queriesMetadata values rarely change, cache them:
var (
cachedProjectID string
cacheOnce sync.Once
)
func getProjectID() (string, error) {
var err error
cacheOnce.Do(func() {
cachedProjectID, err = metadata.ProjectID()
})
return cachedProjectID, err
}Not all instances have all attributes:
startupScript, err := metadata.InstanceAttributeValue("startup-script")
if err != nil {
// Attribute may not exist, use default
startupScript = ""
}package main
import (
"context"
"fmt"
"log"
"time"
"cloud.google.com/go/compute/metadata"
)
func main() {
// Check if running on GCE
if !metadata.OnGCE() {
log.Fatal("Not running on Google Compute Engine")
}
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
// Get project information
projectID, err := metadata.ProjectIDWithContext(ctx)
if err != nil {
log.Fatalf("Failed to get project ID: %v", err)
}
// Get instance information
instanceName, err := metadata.InstanceNameWithContext(ctx)
if err != nil {
log.Fatalf("Failed to get instance name: %v", err)
}
zone, err := metadata.ZoneWithContext(ctx)
if err != nil {
log.Fatalf("Failed to get zone: %v", err)
}
// Get network information
internalIP, err := metadata.InternalIPWithContext(ctx)
if err != nil {
log.Fatalf("Failed to get internal IP: %v", err)
}
// External IP might not exist
externalIP, err := metadata.ExternalIPWithContext(ctx)
if err != nil {
externalIP = "none"
}
// Get service account
email, err := metadata.EmailWithContext(ctx, "default")
if err != nil {
log.Fatalf("Failed to get service account: %v", err)
}
// Print all information
fmt.Printf("Project: %s\n", projectID)
fmt.Printf("Instance: %s\n", instanceName)
fmt.Printf("Zone: %s\n", zone)
fmt.Printf("Internal IP: %s\n", internalIP)
fmt.Printf("External IP: %s\n", externalIP)
fmt.Printf("Service Account: %s\n", email)
}