Skip to content

Instantly share code, notes, and snippets.

@marcellodesales
Last active November 8, 2022 11:49
Show Gist options
  • Star 40 You must be signed in to star a gist
  • Fork 22 You must be signed in to fork a gist
  • Save marcellodesales/a890b8ca240403187269 to your computer and use it in GitHub Desktop.
Save marcellodesales/a890b8ca240403187269 to your computer and use it in GitHub Desktop.
Create Environment Variables in EC2 Hosts from EC2 Host Tags, just like Beanstalk or Heroku does!
######
# Author: Marcello de Sales (marcello.desales@gmail.com)
# Description: Create Create Environment Variables in EC2 Hosts from EC2 Host Tags
#
### Requirements:
# * Install jq library (sudo apt-get install -y jq)
# * Install the EC2 Instance Metadata Query Tool (http://aws.amazon.com/code/1825)
#
### Installation:
# * Add the Policy EC2:DescribeTags to a User
# * aws configure
# * Souce it to the user's ~/.profile that has permissions
####
# Add tags to an EC2 host or Image Profile
# Reboot and verify the result of $(env).
# Loads the Tags from the current instance
getInstanceTags () {
# http://aws.amazon.com/code/1825 EC2 Instance Metadata Query Tool
INSTANCE_ID=$(./ec2-metadata | grep instance-id | awk '{print $2}')
# Describe the tags of this instance
aws ec2 describe-tags --region sa-east-1 --filters "Name=resource-id,Values=$INSTANCE_ID"
}
# Convert the tags to environment variables.
# Based on https://github.com/berpj/ec2-tags-env/pull/1
tags_to_env () {
tags=$1
for key in $(echo $tags | /usr/bin/jq -r ".[][].Key"); do
value=$(echo $tags | /usr/bin/jq -r ".[][] | select(.Key==\"$key\") | .Value")
key=$(echo $key | /usr/bin/tr '-' '_' | /usr/bin/tr '[:lower:]' '[:upper:]')
echo "Exporting $key=$value"
export $key="$value"
done
}
# Execute the commands
instanceTags=$(getInstanceTags)
tags_to_env "$instanceTags"
@ScottEAdams
Copy link

very nice. added some specifics to my install script before running:

echo "export LC_ALL=en_US.UTF-8" >> ~/.bash_profile
echo "export LANG=en_US.UTF-8" >> ~/.bash_profile
source ~/.bash_profile
sudo apt-get --assume-yes awscli jq
wget http://s3.amazonaws.com/ec2metadata/ec2-metadata
chmod u+x ec2-metadata

@jordanboston
Copy link

This is helpful for sure!

@curtisgibby
Copy link

You can get the instance ID by using the -i flag on the ./ec2-metadata script, without having to grep:

INSTANCE_ID=$(./ec2-metadata -i | awk '{print $2}')

@PrimeTimeTran
Copy link

Hey, thanks for setting this up. How do I run this file...? =) I need an environment variable and have been googling around for a while and stumbled across this.
https://stackoverflow.com/questions/28643573/how-to-set-an-environment-variable-in-amazon-ec2
I noticed you said this might help me configure my environment variable for an ec2 instance so figured I'd give it a shot. (sorry I'm not really pro at linux/ubuntu)

@charlesthk
Copy link

charlesthk commented Oct 28, 2017

Another way (maybe simplier and without ec2-metadata) to get the instance-id is :
curl http://169.254.169.254/latest/meta-data/instance-id

Copy link

ghost commented Feb 21, 2018

I did this without any extra dependencies using just python and bash.

If you have a tag like Name=Prod Instance, then echo $TAG_Name prints Prod Instance

getInstanceTags () {
    INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
    EC2_AVAIL_ZONE=`curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone`
    EC2_REGION="`echo \"$EC2_AVAIL_ZONE\" | sed -e 's:\([0-9][0-9]*\)[a-z]*\$:\\1:'`"

    # Print tags as 'export TAG_Key=Value'
    aws ec2 describe-tags --region $EC2_REGION --filters "Name=resource-id,Values=$INSTANCE_ID" | \
      python -c "import sys,json; map(lambda t: sys.stdout.write('export TAG_%s=%s\n' % (t['Key'], t['Value'])), json.load(sys.stdin)['Tags'])"
}

# Export variables from tags
$(getInstanceTags)

@AstroTom
Copy link

AstroTom commented May 6, 2018

Thanks @joshcurago for your simpler script.

I would just add double quotes to your values in case the tag has whitespace TAG_%s=\"%\"s\n

Like this:

    # Print tags as 'export TAG_Key="Value"'
    aws ec2 describe-tags --region $EC2_REGION --filters "Name=resource-id,Values=$INSTANCE_ID" | \
      python -c "import sys,json; map(lambda t: sys.stdout.write('export TAG_%s=\"%s\"\n' % (t['Key'], t['Value'])), json.load(sys.stdin)['Tags'])"

@dominik1001
Copy link

Thank you for the script!

I am having the issue that the script works, but when I run a cron job (even if I include the script), the script still works (I can see the correct values), but the environment variables do not get set. Any ideas? Thank you!

@drumadrian
Copy link

this script works well, but has issues with AWS generated tags.

for example: aws:cloudformation:stack-id

The ":" caused a problem when it is in the string used as the export variable name

Here is the full Key=Value tag pair:

aws:cloudformation:stack-id=arn:aws:cloudformation:us-west-2:634580338419:stack/deployment-pipeline-myfeature/ce1580f0-b3ad-11e8-acae-0a3d4b08165a

@adamscarlat
Copy link

This script works when I run it directly from the EC2 instance. It doesn't work for me when I add it as a command to run in the instance's UserData during instance configuration.
Is it possible to run this script from UserData?

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