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 |
|
|
Package name |
com.amazonaws.util |
software.amazon.awssdk.imds |
Instantiation approach |
Use static utility methods; no instantiation:
|
Use a static factory method:
Or use a builder approach:
|
Types of clients | Synchronous only utility methods: EC2MetadataUtils |
Synchronous: Asynchronous: |
1
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 |
---|---|
|
|
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
The following table compares how you retrieve metadata of an instance identity document in v1 and v2.
Use case | v1 | v2 |
---|---|---|
Retrieve the Region |
|
|
Retrieve the instance id |
|
|
Retrieve the instance type |
|
|
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(...) |
|
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
-
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
andendpointMode
are called on the client builder, the SDK uses the endpoint value from whichever method you use. -
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.
-
The SDK first checks for an endpoint value. If a value is found, it is used.
-
If the SDK still hasn't found a value, the SDK looks for endpoint mode settings.
-
-
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();