You are here
Automating EC2 instance setup with user-data scripts
I recently published ec2metadata which provides a simple CLI and Python interface to the metadata of an Amazon EC2 instance. In that post I mentioned that "one of the most useful pieces of data is user-data, which can be used to pass configuration information or even initialization scripts to the instance upon launch".
I received a couple of responses by email asking for more information, so here it is.
But first, let me just thank Eric Hammond (and RightScale) for the idea. Below is a Python implementation which leverages ec2metadata as the communication layer.
Support for user-data scripts (ec2metadata, 25ec2-userdata) is included in all the latest TurnKey AMI's. If you setup the mechanism as described it should work on your own AMIs too.
Usage
It's simple. If the user-data content starts with the two characters #! (shebang), it will be executed. If no user-data is specified, or does not start with #!, nothing happens.
Launching an instance with user-data
When launching an instance, specify the user-data-file to pass to the instance.
For example:
ec2-run-instances --key KEYPAIR --user-data-file USERDATA_FILE
ami-cbc12fa2
The above example uses the Amazon EC2 CLI tools, but it's possible to pass user-data using the AWS console as well. The AMI specified is that of TurnKey Core in the US-EAST-1 region, the complete AMI listing is available here.
Example user-data script
#!/bin/bash -ex
install()
{
apt-get update
DEBIAN_FRONTEND=noninteractive apt-get -y \
-o DPkg::Options::=--force-confdef \
-o DPkg::Options::=--force-confold \
install $@
}
# installs hello - a highly useful package
install hello
# tell the world what we've done!
echo 'Hello world - I just executed user-data!' > /root/helloworld
The code
The following script depends on ec2metadata, and is executed on firstboot by inithooks on TurnKey AMI's.
/usr/lib/inithooks/firstboot.d/25ec2-userdata
#!/usr/bin/python
# Copyright (c) 2010 Alon Swartz <alon@turnkeylinux.org> - all rights reserved
import os
import shutil
import tempfile
import executil
import ec2metadata
class TempFile(file):
def __init__(self, prefix='tmp', suffix=''):
fd, path = tempfile.mkstemp(suffix, prefix)
os.close(fd)
self.path = path
self.pid = os.getpid()
file.__init__(self, path, "w")
def __del__(self):
if self.pid == os.getpid():
os.remove(self.path)
def main():
userdata = ec2metadata.get('user-data')
if userdata and userdata.startswith("#!"):
fh = TempFile(prefix="ec2userdata")
fh.writelines(userdata)
fh.close()
os.chmod(fh.path, 0750)
executil.system(fh.path)
print "# executed ec2 user-data script"
if __name__ == "__main__":
main()
Comments
Trying to set host name via Java api call
Hi,
Am new to this cloud-init stuff !!!
Am not sure on how to set the host name while launching the ec2 instance.
I believe i need to set the script as input parameter in .withuserdata() method !!!
Correct me if i am wrong !!!
Thanks.
Regards,
Krithika
-ex after #!/bin/bash is complusory?
Hi is the ex after #!/bin/bash is mandatory? I have searched somany tutorials and every one has without -ex. Without -ex my user data is not executing. Now it started working. I am just curious what does this -ex do in the above code
No it's not compulsory
It's totally optional and TBH I'm not sure why your script has suddenly starting working...
Liraz did a blog post that explains what the "-ex" does. Have a look here.
User-data-file is not working on CLI
Hii I have created User-data-file on graphical,On new instance script is running .But When i try with CLI in linux after AWS machine creation i did not find it in running state. I have tried with this command ec2-run-instances ami-e8f1c1ba -t t1.micro -k keypair --user-data file://home/user/script.sh -n 1 Please suggest the solution
Pages
Add new comment