Changes in the EC2 metadata utility from version 1 to version 2 - Amazon SDK for Java 2.x
Services or capabilities described in Amazon Web Services documentation might vary by Region. To see the differences applicable to the China Regions, see Getting Started with Amazon Web Services in China (PDF).

Changes in the EC2 metadata utility from version 1 to version 2

This topic details the changes in the SDK for Java Amazon Elastic Compute Cloud (EC2) metadata utility from version 1 (v1) to version 2 (v2).

High-level changes

Change v1 v2

Maven dependencies

<dependencyManagement> <dependencies> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-java-sdk-bom</artifactId> <version>1.12.5871</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-java-sdk-core</artifactId> </dependency> </dependencies>
<dependencyManagement> <dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>bom</artifactId> <version>2.27.212</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>imds</artifactId> </dependency> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>apache-client3</artifactId> </dependency> </dependencies>
Package name com.amazonaws.util software.amazon.awssdk.imds
Instantiation approach

Use static utility methods; no instantiation:

String localHostName = EC2MetadataUtils.getLocalHostName();

Use a static factory method:

Ec2MetadataClient client = Ec2MetadataClient.create();

Or use a builder approach:

Ec2MetadataClient client = Ec2MetadataClient.builder() .endpointMode(EndpointMode.IPV6) .build();
Types of clients Synchronous only utility methods: EC2MetadataUtils

Synchronous: Ec2MetadataClient

Asynchronous: Ec2MetadataAsyncClient

1 Latest version. 2 Latest version.

3Notice the declaration of the apache-client module for v2. V2 of the EC2 metadata utility requires an implementation of the SdkHttpClient interface for the synchronous metadata client, or the SdkAsyncHttpClient interface for the asynchronous metadata client. The HTTP clients section shows the list of HTTP clients that you can use.

Requesting metadata

In v1, you use static methods that accept no parameters to request metadata for an EC2 resource. In contrast, you need to specify the path to the EC2 resource as a parameter in v2. The following table shows the different approaches.

v1 v2
String userMetaData = EC2MetadataUtils.getUserData();
Ec2MetadataClient client = Ec2MetadataClient.create(); Ec2MetadataResponse response = client.get("/latest/user-data"); String userMetaData = response.asString();

Refer to the instance metadata categories to find the path you need to supply to request a piece of metadata.

Note

When you use an instance metadata client in v2, you should aim to use the same client for all request to retrieve metadata.

Behavior changes

JSON data

On EC2, the locally running Instance Metadata Service (IMDS) returns some metadata as JSON formatted strings. One such example is the dynamic metadata of an instance identity document.

The v1 API contains separate methods for each piece of instance identity metadata, whereas the v2 API directly returns the JSON string. To work with the JSON string, you can use the Document API to parse the response and navigate the JSON structure.

The following table compares how you retrieve metadata of an instance identity document in v1 and v2.

Use case v1 v2
Retrieve the Region
InstanceInfo instanceInfo = EC2MetadataUtils.getInstanceInfo(); String region = instanceInfo.getRegion();
Ec2MetadataResponse response = client.get("/latest/dynamic/instance-identity/document"); Document instanceInfo = response.asDocument(); String region = instanceInfo.asMap().get("region").asString();
Retrieve the instance id
InstanceInfo instanceInfo = EC2MetadataUtils.getInstanceInfo(); String instanceId = instanceInfo.instanceId;
Ec2MetadataResponse response = client.get("/latest/dynamic/instance-identity/document"); Document instanceInfo = response.asDocument(); String instanceId = instanceInfo.asMap().get("instanceId").asString();
Retrieve the instance type
InstanceInfo instanceInfo = EC2MetadataUtils.getInstanceInfo(); String instanceType = instanceInfo.instanceType();
Ec2MetadataResponse response = client.get("/latest/dynamic/instance-identity/document"); Document instanceInfo = response.asDocument(); String instanceType = instanceInfo.asMap().get("instanceType").asString();

