Amazon Web Services Tips

  


[an error occurred while processing this directive]

No Title

[an error occurred while processing this directive]

Reference: Cisco: Internetworking Basics

Contents

Introduction

Amazon Web Services (AWS) provides the ability to associate (map) a static IP address with a running EC2 instance through the use of an Elastic IP addresses. An Elastic IP address is a static IP address which you can allocate and assign to any one of your running EC2 instances either through the AWS Management Console or using the Amazon EC2 API Tools. By default, your account is limited to 5 Elastic IP addresses per region and only one Elastic IP address can be assigned to an instance. On a normal startup, every instance will come with a private IP address and a dynamic Internet routable public IP address. When an Elastic IP address is associated with an instance, it replaces the dynamic public IP address. Because an Elastic IP address is associated with your account and not permanently with a particular instance, you are able to quickly and efficiently mask instance or Availability Zone failures by associating the Elastic IP address to any surviving instance under your account. Associating an Elastic IP address to an instance is a manual process that can take several minutes from when you instruct Amazon to associate the IP address to fully propagating through their system of network devices.

With all of this flexibility and ease of use, there is one feature to be cognitive of. When an instance is stopped and then restarted, the Elastic IP no longer gets associated with the instance. When the instance is started again, the default action is to assign another dynamic IP address (and new hostname) to the public IP address from DHCP instead of the previously associated Elastic IP address.

In this guide, I present one approach that can be used to automatically associate an Elastic IP with an instance on startup using an EC2 startup script and user data. The example in this guide will be performed on an Amazon EBS-backed instance running CentOS 6. In addition to associating the Elastic IP address, I will also be setting the hostname.

 

A similar approach can be used that updates the DNS record of a dynamic DNS resolution service like DynDNS or ZoneEdit with the public IP address assigned to the EC2 instance by DHCP when the instance starts. This provides a persistent domain name that can be used to access the virtual server each time it is started. This method does not make use of the Elastic IP address service provided by Amazon.

Throughout this guide and in practice, keep in mind that an Elastic IP address is free of charge while it is associated with a running instance. However, if an Elastic IP address is allocated and is not associated with an instance, the cost is $0.01/hr at the time of this writing. The reason for this charge, as Amazon states, is because public (IPV4) internet addresses are a scarce resource and they want to encourage users to efficiently use Elastic IP addresses by imposing a small hourly fee if an Elastic IP address is allocated but not assigned to an instance. In theory, Amazon believes by imposing a small hourly fee that users will not hog unused public IP addresses that could be dynamically allocated to other users.

Requirements

Perform the following prerequisites on the target EC2 instance.

  1. Install the Amazon EC2 Tools on the target instance. The EC2 startup script (discussed later in this guide) will make use of the Amazon EC2 API Tools to associate the Elastic IP address with a target instance.

  2. The EC2 startup script used in this guide will need access to your X.509 Certificate. Make certain that your X.509 Certificate (private key file and certificate file) are copied to the appropriate directory on the target instance.

  3. If you have not already done so, allocate a new Elastic IP address for your account using either the AWS Management Console or the Amazon EC2 API Tools. Before allocating a new address, always check AWS for any Elastic IP addresses that may be allocated already. In this example, I am starting fresh with no previously allocated Elastic IP addresses.


    # ec2-describe-addresses # ec2-allocate-address ADDRESS 23.23.232.241 standard

Configure EC2 User Data

When you launch an instance, you can specify user data that will be passed in and queried by the instance to provide special configuration information for the instance during startup.

User data can be retrieved by a user or from a script from the EC2 user-data field on the metadata server (169.254.169.254) using curl.

 

curl is a popular command-line tool for interacting with HTTP services as well as many other protocols.

In this example, I will be providing an Elastic IP address and static hostname in the user-data field for an instance which will be retrieved by a startup script (/etc/init.d/ec2-elastic-ip) to replace the dynamically created public IP address and hostname for the instance when launched.

Note that the user-supplied data in the user-data field is treated as opaque data; meaning that requests for user data is returned as-is (content type application/x-octetstream). It will be the responsibility of our script to interpret the returned data correctly.

