Intro
To help you manage your instances, images, and other Amazon EC2 resources, you can assign your own metadata to each resource in the form of tags. Amazon has added the wonderful feature of tagging EC2 instances with key-value pairs to make the management of large numbers of VMs a bit easier. Now you can also query EC2 tags from within the instance. We’ll look at EC2 instance metadata, and how to use it.
What is an EC2 Tag?

A tag is a label that you apply to an Amazon Web Services resource. Each tag has a key and an optional value, both of which are defined by you. Tags let you organize your AWS resources in a variety of ways, such as by purpose, owner, or environment. For example, you might create a set of tags for your Amazon EC2 instances in your account to assist you in monitoring the owner and stack level of each instance.
The diagram on the left depicts the process of tagging. You’ve given each of your instances two tags in this example, one with the key “Owner” and the other with the key “Stack”. Each tag has a value associated with it.
Filtering and Querying EC2 Instances via AWS CLI
You could access your instance tags from the console or by using the describe-tags API. For example, over AWS CLI, you could list your Amazon EC2 instances describe-instances by tags. Without filters, the response contains information for all of your resources. The following command lists the instance IDs for your only test stack instances.
aws ec2 describe-instances \ --filters Name=instance-state-name,Values=running \ --query "Reservations[*].Instances[*].InstanceId" \ --output text
Here you can filter instances with a specific tag key-value combination
aws ec2 describe-instances \ --filters "Name=Role,Values=BookingApp"
If you want to use different key-value combinations it is better to use a JSON file like this example
aws ec2 describe-instances \ --filters file://filters.json
Contents of the filters.json file might look like
[ { "Name": "instance-type", "Values": ["t2.micro", "t3.micro"] }, { "Name": "availability-zone", "Values": ["eu-central-1a"] }, { "Name": "environment", "Values": ["staging"] } ]
Instance Tags on EC2 Metadata Service
But if you need those tags in your EC2 instance you don’t need to query the DescribeInstance or DescribeTag API calls to collect tag information because you can now access tags from your instance metadata, which minimizes your API transactions per second and allows your tag retrievals to scale with the number of instances you control. Local processes operating on an instance can also see the instance’s tag information directly from the instance metadata.
How to query EC2 Tags from within the instance?
1. Enable tags on instance metadata
To start, use the console or CLI to enable tags on instance metadata during startup, and save this launch configuration in a launch template. On a running or stopped instance, you may also use the CLI to enable tags on instance metadata. When you enable tags on instance metadata at launch, the system publishes your instance tags to your instance metadata. If you have made changes to tags after the launch, they will eventually be reflected in the metadata of your instance.
Over Console:

or CLI:
aws ec2 run-instances
--image-id ami-xxxxxxx
--instance-type t2.micro
...
--metadata-options "InstanceMetadataTags=enabled,HttpEndpoint=enabled,HttpTokens=required,"
2. Prefer Instance Metadata Service Method
You can get metadata from a running EC2 instance by using one of the techniques below.
1. IMDSv1
This is the old style of getting metadata of an EC2 instance based on the request/response model.
curl http://169.254.169.254/latest/meta-data/
2. IMDSv2
The Instance Metadata Service is abbreviated as IMDS. The methods differ slightly, as one might anticipate; IMDSv1 employs a request/response mechanism, whereas IMDSv2 uses a session-oriented approach. IMDSv2 is the preferred technique, and AWS gently pushes you to use it. By default, the AWS SDK uses IMDSv2 calls, and you can enforce users to configure a new EC2 with IMDSv2 enabled using IAM condition keys in an IAM policy. Any older instances configured to use this service can use IMDSv1.
3. Retrieving Instance Metadata
Once your EC2 is up and running, connect to your instance via ssh or any other method you prefer. The terminal and the AWS CLI are unable to access instance metadata from a running instance. You can use only the link-local address 169.254.169.254 to view instance metadata. There are no additional charges from AWS for requests to the metadata via the URI.
Create your token
To begin, create your token with the curl tool on Linux or the PowerShell cmdlet Invoke-WebRequest on Windows. A token is necessary because IMDSv2 is a session-oriented request. The session token is good to specify the duration of the session. You can set anywhere between one second and six hours. You can use the same session token for the specified amount of time.
The token you produce will be valid for the entire six-hour period. The duration request header is in seconds.
TOKEN=`curl --request PUT "http://169.254.169.254/latest/api/token" --header "X-aws-ec2-metadata-token-ttl-seconds: 21600"`

You may then pass the token to the GET request after you’ve created it. All categories can be viewed by appending /latest/meta-data/ to the end of the URI (the —write-out option is used to allow a space after the returned value):
curl --write-out "\n" --request GET "http://169.254.169.254/latest/meta-data/ami-id" --header "X-aws-ec2-metadata-token: $TOKEN"
The instance AMI ID should be returned to the screen.
Query EC2 tags from within the instance by token
Let’s look at how to query EC2 tags from within the instance now that you’ve learned how to retrieve metadata. In the following examples, the sample instance has tags on instance metadata enabled and the instance tags Name=myapp
and Tier=frontend
Stack=test
.
TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` \ && curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/tags/instance

The following example gets the value of the Name
key that was obtained in the preceding example.
curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/tags/instance/Name

## GET THE TOKEN BEFORE RUNNING IMDSv2 Metadata QUERY TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`
Metadata Command Description | IMDSv2 command | IMDSv1 command |
Get the top-level metadata items | curl -H “X-aws-ec2-metadata-token: $TOKEN” -v http://169.254.169.254/latest/meta-data/ | curl http://169.254.169.254/latest/meta-data/ |
Get AMI id | curl -H “X-aws-ec2-metadata-token: $TOKEN” -v http://169.254.169.254/latest/meta-data/ami-id | curl http://169.254.169.254/latest/meta-data/ami-id |
Get the local hostname | curl -H “X-aws-ec2-metadata-token: $TOKEN” -v http://169.254.169.254/latest/meta-data/local-hostname | curl http://169.254.169.254/latest/meta-data/local-hostname |
Get the public hostname | curl -H “X-aws-ec2-metadata-token: $TOKEN” -v http://169.254.169.254/latest/meta-data/local-hostname | curl http://169.254.169.254/latest/meta-data/public-hostname |
Get the subnet id | curl -H “X-aws-ec2-metadata-token: $TOKEN” -v http://169.254.169.254/latest/meta-data/network/interfaces/macs/02:29:96:8f:6a:2d/subnet-id | curl http://169.254.169.254/latest/meta-data/network/interfaces/macs/02:29:96:8f:6a:2d/subnet-id |
Get the instance tags | curl -H “X-aws-ec2-metadata-token: $TOKEN” -v http://169.254.169.254/latest/meta-data/tags/instance | curl http://169.254.169.254/latest/meta-data/tags/instance/Name |
Get the instance tag Value | curl -H “X-aws-ec2-metadata-token: $TOKEN” -v http://169.254.169.254/latest/meta-data/tags/instance/Name | curl http://169.254.169.254/latest/meta-data/tags/instance/Name (ex: Name is a tag here) |
Conlusion
Obtaining information about our EC2 instance from the operating instance using EC2 metadata is a helpful and convenient method. We know we can reference metadata and send these details to the script if we need to develop a dynamic script that runs on multiple EC2 instances. The ability to send instance ids, instance tags,region, and other parameters to an AWS CLI command without having to hard code them provides a lot of flexibility. Furthermore, this information can be retrieved without the use of access keys. Further, it enhances security by eliminating the requirement to maintain access keys in plain text on disk. You can also set a timer for the amount of time it takes to display metadata.
We hope that this post gives you insights on IMDSv1 and IMDSv2 when retrieving EC2 instance metadata.
Thanks.