Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass environment variables when programmatically starting a new Amazon EC2 from image?

Tags:

I am using AWS Java API RunInstance() to start a new EC2 instance from my custom AMI image. How do I pass environment variables to the new EC2 INSTANCE such as database url, AWS credentials etc. ?

like image 642
user193116 Avatar asked Mar 30 '12 21:03

user193116


People also ask

How do I permanently set environment variables on Amazon Linux?

d . You want to create it with an extension of your shell name. For example, if it's bash , it will be called script.sh for example. You will need to start a new shell session to add the variable to your environment which you can do by logging out and back in.

How do I add an environment variable in AWS?

To set environment variablesSign in to the AWS Management Console and open the Amplify console . In the Amplify console, choose App Settings, and then choose Environment variables. In the Environment variables section, choose Manage variables. In the Manage variables section, under Variable, enter your key.

What are the 3 different methods that you connect to a EC2 instance?

AWS support many ways to let you connect to your servers(EC2), we will introduce three methods : SSH, Instance Connect, System Manager and deep dive in EC2 Instance Connect and System Manager – Session Manager.

Can you launch multiple instances from a single AMI Amazon machine images )?

You can launch multiple instances from a single AMI when you require multiple instances with the same configuration. You can use different AMIs to launch instances when you require instances with different configurations.


2 Answers

http://alestic.com/2009/06/ec2-user-data-scripts explains how to do this with user-data. for gotchas about using Java see AmazonEC2 launch with userdata.

note that I've seen mention that this doesn't work with Windows, only Unix.

[update] more data on setting environment variables here: https://forums.aws.amazon.com/message.jspa?messageID=139744

[after much testing] for me, echoing the environment variables into /etc/environment works best, like this:

 reservation = connection.run_instances(image_id = image_id,   key_name = keypair,   instance_type = 'm1.small',   security_groups = ['default'],   user_data = '''#!/bin/sh\necho export foozle=barzle >> /etc/environment\n''') 

then upon login:

ubuntu@ip-10-190-81-29:~$ echo $foozle barzle 
like image 152
jcomeau_ictx Avatar answered Sep 18 '22 06:09

jcomeau_ictx


DISCLAIMER: I am not a sys admin!

I use a secure S3 bucket meaning a bucket that only the instance you're launching has access to. You can setup an IAM role that looks like:

{   "Version": "2012-10-17",   "Statement": [     {       "Effect": "Allow",       "Action": [         "s3:Get*",         "s3:List*"       ],       "Resource": "arn:aws:s3:::some-secure-bucket/*"     }   ] } 

Then you can upload your .env file in that bucket (store it encrypted). Then to access it on your EC2 instance, you could use the AWS cli tools:

sudo apt-get install -y python-pip (for aws s3 CLI library) sudo pip install awscli aws s3 cp --region us-east-1 s3://some-secure-bucket/.some-dot-env-file output_file_path 

You can pull this file down when the code runs or optionally make it happen at boot by putting the aforementioned cp command in an init script located somewhere like /etc/init.d/download_credentials.sh

I think this is a really good option for downloading things that every instance using an AMI needs like credentials. However, if you want to specify per instance metadata, I just implemented using tags which I think works nice. To do this, alter the above IAM role with something more like:

{   "Version": "2012-10-17",   "Statement": [     {       "Effect": "Allow",       "Action": [         "s3:Get*",         "s3:List*"       ],       "Resource": "arn:aws:s3:::some-secure-bucket/*"     },     {       "Effect": "Allow",       "Action": [         "ec2:DescribeInstances",         "ec2:DescribeTags"       ],       "Resource": "*"     }   ] } 

Then install ec2-api-tools

sudo sed -i.dist 's,universe$,universe multiverse,' /etc/apt/sources.list sudo apt-get update sudo apt-get install -y ec2-api-tools 

And now you should be able to get per instance metadata through tags, such as the "Name" of your instance:

ec2-describe-tags --filter resource-id="$(ec2metadata --instance-id)" --filter "key=Name" | cut -f5 

Note: I suck at bash so I'm stripping the name in ruby but you could use tr to remove the newline if you're into it!

like image 20
Tony Avatar answered Sep 20 '22 06:09

Tony