Endpoint resolution differences

The following table shows the locations that the SDK checks to resolve the endpoint to IMDS. The locations are listed in descending priority.

v1 v2
System property: com.amazonaws.sdk.ec2MetadataServiceEndpointOverride Client builder configuration method: endpoint(...)
Environment variable: Amazon_EC2_METADATA_SERVICE_ENDPOINT System property: aws.ec2MetadataServiceEndpoint
Default Value: http://169.254.169.254 Config file: ~.aws/config with the ec2_metadata_service_endpoint setting
Value associated with resolved endpoint-mode
Default value: http://169.254.169.254

Endpoint resolution in v2

When you explicitly set an endpoint by using the builder, that endpoint value takes priority over all other settings. When the following code executes, the aws.ec2MetadataServiceEndpoint system property and config file ec2_metadata_service_endpoint setting are ignored if they exist.

Ec2MetadataClient client = Ec2MetadataClient .builder() .endpoint(URI.create("endpoint.to.use")) .build();

Endpoint-mode

With v2, you can specify an endpoint-mode to configure the metadata client to use the default endpoint values for IPv4 or IPv6. Endpoint-mode is not available for v1. The default value used for IPv4 is http://169.254.169.254 and http://[fd00:ec2::254] for IPv6.

The following table shows the different ways that you can set the endpoint mode in order of descending priority.

Possible values
Client builder configuration method: endpointMode(...)
Ec2MetadataClient client = Ec2MetadataClient .builder() .endpointMode(EndpointMode.IPV4) .build();
EndpointMode.IPV4, EndpointMode.IPV6
System property aws.ec2MetadataServiceEndpointMode IPv4, IPv6 (case does not matter)
Config file: ~.aws/config ec2_metadata_service_endpoint setting IPv4, IPv6 (case does not matter)
Not specified in the previous ways IPv4 is used

How the SDK resolves endpoint or endpoint-mode in v2

  1. The SDK uses the value that you set in code on the client builder and ignores any external settings. Because the SDK throws an exception if both endpoint and endpointMode are called on the client builder, the SDK uses the endpoint value from whichever method you use.

  2. If you do not set a value in code, the SDK looks to external configuration—first for system properties and then for a setting in the config file.

    1. The SDK first checks for an endpoint value. If a value is found, it is used.

    2. If the SDK still hasn't found a value, the SDK looks for endpoint mode settings.

  3. Finally, if the SDK finds no external settings and you have not configured the metadata client in code, the SDK uses the IPv4 value of http://169.254.169.254.

IMDSv2

Amazon EC2 defines two approaches to access instance metadata:

  • Instance Metadata Service Version 1 (IMDSv1) – Request/response approach

  • Instance Metadata Service Version 2 (IMDSv2) – Session-oriented approach

The following table compares how the Java SDKs work with IMDS.

v1 v2
IMDSv2 is used by default Always uses IMDSv2
Attempts to fetch a session token for each request and falls back to IMDSv1 if it fails to fetch a session token Keeps a session token in an internal cache that is reused for multiple requests

The SDK for Java 2.x supports only IMDSv2 and does not fall back to IMDSv1.

Configuration differences

The following table lists the differing configuration options.

Configuration v1 v2
Retries Configuration not available Configurable through builder method retryPolicy(...)
HTTP Connection timeout configurable through the Amazon_METADATA_SERVICE_TIMEOUT environment variable. The default is 1 second. Configuration available by passing an HTTP client to the builder method httpClient(...). The default connection timeout for HTTP clients is 2 seconds.

Example v2 HTTP configuration

The following example shows how you can configure the metadata client. This example configures the connection timeout and uses the Apache HTTP client.

SdkHttpClient httpClient = ApacheHttpClient.builder() .connectionTimeout(Duration.ofSeconds(1)) .build(); Ec2MetadataClient imdsClient = Ec2MetadataClient.builder() .httpClient(httpClient) .build();