metadata

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 11, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package metadata reads the Lambda Metadata Endpoint: what Lambda knows about the execution environment a function runs in, such as the ID of its Availability Zone.

Usage

md, err := metadata.Get(ctx)
if err != nil {
	return err
}
logger.Info("serving", "az_id", md.AvailabilityZoneID) // "use1-az1"

An Availability Zone ID names the same physical zone in every account, so a function can prefer the replica of a cache or a database in its own zone. Converting it to a zone name (us-east-1a) takes ec2:DescribeAvailabilityZones.

The first call asks the endpoint, a local HTTP server Lambda runs in every execution environment (GET http://$AWS_LAMBDA_METADATA_API/2026-01-15/metadata/execution-environment, authenticated with the bearer token in AWS_LAMBDA_METADATA_TOKEN), with a one second timeout (WithTimeout). The answer cannot change during the environment's life, so it is cached until the process ends; calling Get in main has it ready before the first invocation. Fields AWS adds to the response later are in LambdaMetadata.Raw.

Outside Lambda

When AWS_LAMBDA_INITIALIZATION_TYPE is not set (tests, local runs) or POWERTOOLS_DEV is on, Get returns empty metadata and no error, without a request, so that code using it needs no setup to run anywhere. To test with real values, point AWS_LAMBDA_METADATA_API at an httptest.Server, set AWS_LAMBDA_INITIALIZATION_TYPE and AWS_LAMBDA_METADATA_TOKEN, and call ClearCache between cases.

Errors

A failure is a *LambdaMetadataError, with the HTTP status when the endpoint answered, wrapping ErrNoEndpoint, ErrNoToken, ErrStatus, ErrResponse or the transport's error. Failures are not cached.

Environment variables

AWS_LAMBDA_METADATA_API         the endpoint's address, set by Lambda
AWS_LAMBDA_METADATA_TOKEN       the endpoint's token, set by Lambda
AWS_LAMBDA_INITIALIZATION_TYPE  set by Lambda: Get runs in Lambda
POWERTOOLS_DEV                  on: Get returns empty metadata

Concurrency

Lambda Managed Instances start several invocations at once in one process. Concurrent first calls share one request to the endpoint; each returns when it completes, or when its own context ends.

Differences from Powertools Python

  • get_lambda_metadata is Get, which takes a context; its timeout is an option. clear_metadata_cache is ClearCache.
  • POWERTOOLS_DEV is read like every other Powertools truth value (true, 1, yes, on, ...), where Python's metadata utility accepts only "true" and "1".
  • The cache is safe for concurrent use, and concurrent first calls share one request.
  • A response that is not a JSON object (null, an array) is an ErrResponse, where Python fails with an unrelated TypeError.
  • Python's SnapStart cache invalidation has no Go counterpart: SnapStart does not run the provided runtimes Go functions use.

Index

Examples

Constants

View Source
const (
	// APIVersion is the version of the endpoint's API the package speaks.
	APIVersion = "2026-01-15"
	// Path is where the endpoint serves the execution environment's metadata.
	Path = "/metadata/execution-environment"
	// DefaultTimeout bounds a request to the endpoint, as in Powertools
	// Python.
	DefaultTimeout = time.Second
)

The Lambda Metadata Endpoint, as the Lambda developer guide documents it.

Variables

View Source
var (
	// ErrNoEndpoint reports that AWS_LAMBDA_METADATA_API is not set.
	ErrNoEndpoint = errors.New("environment variable " + env.LambdaMetadataAPI + " is not set")
	// ErrNoToken reports that AWS_LAMBDA_METADATA_TOKEN is not set.
	ErrNoToken = errors.New("environment variable " + env.LambdaMetadataToken + " is not set")
	// ErrStatus reports a response other than 200 OK; StatusCode says which.
	ErrStatus = errors.New("unexpected status")
	// ErrResponse reports a response body that is not a JSON object.
	ErrResponse = errors.New("the response is not a JSON object")
)

Sentinel errors, wrapped in a LambdaMetadataError.

Functions

func ClearCache

func ClearCache()

ClearCache forgets the cached metadata, so that the next Get asks the endpoint again. Tests use it between cases.

Types

type LambdaMetadata

type LambdaMetadata struct {
	// AvailabilityZoneID is the Availability Zone ID the environment runs in,
	// such as "use1-az1": the same physical zone in every account, unlike an
	// Availability Zone name.
	AvailabilityZoneID string `json:"AvailabilityZoneID"`
	// Raw is the whole response of the endpoint, for the fields AWS adds
	// after this package was written.
	Raw jsontext.Value `json:"-"`
}

LambdaMetadata describes the execution environment the function runs in.

func Get

func Get(ctx context.Context, opts ...Option) (LambdaMetadata, error)

Get returns the metadata of the execution environment. The first call asks the Lambda Metadata Endpoint; the answer is cached for the life of the environment, so later calls cost nothing. Call it in main to have it ready before the first invocation.

Outside Lambda (AWS_LAMBDA_INITIALIZATION_TYPE unset, in tests and local runs) and when POWERTOOLS_DEV is on, Get returns empty metadata and no error, without a request. A failure is a *LambdaMetadataError and is not cached: the next call asks again.

Concurrent calls share one request; each returns when it completes or when its own ctx ends. The options of the call that starts the request apply.

Example
package main

import (
	"context"
	"fmt"
	"net/http"
	"net/http/httptest"
	"os"
	"strings"

	"github.com/alessandrolattao/powertools-lambda-go/metadata"
)

func main() {
	// In Lambda, Get asks the Lambda Metadata Endpoint once and caches the
	// answer; here a local server plays the endpoint.
	endpoint := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
		_, _ = w.Write([]byte(`{"AvailabilityZoneID":"use1-az1"}`)) //nolint:errcheck // a test server
	}))
	defer endpoint.Close()
	lambdaEnv := map[string]string{
		"AWS_LAMBDA_INITIALIZATION_TYPE": "on-demand",
		"AWS_LAMBDA_METADATA_API":        strings.TrimPrefix(endpoint.URL, "http://"),
		"AWS_LAMBDA_METADATA_TOKEN":      "token",
	}
	for name, value := range lambdaEnv {
		_ = os.Setenv(name, value) //nolint:errcheck // valid names
	}
	defer func() {
		for name := range lambdaEnv {
			_ = os.Unsetenv(name) //nolint:errcheck // valid names
		}
		metadata.ClearCache()
	}()

	md, err := metadata.Get(context.Background())
	if err != nil {
		panic(err)
	}
	fmt.Println(md.AvailabilityZoneID)
}
Output:
use1-az1
Example (OutsideLambda)
package main

import (
	"context"
	"fmt"

	"github.com/alessandrolattao/powertools-lambda-go/metadata"
)

func main() {
	// Outside Lambda there is no endpoint: Get returns empty metadata, so
	// code that uses it runs in tests and on a laptop unchanged.
	md, err := metadata.Get(context.Background())
	fmt.Printf("%q %v\n", md.AvailabilityZoneID, err)
}
Output:
"" <nil>

type LambdaMetadataError

type LambdaMetadataError struct {
	// StatusCode is the HTTP status the endpoint answered with, or 0 when it
	// did not answer.
	StatusCode int
	// Err is the cause.
	Err error
}

LambdaMetadataError reports that the metadata could not be fetched.

func (*LambdaMetadataError) Error

func (e *LambdaMetadataError) Error() string

func (*LambdaMetadataError) Unwrap

func (e *LambdaMetadataError) Unwrap() error

type Option

type Option func(*config)

Option configures Get.

func WithHTTPClient

func WithHTTPClient(client *http.Client) Option

WithHTTPClient sends the request through client instead of a plain http.Client.

func WithTimeout

func WithTimeout(d time.Duration) Option

WithTimeout bounds the request to the endpoint, DefaultTimeout by default.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL