Skip to content

Instantly share code, notes, and snippets.

@codeinthehole
Created August 18, 2014 12:41
Show Gist options
  • Star 72 You must be signed in to star a gist
  • Fork 11 You must be signed in to fork a gist
  • Save codeinthehole/ab9a8dc30917c5705846 to your computer and use it in GitHub Desktop.
Save codeinthehole/ab9a8dc30917c5705846 to your computer and use it in GitHub Desktop.
Get the value of an EC2 instance's tag
#!/usr/bin/env bash
#
# Get the value of a tag for a running EC2 instance.
#
# This can be useful within bootstrapping scripts ("user-data").
#
# Note the EC3 instance needs to have an IAM role that lets it read tags. The policy
# JSON for this looks like:
#
# {
# "Version": "2012-10-17",
# "Statement": [
# {
# "Effect": "Allow",
# "Action": "ec2:DescribeTags",
# "Resource": "*"
# }
# ]
# }
# Define the tag you want to get the value for
KEY=bucket
# Install AWS CLI (you could just do 'apt-get install awscli' although you'll
# get an older version).
apt-get update
apt-get install -y python-pip
pip install -U pip
pip install awscli
# Grab instance ID and region as the 'describe-tags' action below requires them. Getting the region
# is a pain (see http://stackoverflow.com/questions/4249488/find-region-from-within-ec2-instance)
INSTANCE_ID=$(ec2metadata --instance-id)
REGION=$(curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | grep region | awk -F\" '{print $4}')
# Grab tag value
TAG_VALUE=$(aws ec2 describe-tags --filters "Name=resource-id,Values=$INSTANCE_ID" "Name=key,Values=$KEY" --region=$REGION --output=text | cut -f5)
@jhoblitt
Copy link

👍 I was afraid I was going to have to parse the region out of meta-data/placement/availability-zone before I discovered this example. Thanks!

@johndturn
Copy link

This is amazing. Really helped out a ton! Thanks!

@bcodesido
Copy link

Great!!.
Thanks!

@xuzhenglun
Copy link

Great!!!
Thanks!

@chadlnc
Copy link

chadlnc commented Nov 16, 2016

On the Amazon Linux AMI I had to change:

INSTANCE_ID=$(ec2-metadata --instance-id | cut -f2 -d " ")

Saved me tons of time, thanks.

@numero-trey
Copy link

This is fantastic. Thank you so much!!

@ctindel
Copy link

ctindel commented Nov 26, 2016

Any way to do this in a case insensitive way? Like if someone puts the tag name as "name" or "NAME" instead of "Name"

@breigle
Copy link

breigle commented Apr 5, 2017

Excellent! This helped! Used this as a base for getting the info I needed back for a script.

@aebaugh
Copy link

aebaugh commented Apr 25, 2017

Had a couple other suggestions, some require jq (installs using yum, sorry not sure the apt-get equivalent):
sudo yum -y install jq

Get instance ID:
INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)

Get region:
REGION=$(curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | jq -r .region)

Parse tag value with jq:
aws ec2 describe-tags --filters "Name=resource-id,Values=$INSTANCE_ID" "Name=key,Values=$KEY" --region=$REGION --output=json | jq -r .Tags[0].Value

@TaiSHiNet
Copy link

TaiSHiNet commented Sep 6, 2017

Why use jq or cut?
--query 'Tags[0].Value' with --output=text should do the trick

Also, if you're using it within CloudFormation, use ${AWS::Region} and, if you use cloud-init or cloud-config, $INSTANCE_ID should be available

@greg-plume
Copy link

greg-plume commented Oct 5, 2017

From a previous comment:

I was afraid I was going to have to parse the region out of meta-data/placement/availability-zone before I discovered this example

The example script uses bash, and parsing the region from meta-data/placement/availability-zone isn't hard with bash (or most other shells). It returns the full zone name, which is the region name plus the one-letter zone name. I.e., us-west-2a or ap-northeast-1b. So you just have to return the zone name with the last character removed to get the region:

ZONE=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone)
REGION=${ZONE%?}

@espoelstra
Copy link

If you know what Tag you are looking for you can query it directly like --query 'Tags[?Key==`Name`].Value' And yes those are backticks around the tag Key that you are looking for, in this came Name.

@kesor
Copy link

kesor commented Jul 10, 2019

Possibly restrict the policy even more, like so:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "ec2:DescribeTags",
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:ARN": "${ec2:SourceInstanceARN}"
                }
            }
        }
    ]
}

@tinproject
Copy link

@kesor No, you can not restrict that action in an IAM policy...
describetagspolicy

@kesor
Copy link

kesor commented Jan 9, 2020

@tinproject I did write that you "possibly" could, without testing. Looks like there is indeed no such thing as aws:ARN, but there IS aws:SourceArn that you could use (I didn't test it).
https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourcearn

@tinproject
Copy link

DescribeTags action does not allow any Resource limitation (https://docs.aws.amazon.com/IAM/latest/UserGuide/list_amazonec2.html#amazonec2-policy-keys ), the Policy Visual Editor image above also tells so.

Anyway, even if it supports resource limiting, a condition using aws:SourceArn and ${ec2:SourceInstanceARN} is always true in a petition from an Instance Role as both values will be the same, and as the documentation said you can not use ${ec2:SourceInstanceARN} on the Resource part of the policy, hence you're not limiting by resource.

Conclusion: don't lose time trying to make this work (as I already did)

@bonilha
Copy link

bonilha commented Apr 1, 2021

There's an error getting the region.
You can fix it with
INSTANCE_ID=$(ec2-metadata --instance-id | awk '{print $2}')

@dridi93
Copy link

dridi93 commented Jan 20, 2022

TOOOOOOOOP

like a charm !!!!

@badfun
Copy link

badfun commented Nov 17, 2022

If you know what Tag you are looking for you can query it directly like --query 'Tags[?Key==`Name`].Value' And yes those are backticks around the tag Key that you are looking for, in this came Name.

Finally found the working syntax. Thanks @espoelstra

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment