0% found this document useful (0 votes)
244 views

Dynamically Scaling Web Applications in Amazon EC2

This document proposes a solution to dynamically scale web applications running on Amazon EC2 instances. It involves using Nginx as a load balancer, Nagios for monitoring, and shell scripts to dynamically add and remove application servers from the load balancing and monitoring configurations. Key assumptions include having basic Linux, Nginx, and Nagios knowledge. The challenges addressed are dynamic IP addresses, dynamic configurations for load balancing, and session/state management across multiple application servers. The proposed setup has load balancer, application, and database servers each on their own AMIs. Elastic IPs are used for the load balancer and database for stable addressing. Shell scripts will update configurations when scaling the application servers.

Uploaded by

Sindhu Jijo
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
244 views

Dynamically Scaling Web Applications in Amazon EC2

This document proposes a solution to dynamically scale web applications running on Amazon EC2 instances. It involves using Nginx as a load balancer, Nagios for monitoring, and shell scripts to dynamically add and remove application servers from the load balancing and monitoring configurations. Key assumptions include having basic Linux, Nginx, and Nagios knowledge. The challenges addressed are dynamic IP addresses, dynamic configurations for load balancing, and session/state management across multiple application servers. The proposed setup has load balancer, application, and database servers each on their own AMIs. Elastic IPs are used for the load balancer and database for stable addressing. Shell scripts will update configurations when scaling the application servers.

Uploaded by

Sindhu Jijo
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 19

Dynamically Scaling Web Applications in Amazon EC2 Ramesh Rajamani

Blog: www.techmasala.com Email: ramesh.rajamani@gmail.com Twitter: http://twitter.com/rramesh

Disclaimer
The approach and the scripts that are provided along with this whitepaper is AS IS without any warranties of any kind. The scripts have not been thoroughly tested under all conditions. I, therefore, cannot guarantee or imply reliability, serviceability, or function of these programs.

Table of Contents
Disclaimer...................................................................................................2 Introduction................................................................................................4 Assumptions...............................................................................................4 The Problem................................................................................................4 The Setup....................................................................................................5
Elastic IP..........................................................................................................6

The Approach.............................................................................................7 Nginx Configuration...................................................................................9 Nagios Configuration...............................................................................11 The Shell Script Web Server...................................................................14
The Approach................................................................................................14 Examples.......................................................................................................14 The Script and Configuration bindings..........................................................15 The Scripts.....................................................................................................15 Adding to Xinetd service ...............................................................................15

Client Side Script......................................................................................16 Finally........................................................................................................18 What Next?................................................................................................18 Appendix A References.......................................................................19

Introduction
This whitepaper attempts at a solution to scale your web applications running on EC2 instances dynamically using simple shell scripts. The whitepaper uses Linux instances, with Nginx acting as the load balancer and Nagios for monitoring the instances. The application server could be anything but for this whitepaper, am assuming a Rails application running on Mongrel and using the mongrel cluster. While these technologies are specific to this whitepaper to provide an easy understanding, what is important here is the approach and if one understands it, s/he could apply it using any technology that fits the respective roles.

Assumptions
This document assumes that you have fair amount of knowledge working with Linux systems, and you know and have worked with Nginx and Nagios and their setup and configuration. Also this whitepaper assumes that you know how to work with Amazon EC2 instances such as to bring up and bring down instances and bundling and uploading the AMIs to S3.

The Problem
Even though the Amazon cloud is a dynamic computing environment that enables one to bring in or run as many instances at any given point of time, the reality of all these instances working together as a cluster with load balancing and scaling up or down as needed is far from true. Let us take an example to see why high scalability is a possibility than something that is available off the shelves. A highly scalable environment means that the resources that are setup can individually or together be scaled up or scaled down based on the demand and the amount of utilization of these resources. When a program or an application that is run on an environment is as independent from any program or application or an environment that lives physically separate on a different environment, then that program or application can be highly scalable. This also includes state information that needs to be shared. Think of a calculator program that accepts an input, processes it and gives back a result. Now this program is only dependent on the environment where it runs. One can bring in as many similar environments as needed and route a user to any of these instances to be served without having to worry about partially served transactions and thereby inconsistency. On the other hand take a web application as an example. Typically a web application might be dependent on a database or a service from third party application or vendor that could be residing outside of the environment. Also the application might be dependent on maintaining the state of a user for continuity and session validity for performing an action. In such a case the difficulty in scaling up or scaling down the environment becomes tight as there are dependencies that need to be considered. Given these dependencies when a web application is configured to run on environment it is dependent on information that will enable it to communicate with its dependencies. For example a database configuration that helps the web application knows where the

database is hosted, which port it is listening to and so on. Hence when the environment is cloned for clustering it is important that these dependencies can accept the new cloned instance. For example if the database access has been specifically given to a host then the connectivity from the new cloned instance may not work because the hosts identification (IP in this case) will be different. The other important aspect in a web application is the session handling. When all the requests come to a single instance, the session can be maintained in memory and can be used to check the validity of a user and also enable user continuity or flow across the web application. But when the web application is clustered and scaled, the session information has to be either shared in the database or we need to ensure a way to send a user always to a specific instance once he is into the application. Those are some of the challenges when it comes to scaling a web application. With respect to deploying a web application into the EC2 environment below are additional challenges. IP Address Since the EC2 is dynamic in nature the IP address of an instance is dynamically generated whenever an instance is started. Even though Amazon provides Elastic IPs which are static IP addresses that can be assigned to EC2 instances and can be used to refer from other instances, it is available limited in number (even though it could be requested for more) and also puts an additional dependency on binding specific addresses to instances. Because of this limitation using Elastic IP addresses, especially on the instances holding applications limits the scalability aspect of the application. Dynamic configuration When applications are scaled the requests have to be routed to the instances dynamically and based on certain algorithm. In deciding which instance will serve a request certain parameters and current status and load of the instances are also considered. This is what a load balancer does. A load balancer can either be hardware based or software based. A hardware based load balancer is highly reliable and available than a software load balancer. At this point of writing, Amazon does not have anything to offer with regards to providing a solution for load balancing EC2 instances. Hence the user is left with setting up a software load balancer of his own. So the problem becomes more apparent when the application servers are scaled dynamically how to add a new instance to the load balancers configuration or how to remove when an instance is removed from the cluster? This whitepaper aims at solving the above two problems.

The Setup
We will assume the below setup for our web application. You could improvise on this setup to meet your needs.

Application Server 1

Load Balancer

Application Server 2

Database Server

Application Server N

Figure 1

As per the above setup we will have three AMIs as described below. Load Balancer This AMI will contain the Nginx web server that will help us do the load balancing of the application in the application server. This instance will also contain the Nagios monitoring software. We will see how we can add the app server instances can be added to the monitoring service for health check up. Application Server This AMI will contain your application. As mentioned earlier we will be assuming this is a Rails application running on Mongrel and Mongrel Cluster plugin. But in fact this could be any web application running on any technology. All we are going to do is write some script that will update our load balancer configuration of the new instance and the application. Database Server This AMI contains the RDBMS required by the web application.

Elastic IP
To make our lives easy we will associate an Elastic IP for our load balancer instance and the database instance. Since these two instances are single and will not change we will use the Elastic IP and ensure that the Elastic IP address is used wherever we refer to these instances. The following information will be used for reference within this document and in the scripts. This is just dummy data and you should use the actual information pertaining to your environment before making use of the scripts. Load Balancer Instance

Elastic IP Address 111.222.111.1 Public DNS - ec2-111-222-111-1.compute-1.amazonaws.com Database Server Instance Elastic IP Address 111.222.111.3 Public DNS - ec2-111-222-111-3.compute-1.amazonaws.com Application Server Instance Dynamic IP address Gets assigned when starting an instance Application Mongrel cluster running on ports 8500, 8501, 8502 Notice that since we are using mongrel cluster, now this application is kind of vertically load balanced through mongrel and then horizontally load balanced through NGINX. In your case it could be just one instance of the application running on an application server. Accordingly you might have to update the scripts.