Initially, I thought it would make the most sense to use tags to pass in the Elastic IP address and hostname as metadata instead of user data given its key=value nature. At the time of this writing, however, I learned that instance metadata does not contain tag information through the metadata API. (See Metadata Categories for the list of metadata categories)

Once you have an Elastic IP address, the first step is to shutdown the target EC2 instance if it is running. To change the user-data field for an instance, the instance needs to be stopped.


# ec2-stop-instances i-0a33fc72 INSTANCE i-0a33fc72 running stopping

With the instance stopped, modify the user-data field for the instance. The user data will be available through instance metadata when the instance starts.


# ec2-modify-instance-attribute i-0a33fc72 --user-data "elastic-ip=23.23.232.241|hostname=ip-test.aws-idev.com" userData i-0a33fc72 elastic-ip=23.23.232.241|hostname=ip-test.aws-idev.com

After configuring user data for the target EC2 instance, start it back up.


# ec2-start-instances i-0a33fc72 INSTANCE i-0a33fc72 stopped pending

Once the EC2 instance is started, log in and do a quick check to verify the user data was passed in.


# curl -s http://169.254.169.254/latest/user-data elastic-ip=23.23.232.241|hostname=ip-test.aws-idev.com

Create EC2 Startup Script

On the target EC2 instance, create a startup script that will retrieve the Elastic IP address and hostname from the metadata server (169.254.169.254) using curl. The Elastic IP address and hostname will be available in the user-data field that was configured and passed in to the instance in the previous step.

In addition to changing the Elastic IP address, I will also be changing the hostname for the machine in the startup script. You can change the hostname on the instance using the Linux hostname command and in the case of an Amazon EBS-backed instance running RHEL/CentOS/Oracle Linux, making the change persistent by updating the /etc/sysconfig/network network configuration file.

Create the following startup script on the target EC2 instance and update the runlevel information for the new system service.


# vi /etc/init.d/ec2-elastic-ip #!/bin/bash # chkconfig: 2345 95 20 # processname: ec2-elastic-ip # description: Associate EC2 instance with Elastic IP and change hostname on boot # Source function library . /etc/rc.d/init.d/functions # Source networking configuration [ -r /etc/sysconfig/network ] && . /etc/sysconfig/network # Replace the following environment variables for your system export EC2_BASE=/opt/ec2 export EC2_HOME=$EC2_BASE/tools export EC2_PRIVATE_KEY=$EC2_BASE/certificates/ec2-pk.pem export EC2_CERT=$EC2_BASE/certificates/ec2-cert.pem export EC2_URL=https://ec2.amazonaws.com export PATH=$PATH:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:$EC2_HOME/bin export JAVA_HOME=/usr # Check that networking is configured if [ "${NETWORKING}" = "no" ]; then echo "Networking is not configured." exit 1 fi # Verify Amazon EC2 API Tools test -d "$EC2_HOME/bin" || { echo "ec2-api-tools not installed."; if [ "$1" = "stop" ]; then exit 0; else exit 5; fi; } # Verify Java Runtime Environment (JRE) test -x "$JAVA_HOME/bin/java" || { echo "Java Runtime Environment (JRE) not installed."; if [ "$1" = "stop" ]; then exit 0; else exit 5; fi; } # Verify curl utility test -x "$(which curl)" || { echo "curl not installed."; if [ "$1" = "stop" ]; then exit 0; else exit 5; fi; } start() { INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id) USERDATA=$(curl -s http://169.254.169.254/latest/user-data) ELASTIC_IP=$(echo $USERDATA | awk 'BEGIN{RS="|";FS="="} /elastic-ip/ {print $2}') ELASTIC_HOSTNAME=$(echo $USERDATA | awk 'BEGIN{RS="|";FS="="} /hostname/ {print $2}') if [ -n "${ELASTIC_IP}" ] then ec2-associate-address --private-key $EC2_PRIVATE_KEY --cert $EC2_CERT --instance $INSTANCE_ID $ELASTIC_IP else echo "No Elastic IP passed." fi if [ -n "${ELASTIC_HOSTNAME}" ] then hostname $ELASTIC_HOSTNAME unalias cp cp -f /etc/sysconfig/network /etc/sysconfig/network.bak sed -ie 's/^\(HOSTNAME\)=.*$/\1='$ELASTIC_HOSTNAME'/' /etc/sysconfig/network else echo "No hostname passed." fi } stop() { echo "Nothing to do here" } restart() { stop start } # See how we were called. case "$1" in start) start ;; stop) stop ;; restart) restart ;; *) echo $"Usage: $0 {start|stop|restart}" exit 1 esac exit $?

