54

I created a tag on the AWS console for one of my EC2 instances.

enter image description here

However, when I look on the server, no such environment variable is set.

The same thing works with elastic beanstalk. env shows the tags I created on the console.

$ env
 [...]
 DB_PORT=5432

How can I set environment variables in Amazon EC2?

PJ Bergeron
  • 2,788
  • 4
  • 25
  • 42
  • 2
    Tags are *not* environment variables. Tags are a way to organise your AWS resources. For instance you might apply the "project=abc" tag to an EC2 instance, and S3 bucket and a Lambda that are part of the same project. – Tom Saleeba Jan 07 '22 at 22:06

6 Answers6

34

You can retrieve this information from the meta data and then run your own set environment commands.

You can get the instance-id from the meta data (see here for details: http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html#instancedata-data-retrieval)

curl http://169.254.169.254/latest/meta-data/instance-id

Then you can call the describe-tags using the pre-installed AWS CLI (or install it on your AMI)

aws ec2 describe-tags --filters "Name=resource-id,Values=i-5f4e3d2a" "Name=Value,Values=DB_PORT"

Then you can use OS set environment variable command

export DB_PORT=/what/you/got/from/the/previous/call

You can run all that in your user-data script. See here for details: http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-data.html

Guy
  • 12,388
  • 3
  • 45
  • 67
  • 7
    I recommend using an IAM role for your instance - this will allow you to do the API call without specifying the credentials. This answer Guy gave is exactly what we use in production. – Shimon Tolts Feb 21 '15 at 14:15
  • 1
    Thanks for your answers. I created an IAM role allowing `ec2:DescribeTags` but when I execute `aws ec2 describe-tags` I get `A client error (UnauthorizedOperation) occurred when calling the DescribeTags operation: You are not authorized to perform this operation`. What am I missing? – PJ Bergeron Feb 21 '15 at 15:40
  • Ok, I had to do `rm -rf .aws` and `aws configure` (without entering any API key) in order to have aws reading the new credentials from the instance metadata. – PJ Bergeron Feb 21 '15 at 16:04
  • You need to create a role for the ec2 instance to allow it to do the calls: http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html – Guy Feb 22 '15 at 10:58
  • it appears that they limit the number of tags to be 10. `The maximum number of Tags for a resource has been reached. ` Wondering if there is any workaround on that? – Shih-Min Lee May 24 '16 at 06:35
  • 1
    @Shih-MinLee use only one tag for your data, and encode its contents in json or similar. – Mahmoud Al-Qudsi Jan 28 '18 at 20:32
10

Lately, it seems AWS Parameter Store is a better solution.

Now there is even a secrets manager which auto manages sensitive configurations as database keys and such..

See this script using SSM Parameter Store based of the previous solutions by Guy and PJ Bergeron.

https://github.com/lezavala/ec2-ssm-env

dlz21
  • 121
  • 1
  • 3
  • 1
    I see that the script is a bash script. I assume I put the call to it (`sh import-params.sh -p /NAMESPACE/ENV/ -r us-west-1`) in the USER DATA section of the EC2 instance, but where should I store the script so it is accessible when the instance is starting? – chris Frisina Sep 10 '18 at 04:56
  • 1
    @chrisFrisina I believe in Linux it is a common practice to store scripts in the /usr/local/bin directory. You can run the command on boot via cron `@reboot` or /etc/rc.local My preference is to trigger it via [AWS Run Command](https://docs.aws.amazon.com/systems-manager/latest/userguide/execute-remote-commands.html) as I can target/update multiple instances. – dlz21 Sep 11 '18 at 15:50
9

I used a combination of the following tools:

  • Install jq library (sudo apt-get install -y jq)
  • Install the EC2 Instance Metadata Query Tool

Here's the gist of the code below in case I update it in the future: https://gist.github.com/marcellodesales/a890b8ca240403187269

######
# 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
#### 
# 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"
Marcello DeSales
  • 21,361
  • 14
  • 77
  • 80
6

If you are using linux or mac os for your ec2 instance then,

Go to your root directory and write command:

vim .bash_profile

You can see your bash_profile file and now press 'i' for inserting a lines, then add

export DB_PORT="5432"

After adding this line you need to save file, so press 'Esc' button then press ':' and after colon write 'w' it will save the file without exiting.

For exit, again press ':' after that write 'quit' and now you are exit from the file. To check that your environment variable is set or not write below commands:

python
>>>import os
>>>os.environ.get('DB_PORT')
>>>5432 
Apurv
  • 71
  • 1
  • 2
4

Following the instructions given by Guy, I wrote a small shell script. This script uses AWS CLI and jq. It lets you import your AWS instance and AMI tags as shell environment variables.

I hope it can help a few people.

https://github.com/12moons/ec2-tags-env

PJ Bergeron
  • 2,788
  • 4
  • 25
  • 42
-1

If you are using linux or mac os for your ec2 instance then, go to your root directory and run the following command:

vim .bash_profile

You will see your bash_profile file open in the text editor 'vim'. Next press 'i' to enter 'insert' mode (or 'o' to enter insert mode on a new line), then append the following:

export DB_PORT="5432"

After adding this line, you need to save the file. So press the 'Esc' key to exit insert mode, then press ':' to initiate a new command, and after colon write 'w' and then press enter to save the file. It will save the file without exiting. To exit, again press ':' after that write 'quit' and the file will close. Alternatively, you can enter 'x' instead of 'w' to save and close the file all at once.

refer here for a vim cheat sheet.

After that run the command, "source ~/.bash_profile" in your shell. To check that your environment variable is set, enter the below commands in your shell to check via python:

python
>>>import os
>>>os.environ.get('DB_PORT')
>>>5432 

or the following in your shell to check natively:

echo DB_PORT
Mike
  • 537
  • 2
  • 6
  • 20