The Approach
In order for dynamically scaling the application server we need to make sure that we can meet the flow depicted in Figure 2. As you can see the key thing is this whole thing can work if we are able to call a program on the load balancer server when an instance is launched and when it is taken down. This program should assist us in adding or removing an instance to the load balancer configuration and the monitoring application configuration. The server application could be written in any programming language that can listen on a specific port for requests and then it can call some native commands to update the configuration files and restart the load balancer and the monitoring application. Since after receiving the request all the tasks performed by this server are commands to be executed in the shell, why not this server itself is created using shell script? My inspiration in making it came from sites that I stumbled upon that had articles on creating a web server using shell script1 and using Bourne shell2. Using the above references I created a web server in shell script that accepts REST URL type requests that is parsed and based on the request changes the load balancer and monitoring configuration and restarts. Before we get into the details of how this server works, let us see how we can setup the Nginx configuration and Nagios configuration to take in dynamically instances that need to be load balanced and monitored respectively.

1 2

A Web Server in a Shell Script - http://www.debian-administration.org/articles/371 Writing a web server in Bourne Shell - http://sprocket.io/blog/2008/03/writing-a-web-server-in-bourneshell/

Start an application server instance

Instance Terminate

Instance Boot and Service Initializations

Shutdown Process

Get this instances IP address

Call service on load balancer , pass this IP and application ports to be added to NGINX configuration

Call service on load balancer , pass this IP and application ports to be removed from NGINX configuration

Call service on load balancer , pass this IP and ask it to add this instance for monitoring

Call service on load balancer , pass this IP and ask it to remove this instance from monitoring

Instance Ready, serve requests

Shutdown Request

Requests proxied from NGINX

Figure 2 - The scaling flow

Nginx Configuration
Typically the Nginx configuration is in the file nginx.conf under the conf directory of Nginx home directory. As a standard practice it would be easy to maintain and separate, application specific configurations in a separate configuration file under a separate folder and include the files in the main configuration file using the include directive. I prefer to create a separate directory include.conf under Nginx home directory and have separate configuration file for every application I want to be served through Nginx. Below is a sample section of the main configuration file that includes the other configuration files under the include.conf folder.