Update the runlevel information for the new system service.


# /bin/chmod +x /etc/init.d/ec2-elastic-ip # /sbin/chkconfig --level 34 ec2-elastic-ip on

Start the Instance

Once the startup script is in place and you have verified that the user data is being passed to the instance, restart the target EC2 instance.


# ec2-stop-instances i-0a33fc72 INSTANCE i-0a33fc72 running stopping # ec2-start-instances i-0a33fc72 INSTANCE i-0a33fc72 stopped pending

At this point, it should be noted that associating an Elastic IP address or changing the hostname of the target EC2 instance will not effect your DNS in any way. Update your DNS by creating or modifying an A-record for the EC2 instance by supplying the static IP address and hostname so that the instance is accessible by other computers. Note that changing the hostname of the instance in the EC2 startup script only effects the "internal" hostname. Test your DNS using ping.


# ping -c 3 ip-test.aws-idev.com PING ip-test.aws-idev.com (23.23.232.241) 56(84) bytes of data. 64 bytes from ec2-23-23-232-241.compute-1.amazonaws.com (23.23.232.241): icmp_seq=1 ttl=49 time=24.4 ms 64 bytes from ec2-23-23-232-241.compute-1.amazonaws.com (23.23.232.241): icmp_seq=2 ttl=49 time=25.0 ms 64 bytes from ec2-23-23-232-241.compute-1.amazonaws.com (23.23.232.241): icmp_seq=3 ttl=49 time=26.8 ms

When the instance starts up, it should now be accessible using its associated Elastic IP address.


# ssh -i .ssh/idevelopment-ec2-key.pem ip-test.aws-idev.com The authenticity of host 'ip-test.aws-idev.com (23.23.232.241)' can't be established. RSA key fingerprint is c2:78:93:e3:9c:c8:00:93:dc:a9:1f:20:df:4b:3f:3c. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'ip-test.aws-idev.com,23.23.232.241' (RSA) to the list of known hosts. Last login: Tue Jul 3 20:38:28 2012 from 24.144.233.98 # hostname ip-test.aws-idev.com # cat /etc/sysconfig/network NETWORKING=yes HOSTNAME=ip-test.aws-idev.com # cat /etc/sysconfig/network.bak NETWORKING=yes HOSTNAME=localhost.localdomain

About the Author

Jeffrey Hunter is an Oracle Certified Professional, Java Development Certified Professional, Author, and an Oracle ACE. Jeff currently works as a Senior Database Administrator for The DBA Zone, Inc. located in Pittsburgh, Pennsylvania. His work includes advanced performance tuning, Java and PL/SQL programming, developing high availability solutions, capacity planning, database security, and physical / logical database design in a UNIX / Linux server environment. Jeff's other interests include mathematical encryption theory, tutoring advanced mathematics, programming language processors (compilers and interpreters) in Java and C, LDAP, writing web-based database administration tools, and of course Linux. He has been a Sr. Database Administrator and Software Engineer for over 20 years and maintains his own website site at: http://www.iDevelopment.info. Jeff graduated from Stanislaus State University in Turlock, California, with a Bachelor's degree in Computer Science and Mathematics.



Copyright (c) 1998-2017 Jeffrey M. Hunter. All rights reserved.

All articles, scripts and material located at the Internet address of http://www.idevelopment.info is the copyright of Jeffrey M. Hunter and is protected under copyright laws of the United States. This document may not be hosted on any other site without my express, prior, written permission. Application to host any of the material elsewhere can be made by contacting me at jhunter@idevelopment.info.

I have made every effort and taken great care in making sure that the material included on my web site is technically accurate, but I disclaim any and all responsibility for any loss, damage or destruction of data or any other property which may arise from relying on it. I will in no case be liable for any monetary damages arising from such loss, damage or destruction.

Last modified on
Friday, 28-Sep-2012 20:09:59 EDT
Page Count: 37459