Menu
Amazon Elastic Compute Cloud
User Guide for Linux Instances

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 Microsoft 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, and mysql packages are installed.

  • The httpd service is started and turned on via chkconfig.

  • The www group is added, and the ec2-user is 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 php engine.

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

  1. 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.php
  2. Allow 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.php

    You 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 an HTTP rule to your security group, see Adding Rules to a Security Group.

  3. (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-init output log file at /var/log/cloud-init-output.log and look for error messages in the output.

    For additional debugging information, you can create a Mime multipart archive that includes a cloud-init data 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 on cloud-init data formats and creating Mime multi part archive, see cloud-init Formats.

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

  1. Follow the procedure for launching an instance at Launching Your Instance from an AMI, but when you get to Step 6, paste your cloud-init directive 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' ]
  2. 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.php

    You 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 an HTTP rule to your security group, see Adding Rules to a Security Group.

  3. (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-init output log file at /var/log/cloud-init-output.log and 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-data parameter with the run-instances command.

  • AWS Tools for Windows PowerShell: Use the -UserData parameter with the New-EC2Instance command.

  • Amazon EC2 CLI: Use the --user-data parameter with the ec2-run-instances command.

  • Amazon EC2 Query API: Use the UserData parameter with the RunInstances command.