include ../include.conf/*.conf;

Notice that you dont have to include the configuration files individually but use wildcard to include all the files that have the suffix .conf. Next we want to configure Nginx for a virtual host configuration for a specific domain and we want Nginx to proxy those requests to the application on the application server. We not only want to proxy the request but also want Nginx to load balance and pass the requests to one of the instances of the application. Here is an example configuration application.conf which needs to be placed under the include.conf folder.
# application.cluster will hold the available clusters # at any given point of time include ../include.conf/application.cluster; server { listen server_name access_log error_log 80; www.example.com; logs/example.access.log main; logs/example.error.log;

# }

location / { proxy_pass http://clustapp; proxy_set_header X-Real-IP $remote_addr; error_page 500 502 503 504 /50x.html; Other parameters }

What are important in the above example is the first line that includes another file and the line that has proxy_pass keyword. The proxy_pass basically says proxy all the requests coming to this server (defined by www.example.com listening on default HTTP port 80)

to http://clustapp. Where is this clustapp and what it is? Well it is a way of defining the route where the request has to be reflected. Let us look at a sample of what application.cluster file contains.
upstream clustapp { ip_hash; server 100.110.120.130:8500; server 100.110.120.130:8501; server 100.110.120.130:8502; }

The first line is the upstream directive that helps in configuring the load balancer for an application. As you can see the name clustapp is what we used as http://clustapp in the proxy_pass directive. Nginx picks up an instance out of the list and passes the request. Refer to the Nginx manual for more detail on how Nginx load balancing works using the above syntax. One of the problems we discussed was session sharing and the difficulties in sharing a users state in a clustered environment. As also said that one of the easiest approaches is to ensure that a clients request is always sent to the same instance from the moment the client hits the server. This is also called as session stickiness. This is easily achieved through Nginx through the ip_hash directive. As you can see in the above example there are three server entries, which means Nginx can use those servers for load balancing. The IP address of all the three servers are the same but the ports are different. In our case as we said our application is a Rails application using mongrel cluster those are nothing but the three instances of the same application run by mongrel on the same server on ports 8500, 8501 and 8502 respectively. But since we said that the application servers are going to be dynamically added whenever the instances are run, by default before starting our instances this file would be empty as below.
upstream clustapp { ip_hash; }

We will use our shell script web server to add and remove the servers with ports as and when an instance is added and removed. When the configuration is changed it is not picked up by Nginx automatically. If we stop and start the service it is possible that some of the client requests are not met or some of the clients might be routed to different instance in the cluster which may not be aware of the users session and the user might be taken to a login page all of a sudden. But Nginx picks up the configuration when it is reloaded. To reload the nginx configuration one has to kill the nginx process with the HUP signal. This ensures that nginx reloads itself

thereby loading the latest configuration and at the same time preserving client information and the routing. Nginx doesnt come with any script that allows starting, stopping and reloading the server. When you download the scripts along with this white paper it contains a script nginx.server that will help doing the starting, stopping and reloading Nginx server. This script is used in the cluster.modify script to reload Nginx after modifying the cluster details.

Nagios Configuration
Nagios is a monitoring software that can help in checking if things are going right in a server through certain commands passing in some parameters and evaluating the result versus the expected. If things are wrong then it sends out notification emails so that someone can take care of it. Nagios can not only monitor the server on which it resides but can also monitor any remote server through its plugin called NRPE. NRPE can run as a daemon on a remote server, execute the commands that can check the status of various things on the server and send back a status to the main Nagios server. The servers that need to be monitored and the services that need to be monitored on each of these servers are configured using configuration files on the Nagios server. For our application server we need to have a configuration file and the services defined. For the purpose of simplifying things we will show a simple configuration file with only one service to check the CPU load of the server. You could always add more services that you want to be monitored. Refer the Nagios documentation for more details on how to configure a server and services to be monitored. The below is an example Nagios configuration file for our application server.
define host{ name appserver ; Name of this template use generic-host ; Inherit default values check_period 24x7 check_interval 5 retry_interval 1 max_check_attempts 10 check_command check-host-alive notifications_enabled 1 notification_period 24x7 notification_interval 30 notification_options d,r contact_groups admins register 0 ; DONT REGISTER THIS - ITS A TEMPLATE

} define host{

use appserver ; Inherit default values from a template host_name appserver-1 ; Name of this server alias Application Server - 1 ; A longer name address 111.222.111.1 ; IP address of the server }

define service{ use generic-service host_name appserver-1 service_description CPU Load servicegroups Process check_command check_nrpe!check_load notifications_enabled 1 check_period 24x7 notification_interval 30 notification_period 24x7 notification_options w,c,r contact_groups admins

There are three blocks in the above configuration file. The first one is a host definition and a template for the application server instance that we want to use. As you can see the last line in that block register 0 tells Nagios to consider this itself as a host but rather take this as a template that could be inherited in another host definition. And thats what we do in the first line of the next host block. The service block defines a service for checking the CPU load and using the check_nrpe command which means that the check has to be done on a remote server. The host_name in the service block binds this service check with the host defined with appserver-1. As a good practice the template definition of the host for the application server could be kept in a separate file and can be included through the global configuration file nagios.cfg. There is a catch in this configuration. If you notice the lines that have been bolded in the above script are the lines that have information bound to very specific instance. Especially the host name and address are very specific. What we need is to have the configuration definitions added dynamically whenever a new instance of the application server is launched. Also when an application server instance is brought down we want it to be removed from monitoring. So instead of creating the whole configuration for every instance we launch, we could use a template and replace the lines that bind the configuration to an instance through the shell script server we are going to write. So we will replace the lines in bold in the above script as below.
... host_name appserver-@boxname ; Name of this server alias Application Server - @boxname ; A longer name address @boxname ; IP address of the server } define service{ use generic-service host_name appserver-@boxname ...

You see we have replaced the name and the address with @boxname which we will use it as a label to be replaced with the IP address of the actual server through our shell script web server when adding an application server instance. After replacing we will save it as a separate configuration file for the instance that was launched. Let us keep this configuration template in a separate directory than from the configuration files present in the <nagios home>/etc/objects directory. I created a directory templates under <nagios home>/ and saved the above configuration as appserver.tpl. The configuration files for specific hosts are included in the global nagios configuration file nagios.cfg. Unless the configuration files are included explicitly Nagios does not consider other files even though they may be present under the <nagios home>/etc/objects directory. Here are the lines in the nagios.cfg that are important to us.
# You can specify individual object config files as shown below: cfg_file=/usr/local/nagios/etc/objects/commands.cfg cfg_file=/usr/local/nagios/etc/objects/contacts.cfg cfg_file=/usr/local/nagios/etc/objects/timeperiods.cfg cfg_file=/usr/local/nagios/etc/objects/templates.cfg # Definitions for monitoring the local (Linux) host cfg_file=/usr/local/nagios/etc/objects/localhost.cfg

In a typical scenario we would add our application servers monitoring configuration file under those lines, but then we dont want to keep adding a line that is a configuration file for specific application server instance every time we start one. Instead let us make this simple. Whenever our shell script web server receives a request to add an instance for monitoring we will use the template we have, replace the label @boxname with the IP address of the new instance and save that configuration file in a specific location with the appserver-ip-address as the file name with the extension of cfg. Let us call this directory cluster and create it under <nagios home>/etc. When our scripts are ready and put to use you should be seeing files under the <nagios home>/etc/cluster something like below.
nagios]# ls etc/cluster/ appserver-10.10.10.1.cfg appserver-10.10.10.2.cfg

So now we want all the configuration files under the cluster directory to be included by Nagios. So in the global nagios.cfg file the place that we should be interested in is the section that has a comment as given below.
# You can also tell Nagios to process all config files (with a .cfg # extension) in a particular directory by using the cfg_dir # directive as shown below: #cfg_dir=/usr/local/nagios/etc/servers cfg_dir=/usr/local/nagios/etc/cluster

There, we have added the cluster directory to tell Nagios to include all the configuration files under that directory. With that set we have setup Nagios ready to take up new instances to be monitored dynamically.

The Shell Script Web Server


Now that we have our load balancer and the monitoring application ready to take in dynamically the configurations needed when adding a new application server instance, it is time for us to look at our shell script based web server that will help us in receiving a request from the application server when it boots up and will add the necessary configurations to the load balancer and the monitoring and restart these services, all on the fly.

The Approach
1. We will write our web server with the following approach. 2. Our script will be made to listen on a specific port and will receive HTTP requests and will output HTTP response. 3. The script will reside on the same server as the load balancer and the monitoring application resides. 4. The server will have two functions scale and monitor. 5. The scale function will either add or remove configurations from load balancer based on the parameters 6. The monitor function will add or remove the configuration from Nagios to monitor or remove monitoring of an instance respectively. 7. The script will reload/restart the services after adding/removing necessary configurations.

Examples
To scale up an application named application running in an instance with EC2 private address 10.10.10.1 and on port 8500, the client has to call the server with the following URL.
http://host:port/cluster/scale/application/up/10.10.10.1/8500

To scale down an application named application running in an instance with EC2 private address 10.10.10.1 and on port 8500, the client has to call the server with the following URL.
http://host:port/cluster/scale/application/down/10.10.10.1/8500

To scale down all the applications named application running in an instance with EC2 private address 10.10.10.1 and any number of ports, the client has to call the server with the following URL.

http://host:port/cluster/scale/application/up/10.10.10.1

To add monitoring to an EC2 instance with the private address 10.10.10.1, the client has to call the server with the following URL.
http://host:port/cluster/monitor/application/10.10.10.1/add

To remove monitoring of an EC2 instance with the private address 10.10.10.1, the client has to call the server with the following URL.
http://host:port/cluster/monitor/application/10.10.10.1/remove

The Script and Configuration bindings


The shell script web server is dependent on certain configuration requirements for it to work properly. If you have noticed in the above examples, there is a parameter application. The script uses this to look for some files in the load balancer configuration and as well as in the Nagios configuration. Nginx The file application.cluster is being looked for in the <nginx home>/include.conf directory where the server:port is added or removed whenever a scale up or down is called. Nagios The file application.tpl is being looked for in the <nagios home>/template directory and is used to replace the label @boxname and the replaced file is placed under <nagios home>/etc/cluster/application-ip-address.cfg file.

The Scripts
There are two scripts that are used to achieve the whole configuration setup and restart of Nginx and Nagios services. scale.server This is the core script that receives all the requests coming from the client. It parses the requests, gets the parameters, does a bit of validation and then calls the appropriate function to scale or to monitor. cluster.modify This script is called by the scale.server when the request is to add an instance to be added to the nginx load balancer configuration. This script is kept separate for the sake of better readability, maintainability and to use it separate or with other scripts if need be. The above scripts are available along with this white paper in the zip file. The script has necessary comments to understand where what happens.

Adding to Xinetd service


We want the scale.server to be listening on a specific port for processing the requests and also we want this to be a service that gets started when load balancer server starts. So we

make use of the Xinetd service that should be available in most of the linux systems or it can be installed easily. xinetd, the eXtended InterNET Daemon, is an open-source superserver daemon which runs on many Unix-like systems and manages Internet-based connectivity. It offers a more secure extension to or version of inetd, the Internet daemon. First we add the configuration in a file, let us call it scale under /etc/xinetd.d/. The below is the configuration to be added in the file scale.
# default: on # description: Service that enables adding/removing instances # to the nginx load balancer configuration and nagios monitoring # service service scale { flags = REUSE socket_type = stream port = 11511 wait = no user = webuser group = webuser server = /usr/bin/scale.server log_on_failure += USERID disable = no }

As you can see we are using a non-standard port 11511 for the scale.server script to listen to. You can also see that the webuser is being used as the user which the script will be run as. You can alter these values to your preferences and also the location where the scale.server script is located. Next is to add this to the list of services in the file /etc/services.
. . . # Local services scale 11511/tcp load/monitoring

Dynamically

add

ec2

instances

for

With that our web server should be ready and listening for requests from instances to add/ remove them in the cluster to be load balanced and monitored.

Client Side Script


Now that our server is ready we have to get ready our application server instance. We need to ensure during the boot up process we can add our instance to the cluster to be load balanced and to be able to be monitored. And while terminating the instance we need to ensure that this instance is removed from the load balancing cluster and removed from being monitored. The assumption is that NRPE daemon is installed and configured to enable checking necessary services to ensure the health of the system and the applications running.

This can be achieved by writing a couple of simple shell scripts that can be run during the startup and shutdown. In both the scripts we need to be able to find the IP address of this instance so that we can pass that to our script server. For this I am thankful to the script that I found on the nixCraft website 3. The script is saved as an executable shell script, findip in the /usr/bin folder for easy access. Below is the script readyToServe.sh that does the job of calling the script server to add this instance to the cluster and to be monitored.
#!/bin/bash # Find the IP address of this instance myIP=`/usr/bin/findip` # The public DNS name of the host that runs the server script lbHost=ec2-111-222-111-1.compute-1.amazonaws.com # The port on which the server script is listening serverPort=11511 # Where do we want to log the output of the execution of this script logFile=/mnt/logs/readyToServe.log # Start our Rails application mongrel cluster /etc/init.d/mongrel_cluster start # Add Rails application mongrel cluster curl -s http://$lbHost:$serverPort/scale/application/up/$myIP/8500 >> $logFile curl -s http://$lbHost:$serverPort/scale/application/up/$myIP/8501 >> $logFile curl -s http://$lbHost:$serverPort/scale/application/up/$myIP/8502 >> $logFile # Add this instance to be monitored by nagios curl -s http://$lbHost:$serverPort/monitor/appserver/$myIP/add >> $logFile

Similarly when we shutdown the instance we can create a script takeMeOff.sh that will remove this instance from the load balance cluster and also remove to be monitored.
#!/bin/bash # Find the IP address of this instance myIP=`/usr/bin/findip` # The public DNS name of the host that runs the server script lbHost=ec2-111-222-111-1.compute-1.amazonaws.com # The port on which the server script is listening serverPort=11511 # Where do we want to log the output of the execution of this script logFile=/mnt/logs/readyToServe.log # Remove the Rails application mongrel cluster, pass only the IP # our server will remove all references to this IP curl -s http://$lbHost:$serverPort/scale/application/down/$myIP >> $logFile # Remove this instance from being monitored by nagios curl -s http://$lbHost:$serverPort/monitor/appserver/$myIP/remove >> $logFile

Shell Script to Read IP Address - http://bash.cyberciti.biz/misc-shell/read-local-ip-address/

# Stop our Rails application mongrel cluster /etc/init.d/mongrel_cluster stop

Now that we have the scripts we need to be able to add these to be run when the instance is started and when the instance is shutdown respectively. This can be done in several ways. The easiest approach would be to call the readyToServe.sh script in the /etc/rc.local file and add the line in the stop function in /etc/init.d/xinetd script. These two scripts get executed during the instance start and shutdown and hence our script will be called during the boot and shutdown of the instance. But a standard professional approach would be to add them as services to be executed during boot and shutdown. There are several websites and manuals that explain about this. As one reference you can read the article Using chkconfig and /usr/sbin/service to run startup scripts in Redhat4. Depending on your linux distribution the steps, configurations and files could be different.

Finally
Finally after you are done with setting up everything on the instances dont forget to bundle up the instances and upload them to S3 and register them as AMIs.

What Next?
The approach and the scripts presented in this whitepaper are just first step to making your application in Amazon environment highly scalable. As you might have realized this setup only focuses on scaling up the application running on a server. There are few bottlenecks in this setup. The load balancer server and database server are single point of failures in this setup. Database clustering and load balancing is a separate topic of its own and comes with its own complexity and problems. There are several techniques to solve the problem of load balancer being single point of failure. One of them being that every instance in the cluster could also act as a load balancer and a dynamic DNS with round robin algorithm can be used to make any instance front end the requests and then load balance the requests to other instances in the cluster. These are beyond the scope of this document and are left to the user to explore further and also modify the setup provided in this whitepaper accordingly.

Using chkconfig and /usr/sbin/service to run startup scripts in Redhat http://www.netadmintools.com/art94.html

Appendix A References
Amazon EC2 Tools http://developer.amazonwebservices.com/connect/entry.jspa? externalID=351&categoryID=88 AWS Security http://s3.amazonaws.com/aws_blog/AWS_Security_Whitepap Whitepaper er_2008_09.pdf EC2 Tools Developer http://awsdocs.s3.amazonaws.com/EC2/latest/ec2-dg.pdf documentation Whitepaper Extend Elastic IP http://aws.amazon.com/contact-us/eip_limit_request/ address limit NGINX Wiki http://wiki.codemongers.com/Main Nagios Guide http://nagios.sourceforge.net/docs/nagios-3.pdf NRPE Guide http://nagios.sourceforge.net/docs/nrpe/NRPE.pdf Using chkconfig and http://www.netadmintools.com/art94.html /usr/sbin/service to run startup scripts in Redhat Shell Script to Read IP http://bash.cyberciti.biz/misc-shell/read-local-ip-address/ Address A Web Server in a Shell http://www.debian-administration.org/articles/371 Script Writing a web server in http://sprocket.io/blog/2008/03/writing-a-web-server-inBourne Shell bourne-shell/

You might also like