Running Commands on Your Linux Instance at Launch
When you launch an instance in Amazon EC2, you have the option of passing user data to the
instance that can be used to perform common automated configuration tasks and even run
scripts after the instance starts. You can pass two types of user data to Amazon EC2: shell
scripts and cloud-init directives. You can also pass this data into
the launch wizard as plain text, as a file (this is useful for launching instances via
the command line tools), or as base64-encoded text (for API calls).
If you are interested in more complex automation scenarios, consider using AWS CloudFormation and AWS OpsWorks. For more information, see the AWS CloudFormation User Guide and the AWS OpsWorks User Guide.
For information about running commands on your Windows instance at launch, see Executing User Data and Managing Windows Instance Configuration in the Amazon EC2 User Guide for Windows Instances.
In the following examples, the commands from the Installing a LAMP Web Server tutorial are converted to a shell script and a
set of cloud-init directives that executes when the instance
launches. In each example, the following tasks are executed by the user data:
The distribution software packages are updated.
The necessary web server,
php, andmysqlpackages are installed.The
httpdservice is started and turned on via chkconfig.The
wwwgroup is added, and theec2-useris added to that group.The appropriate ownership and file permissions are set for the web directory and the files contained within it.
A simple web page is created to test the web server and
phpengine.
Note
By default, user data and cloud-init directives only run during the first
boot cycle when you launch an instance. However, AWS Marketplace vendors and owners of
third-party AMIs may have made their own customizations for how and when scripts
run.
Contents
Prerequisites
The following examples assume that your instance has a public DNS name that is
reachable from the Internet. For more information, see Step 1: Launch an Instance.
You must also configure your security group to allow SSH (port
22), HTTP (port 80), and HTTPS (port 443)
connections. For more information about these prerequisites, see Setting Up with Amazon EC2.
Also, these instructions are intended for use with Amazon Linux, and the commands and
directives may not work for other Linux distributions. For more information about
other distributions, such as their support for cloud-init, see
their specific documentation.
User Data and Shell Scripts
If you are familiar with shell scripting, this is the easiest and most complete
way to send instructions to an instance at launch, and the
cloud-init output log file
(/var/log/cloud-init-output.log) captures console output so
it is easy to debug your scripts following a launch if the instance does not behave
the way you intended.
Important
User data scripts and cloud-init directives only run during
the first boot cycle when an instance is launched.
User data shell scripts must start with the #! characters and
the path to the interpreter you want to read the script (commonly
/bin/bash). For a great introduction on shell scripting, see
the BASH
Programming HOW-TO at the Linux Documentation Project (tldp.org).
Scripts entered as user data are executed as the root user, so
do not use the sudo command in the script. Remember that any
files you create will be owned by root; if you need
non-root users to have file access, you should modify the
permissions accordingly in the script. Also, because the script is not run
interactively, you cannot include commands that require user feedback (such as
yum update without the -y flag).
Adding these tasks at boot time adds to the amount of time it takes to boot the instance. You should allow a few minutes of extra time for the tasks to complete before you test that the user script has finished successfully.
To pass a shell script to an instance with user data
Follow the procedure for launching an instance at Launching Your Instance from an AMI, but when you get to Step 6, paste the user data script text into the User data field and then complete the launch procedure. For the example below, the script creates and configures our web server.
#!/bin/bash yum update -y yum install -y httpd24 php56 mysql55-server php56-mysqlnd service httpd start chkconfig httpd on groupadd www usermod -a -G www ec2-user chown -R root:www /var/www chmod 2775 /var/www find /var/www -type d -exec chmod 2775 {} + find /var/www -type f -exec chmod 0664 {} + echo "<?php phpinfo(); ?>" > /var/www/html/phpinfo.phpAllow enough time for the instance to launch and execute the commands in your script, and then check to see that your script has completed the tasks that you intended. For our example, in a web browser, enter the URL of the PHP test file the script created. This URL is the public DNS address of your instance followed by a forward slash and the file name.
http://my.public.dns.amazonaws.com/phpinfo.phpYou should see the PHP information page.
Tip
If you are unable to see the PHP information page, check that the security group you are using contains a rule to allow
HTTP(port 80) traffic. For information about adding anHTTPrule to your security group, see Adding Rules to a Security Group.(Optional) If your script did not accomplish the tasks you were expecting it to, or if you just want to verify that your script completed without errors, examine the
cloud-initoutput log file at/var/log/cloud-init-output.logand look for error messages in the output.For additional debugging information, you can create a Mime multipart archive that includes a
cloud-initdata section with the following directive:output : { all : '| tee -a /var/log/cloud-init-output.log' }This directive sends command output from your script to
/var/log/cloud-init-output.log. For more information oncloud-initdata formats and creating Mime multi part archive, seecloud-initFormats.
User Data and cloud-init Directives
The cloud-init package configures specific aspects of a new
Amazon Linux instance when it is launched; most notably, it configures the
.ssh/authorized_keys file for the
ec2-user so you can log in with your own private key.
The cloud-init user directives can be passed to an instance at
launch the same way that a script is passed, although the syntax is different. For
more information about cloud-init, go to http://cloudinit.readthedocs.org/en/latest/index.html.
Important
User data scripts and cloud-init directives only run during
the first boot cycle when an instance is launched.
The Amazon Linux version of cloud-init does not support all of the
directives that are available in the base package, and some of the directives have
been renamed (such as repo_update instead of
apt-upgrade).
Adding these tasks at boot time adds to the amount of time it takes to boot an instance. You should allow a few minutes of extra time for the tasks to complete before you test that your user data directives have completed.
To pass cloud-init directives to an instance with user
data
Follow the procedure for launching an instance at Launching Your Instance from an AMI, but when you get to Step 6, paste your
cloud-initdirective text into the User data field and then complete the launch procedure. For the example below, the directives create and configure a web server.#cloud-config repo_update: true repo_upgrade: all packages: - httpd24 - php56 - mysql55 - server - php56-mysqlnd runcmd: - service httpd start - chkconfig httpd on - groupadd www - [ sh, -c, "usermod -a -G www ec2-user" ] - [ sh, -c, "chown -R root:www /var/www" ] - chmod 2775 /var/www - [ find, /var/www, -type, d, -exec, chmod, 2775, {}, + ] - [ find, /var/www, -type, f, -exec, chmod, 0664, {}, + ] - [ sh, -c, 'echo "<?php phpinfo(); ?>" > /var/www/html/phpinfo.php' ]Allow enough time for the instance to launch and execute the directives in your user data, and then check to see that your directives have completed the tasks you intended. For our example, in a web browser, enter the URL of the PHP test file the directives created. This URL is the public DNS address of your instance followed by a forward slash and the file name.
http://my.public.dns.amazonaws.com/phpinfo.phpYou should see the PHP information page.
Tip
If you are unable to see the PHP information page, check that the security group you are using contains a rule to allow
HTTP(port 80) traffic. For information about adding anHTTPrule to your security group, see Adding Rules to a Security Group.(Optional) If your directives did not accomplish the tasks you were expecting them to, or if you just want to verify that your directives completed without errors, examine the
cloud-initoutput log file at/var/log/cloud-init-output.logand look for error messages in the output. For additional debugging information, you can add the following line to your directives:output : { all : '| tee -a /var/log/cloud-init-output.log' }This directive sends runcmd output to
/var/log/cloud-init-output.log.
API and CLI Overview
You can pass user data to your instance during launch using one of the following commands. For more information about these command line interfaces, see Accessing Amazon EC2.
AWS CLI: Use the
--user-dataparameter with the run-instances command.AWS Tools for Windows PowerShell: Use the
-UserDataparameter with the New-EC2Instance command.Amazon EC2 Query API: Use the
UserDataparameter with the RunInstances command.

