To create a 3-tiered production-like Deployment from scratch using the 11H1 ServerTemplates.
Table of Contents
This tutorial is lengthy, but is a true end-to-end exercise that starts with nothing configured and finishes with a functional 3-tiered deployment similar to one that might be used in a production environment. The three tiers are load balancers, application servers (that can dynamically scale), and database servers. Unlike other tutorials that start with two front-end application servers that balance the load, this tutorial shows you how to create a distinct tier for load balancers and a distinct tier for application servers.
The following diagram illustrates the 3-tiered archictecture that we'll use in this tutorial.
This tutorial does not increase availability by using multiple Availability Zones. The tutorial assumes one Availability Zone for simplicity's sake. As a best practice, however, we recommend using multiple Availability Zones when creating robust, highly available, production deployments. We do not recommend using multiple regions as part of a high-availability architecture because doing so incurs additional data transfer costs and adds latency.
Some of the simpler steps in this tutorial are not covered in detail but are instead outlined here while including additional Tips on configuration. This approach reduces the length of the tutorial and makes it easier to follow the overall approach. If you need additional information about a specific step, you can always use the Help text in the RightScale Dashboard. Additionally, the “See also” section at the end of this tutorial provides links to more detailed tutorials with step-by-step instructions.
This tutorial assumes that you are using the most recently published revisions of the referenced 11H1 ServerTemplates available in the MultiCloud Marketplace (MCM). If you have previously imported an older revision of an 11H1 ServerTemplate, it’s strongly recommended that you download the newest available revision to account for the maintenace releases since their original publish date. The tutorial may not be compatible with older revisions.
Use the following instructions to create a security group, an SSH key, and the Elastic IPs (EIPs) necessary for this tutorial. Collectively these are referred to as cloud resources.
Important! You must create the cloud resources in the specific AWS region (e.g. US East, US West, ect.) where you will launch your servers. This tutorial uses the US-East region.
First, you need a security group. You can use an existing one (if you have one) or simply create a new one.
Important! You must create the following cloud resources (security group, SSH key, and Elastic IPs) in the specific AWS region (e.g. US-East, US-West, etc.) where you will launch servers. In this tutorial, we launch servers in the US-East region.
To create your security group, see Create a New EC2 Security Group.
Tips:
After you have created your security group, add it to itself for all protocols (TCP/UDP/ICMP) and ports.
Important! When you add a security group, you must manually enter the name of the security group. Do not use the default name. In this case, the name is going to be the name of the new security group you are creating. You cannot achieve the same results using the “default” group. For more information, see Add a Security Group to Itself.
In the following example, the security group name is “production” and it has the following port permissions. The final list of permissions for your security group should look similar.
If you don’t have one already, you need to create a new SSH key. Even if your deployment uses strictly RightLink-enabled images, which do not require SSH to communicate, you need to use SSH to connect to your servers for testing and debugging purposes during this tutorial.
To create your SSH Key, see Create an SSH Key.
You will need two Elastic IP Addresses (EIPs) for your front-end load balancers. Name the EIPs appropriately (‘my-lb1’ and ‘my-lb2’). Be sure to record your EIP names and the associated IP addresses. You’ll need this information later in the tutorial.
To create your EIPs, see Create Elastic IPs (EIP)
Create two S3 buckets, one for the sample application file and one for your database dump file (and subsequent snapshots). Later in the tutorial, you will configure the Inputs for your ServerTemplates to point to these files. When servers are launched from the ServerTemplates, the servers access the files and create application and database servers.
To create the S3 buckets, see Create a New S3 Bucket.
To download the sample application and database dump file, click the following links. Make sure that the filenames are not modified by your operating system or browser when you download and save the files. Sometimes, extra characters are added to the filenames or the file extensions are changed or missing. The files must have the correct names to work.
Alternatively, our services team provides another sample PHP application (in .tgz format) and MySQL database dump file listed below (further known as the 'world' application/database). The database dump is the 'world' test database provided directly by MySQL.
Once you have a .tgz file for the sample application, you can upload them to your own web server or S3 bucket for use in the APPLICATION_CODE_PACKAGE input later in the tutorial. The MySQL dump .gz file should also be uploaded to an S3 bucket which will later be used in conjunction with the DB_MYSQLDUMP_FILENAME and DB_MYSQLDUMP_BUCKET inputs. Use a text value of 'world' for the DB_SCHEMA_NAME input later in the 'Database Tier Setup' section.
Upload the application and database dump files to their respective S3 buckets. After you upload a file, you need to refresh the browser window to view the file in the S3 bucket.
Note: When you upload a file to an S3 bucket, its access permissions are automatically set to “private” and can only be accessed with your AWS account credentials. Our scripts can use your AWS account credentials to access the files if they are located inside your AWS account buckets, even when the files are “private”. However, if you are using files stored in S3 buckets that do not belong to your AWS account, you must change the file permissions to “public-read”. You can do this by updating the file permissions from the drop-down menu.
The 11H1 ServerTemplates support the use of multiple DNS solutions including DNSMadeEasy, DynDNS, and Route 53. The information required for your ServerTemplates varies depending on the DNS solution you choose. The instructions that follow are for DNSMadeEasy. However, you can use these same steps to configure one of the other providers.
First, log into your DNSMadeEasy (DME) account. Then use the following information to create “A Records” for your Master and Slave Database Server and for your two Load Balancers.
For your Master Database Server:
For your Slave Database Server:
For your first load balancer (Load Balancer One):
For your second load balancer (Load Balancer Two):
Important! The only difference between the records for the Load Balancers is that the records have different Elastic IPs (EIPs).
The final records should look similar to the following screenshot.
Create the Credentials from the following list in the RightScale Credentials store. Creating Credentials is very simple to do (Design > Credentials), but quite easy to get wrong by entering the wrong values or by misusing the Credentials later on in this tutorial. Incorrect Credential names or values are common errors.
To create your Credentials, follow the instructions in Create Credentials for Common Inputs. Refer to the following table for guidance on setting the Credential values correctly.
Warning! The following values are examples only. Please provide your own unique values for these credentials to avoid using identical credentials as other users of this tutorial.
If you already have a Deployment for this tutorial, skip this section.
To create a Deployment, go to Manage > Deployments and click New. Provide a title and a brief description. Later, when you add Servers to the Deployment, you can set a specific Availability Zone. The Availability Zone that is defined at the Deployment level only takes effect if you add a Server with ‘-any-‘ as its Availability Zone.
For this tutorial, ignore the Default VPC Subnet and Default Placement Group and keep the default ‘None’ settings.
When you are ready, click Save to finish creating your Deployment.
The Database Manager for MySQL ServerTemplates are based on Amazon Elastic Block Store (EBS) Snapshots. Snapshots are highly efficient backups representing an EBS volume at a specific point in time. New EBS Volumes are created from a snapshot and are attached to a master/slave instance. When you launch a new Server using a Database Manager for MySQL ServerTemplate, the template uses the most recent EBS snapshot (or snapshots if you’re using a set of striped EBS volumes) available to begin the boot process.
Because you are creating this EBS setup from scratch, you don’t yet have a backup of the database (i.e. an existing set of EBS Snapshots). Therefore, the first step is to create your first backup of the database. When dealing with EBS Volumes, you should always attach fresh volumes that were created from the most recent snapshots.
Go to Design > MultiCloud Marketplace and import the following components:
Note: If you plan to make modifications to the ServerTemplates or RightScripts, make sure to clone the templates or scripts before you modify them.
From the Deployment’s Servers tab (Manage > Deployments > deployment name), select the cloud region where you want to create your database setup (e.g. AWS US-East) and click the Add Server button.
Select either the imported or cloned version of the “Database Manager for MySQL 5.0/5.1” ServerTemplate. Provide a nickname (i.e. my-db1) and select your SSH Key and Security Group.
For the Availability Zone, you can either launch the Master and Slave Servers in the same or different zones. For production environments, you might want to have your database servers in separate zones. But for testing purposes, you can launch the servers in the same zones.
Select a particular Availability Zone (e.g. us-east-1a). Click Confirm, double-check your selections and click Finish.
This first server is your Master Database Server. Although a running Slave Database Server is technically not required to have a functional site, it’s strongly recommended for replication and failover purposes. Fortunately, you can use the same ServerTemplate to add a second database server that will become the “slave” for the Master Database.
While you can repeat the steps above to create a second server, an easier method is to clone the existing server. Click on the Master Database Server’s Nickname link. Then click the Clone button. Give the second server a new name (e.g. jd-db2).
For high-availability purposes, we recommend that you launch the Slave Database Server in a different availability zone than the Master Database Server. Under the Info tab for the Slave Database Server, click the Edit button. Select a different availability zone for the slave (e.g. us-east-1b).
Next, as a best practice, we will define some common Input parameters at the Deployment level. Defining the Input parameters at the Deployment level ensures that all of the Servers in the Deployment inherit the Inputs and their values. This means that you only have to define the Inputs and set the values once.
Go to the Deployment’s Inputs tab and click Edit .
Notice that most of the Inputs are inherited from the ServerTemplate. However, there are a few required Inputs that you need to define, as well as a few others whose values you might want to change. Hover over the Info icon next to the Input name for a detailed description and a sample value. The values that you need to provide depend on the DNS solution you are using.
By default, the Inputs with missing values have “Inherit” selected as the data type. Use thepull-down menu to select the appropriate data type for the Input (e.g. Text, Cred (entail), SSH, etc.).
Database
Name | Description | Example Values |
DB_LINEAGE_NAME | Enter the name that will be used for the backup snapshots of the database. | text:mystripe |
MASTER_DB_DNSID | Enter the ID that points to the Master Database Server’s DNS Record, which maps to its private IP address. See Domain Setup. | DNSMadeEasy: 1234567 DynDNS: db-master.dyndns-home.com Route 53: Z3DSDFSDFX:db-master.aws.site.com Note:If Route 53 is used, the Time-To-Live (TTL) for the A Record must be 60 seconds, otherwise the script will fail. |
MASTER_DB_DNSNAME | Enter the Fully Qualified Domain Name (FQDN) that points to the Master Database Server. See Domain Setup. | DNSMadeEasy: master1.example-dnsname.com DynDNS: db-master.dyndns-home.com Route 53: db-master.aws.site.com |
SLAVE_DB_DNSID | Enter the ID that points to the Slave Database Server’s DNS Record, which maps to its private IP address. See Domain Setup. | DNSMadeEasy: 1234567 DynDNS: db-slave.dyndns-home.com Route 53: Z3DSDFSDFX:db-slave.aws.site.com Note:If Route 53 is used, the Time-To-Live (TTL) for the A Record must be 60 seconds, otherwise the script will fail. |
DNS
Name | Description | Example Values |
DNS_PASSWORD | Enter the password for your DNS account. Use a credential if you do not want to enter the value as text. | DNSMadeEasy: password |
DNS_PROVIDER | Enter your DNS provider. If you're using a DNS provider other than DNSMadeEasy, you will need to select it. | text:DNSMadeEasy (default) text:DynDNS text:Route53 |
DNS_USER | Enter the username for your DNS account. Use a credential if you do not want to enter the value as text. | DNSMadeEasy: username DynDNS: username Route 53: cred:AWS_ACCESS_KEY_ID |
SSH
Name | Decription | Example Values |
PRIVATE_SSH_KEY | Select the same SSH Key that you selected when you added the server. This key is used for server-to-server communication. Make sure the private key material is not missing. Syntax: key:<keyname>:<cloud_id> | key:production:1 |
After setting the Input values using the preceding tables, click Save.
Go back to the Deployment’s Servers tab (Manage > Deployments > deployment name) and launch the first database server (e.g. my-db1). This server will become your Master Database Server. To launch the server, click the Launch action icon.
When the Input Confirmation screen opens, verify that the INIT_SLAVE_AT_BOOT Input parameter is set to "False" (default). Since this server will be your Master Database Server, it is important to make sure that the server does not initialize as a slave database server at boot time.
Click the Launch action button to continue launching your database server.
Note: Do not launch your slave database server until you back up the database of the master server. Master server backup is covered in a later section of this tutorial.
In a few minutes, you will have a new server instance with MySQL installed, but it has an empty database. Be sure to wait for the server to boot up and enter the operational state before continuing to the next step (about 5-10 minutes).
Note: If you receive an error message about missing Input parameters and no Input is highlighted in red, it’s most likely because some of the required RightScale Credentials do not exist. The ServerTemplates have been preconfigured to use certain Credentials and assume that you’ve already created them.
If you did not complete the Create Credentials for Common Inputs step in the Deployment Setup section properly, you may not have created the required credentials that the ServerTeplates are trying to use. Once you’ve created those credentials, you should be able to successfully launch the server without receiving any missing Input error messages.
The next step is to create and attach an Amazon Elastic Block Store (EBS) volume, or stripe of EBS volumes, to the running instance where your MySQL data will be stored. To do this, you use the DB Create MySQL EBS stripe volume – 11H1 RightScript, which creates and attaches an EBS stripe designed for a MySQL server. By default, it creates a blank MySQL database with no striping that includes all the necessary privileges for replication, administration, and application purposes.
Go to the the Scripts tab of the running server. Under the Any Script section, select the latest revision of the DB Create MySQL EBS stripe volume – 11H1 script. If you do not see this script in the list, you can import it from the MultiCloud Marketplace (Design > MultiCloud Marketplace > RightScripts). See DB Create MySQL EBS stripe volume - 11H1.
After you select the script, click Run.
Note: If you run revision 9 of the script, you may receive the following Audit Entry: “failed: DB Create MySQL EBS stripe volume – 11H1”. This is not an issue. The script executed successfully and imported the database into the attached volumes. There is a check that needs to be modified in this script to prevent this Audit Entry from being logged. A modified version of the script will be published soon, but in the meantime you can continue with the rest of the tutorial.
Before the script executes, you are prompted to provide values for some of the Input parameters. Use the following tables to set these values. When all of the required Inputs have values and you are ready, click Continue to execute the script.
Backup
Name | Description | Example Values |
EBS_STRIPE_COUNT | Set the number of EBS volumes to create in the EBS stripe (e.g. 1,2,3, or more). The script creates and mounts the EBS volumes to the instance. The default value is 1, which means only a single volume is used (no striping). For this tutorial, set the value to 3. This creates an EBS stripe that consists of three EBS volumes. | text:3 |
EBS_TOTAL_VOLUME_GROUP_SIZE | Set the total size of the striped EBS volume set in GB. For example, For this tutorial, set the value to 3. A value of 3 here combined with a stripe count of 3 above, creates an EBS stripe that contains 3 EBS volumes that are each 1 GB in size (total size 3 GB). | text:3 |
Cloud
Name | Description | Example Values |
AWS_ACCESS_KEY_ID | Select the predefined Credential for the AWS Access Key ID. | cred:AWS_ACCESS_KEY_ID |
AWS_SECRET_ACCESS_KEY | Select the predefined Credential for the AWS Secret Access Key. | cred:AWS_SECRET_ACCESS_KEY |
SERVER_EIP | (Optional) If there are remote servers (located outside of the EC2 region in which the database servers are launched) that need to communicate with master database server, you can assign the instance an Elastic (public) IP address. | env: RS_EIP of "my-db1" server |
Database
Name | Description | Example Values |
DBADMIN_PASSWORD | Select the Credential you created for the password of the admin user in the database. Make sure the Credential has the correct value for this tutorial (admindb). | cred:DBADMIN_PASSWORD |
DBADMIN_USER | Select the Credential you created for the username of the admin user in the database. Make sure the Credential has the correct value for this tutorial (admindb). The admin username and password are used for tasks that require administrator access to the database. | cred:DBADMIN_USER |
DBAPPLICATION_PASSWORD | Select the Credential you created for the password of the application user in the database. Make sure the Credential has the correct value for this tutorial (1234). | cred:DBAPPLICATION_PASSWORD |
DBAPPLICATION_USER | Select the Credential you created for the username of the application user in the database. Make sure the Credential has the correct value for this tutorial (1234). The application username and password allow the application to access the database in a restricted fashion. | cred:DBAPPLICATION_USER |
DBREPLICATION_PASSWORD | Select the Credential you created for the password of the replication user in the database. Make sure the Credential has the correct value for this tutorial (dbrpl). | cred:DBREPLICATION_PASSWORD |
DBREPLICATION_USER | Select the Credential you created for the username of the replication user in the database. Make sure the Credential has the correct value for this tutorial (dbrpl). The replication username and password are used for replication between the Master and Slave Database Servers. | cred:DBREPLICATION_USER |
DB_LINEAGE_NAME | Enter the name the script will use to locate the appropriate EBS snapshots for the EBS striped volume set. This value will also serve as the common name for each backup snapshot (e.g. mystripe). | text:mystripe |
DB_MYSQLDUMP_BUCKET | Enter the name of the S3 bucket where the existing MySQL database dump file is stored (e.g. myproject-db). Click the ‘Override’ checkbox, select ‘Text” and enter the name of the S3 bucket. | text:mybucket |
DB_MYSQLDUMP_FILENAME | Enter the full filename of the MySQL dump file. This file needs to be located in the DB_MYSQLDUMP_BUCKET you set above. Click the 'Override dropdown' checkbox, select 'Text'. Enter the name of the MySQL dump file. You must specify a full filename. For example: myapp_prod_dump-200804161345.gz This is the name of the MySQL dump that file you uploaded to your S3 bucket earlier in this tutorial. | text:myapp_prod_dump-200804161345.gz |
DB_SCHEMA_NAME | Enter the name of the database schema. This name is set when you import the dump file into MySQL. The name is only defined within the MySQL instance and not within the actual dump file. As a result the name is somewhat arbitrary but should be descriptive. Important! Be sure to record this value. The Application Servers use this value to connect to the correct database schema. | text:myschema |
In order for the automatic backup RightScript to function properly, you first need to designate the running instance as the Master Database Server. Then you need to run a script that makes the server function as a Master Database Server. To do this, you use the DNS Master DB register – 11H1 RightScript. This script registers the server as the “Master-DB” and updates your DNS A Records accordingly.
Go to the Scripts tab of the running server. Under the Any Script section, select and run the DNS Master DB register – 11H1 script. Select the latest revision of the script. If you do not see this script in the list, you can import it from the MultiCloud Marketplace (Design > MultiCloud MarketPlace > RightScripts). See DNS Master DB register - 11H1.
After you select the script and the revision, click Run.
When the Inputs confirmation window appears, enter any missing Input parameter values. Be sure to use the same values that you defined earlier at the Deployment level. When you run an Any Script, these Inputs are not pre-populated from the values you defined at the Deployment level.
The followingInputs are used by the script and are pre-populated from the Deployment level: MASTER_DB_DNSID, DNS_PASSWORD, DNS_USER. You do not need to set the values for these Inputs again.
When the script executes, the running server's Private IP Address is reported to your DNS provider and the A Record that you previously defined for your Master Database Server is updated. To quickly verify this change, log into your DNS provider and check your A Records. The IP address of the "Master-DB" A Record should match the private (not public) IP address of your Master Database Server. Notice that because the Slave Database Server is not up and running yet, the A Record for the “Slave-DB” still has its placeholder IP address (1.2.3.4). Later, when you launch the Slave Database Server, this A Record will be automatically updated by one of the boot scripts.
The following screenshot shows an example for DNSMadEasy.
The next step is to manually create a snapshot (backup) of the EBS volume(s) for the MySQL database. This step is required before you launch the Slave Database Server. When you launch the Slave Database Server, it uses the most recent database backup to restore the database. This enables the server to come up and get in-sync with the Master Database in a much shorter timeframe.
Go to the Scripts tab of the running server and run the "DB EBS backup - 11H1" operational RightScript. This script makes a backup of your MySQL database by creating a snapshot for each attached volume in the stripe.
Important! You must wait for all of the snapshots to be 100% complete before continuing the tutorial. Go to Clouds > your AWS Region > EBS Snapshots to check the status. If there are multiple pages of snapshots, use the Filter by Nickname option and search for the value that you set for the DB_LINEAGE_NAME Input to quickly find your related snapshots (e.g. mystripe). You should find a snapshot for each volume in the stripe.
The time it takes to complete the initial EBS snapshots varies depending on the size of the EBS volumes. For example, it can take a long time (over an hour) for large volumes, where smaller volumes might complete in just 5-10 minutes.
You now have a backup of your MySQL database in the form of a set of EBS snapshots that you can use to launch a fresh, new database server using the same ServerTemplate. Notice that each snapshot has the same name and timestamp, but has a unique ID and a tag which denotes the stripe order.
When the database backup is 100% complete, you are ready to launch your Slave Database Server (e.g. my-db2).
Before you launch your Slave Database Server, you might want to consider changing its Availability Zone. Since you created the slave server by cloning the master server, the slave server is configured to launch an instance into the same Availability Zone as the master. If you want added redundancy (and are willing to pay for the additional data transfer costs), we recommend that you launch the slave server in a different Availability Zone from the master server. This allows you to have a running and in-sync backup server that you can use for failover and recovery scenarios if there is ever a major failure in the Availability Zone of your master server. You can edit the slave server's Availability Zone under the server’s Info tab.
Click the Launch action button of the second server in your Deployment. This new server will become a replicating slave server of the existing master server.
The ServerTemplate finds the most recent database snapshots using the DB_LINEAGE_NAME Input parameter (e.g. mystripe). The snapshots have a matching prefix (e.g. mystripe-master-yyyymmddttmm). For optimization purposes, the ServerTemplate automatically uses the most recent completed set of backup snapshots regardless of whether they are "slave" or "master” backups. This way, the slave server launches and is synchronized with the master server in a shorter timeframe.
Important! Set the INIT_SLAVE_AT_BOOT Input parameter to "true" (under the "Database" category's advanced inputs section) since you have a Master Database Server that's currently running. Setting this Input to "true" instructs the instance to initialize MySQL as a "Slave-DB" server during the boot process. Click the Launch, not Save and Launch button.
Congratulations! In a few minutes, when the server enters the "operational" state, you will have a MySQL master/slave database setup with data replication and automatic backups saved as EBS snapshots.
Note: In this example, we purposely did not name the first database server "master" (in the Dashboard) and the other one "slave" because we do not want the server names to become a source of confusion. Remember, over the lifecycle of your Deployment you'll most likely have to promote a "slave" to become the new "master" database server for troubleshooting purposes, or for performing various upgrades (e.g. vertical scaling from a 'small' to 'large' instance type).
Because you defined this server to be a Slave Database Server at launch time, one of the scripts reported the server’s Private IP Address to your DNS provider. Verify this change by logging into your DNS provider and checking your A Records. You should see that both of the A Records for your database servers are properly pointing to the Private IP Addresses of your Master and Slave Database Servers.
The following screenshot hows an example for DNSMadeEasy.
Important! If for any reason both servers are shut down, and you want to recreate the master/slave setup, it doesn't matter which server you launch first. Simply launch the first server with INIT_SLAVE_AT_BOOT set to false. Once the server becomes operational, run "DB EBS restore and become master" RightScript to make it the "master" server. Then you can launch the other server as the "slave" with INIT_SLAVE_AT_BOOT set to true. See the Database Manager for MySQL Stripe Runbook for other common scenarios.
If you ever need to shut down a database server, be sure to terminate it by running the 'DB TERMINATE SERVER' operational script, which will automatically delete the detached EBS volumes. If you terminate an instance using the "Terminate" action button in the Dashboard, the detached EBS volumes will not be deleted. You will need to manually delete them.
Import the RightScale Load Balancer with Apache/HAProxy - 11H1 ServerTemplate from the MultiCloud Marketplace (Design > MultiCloud Marketplace > ServerTemplates). Select the ServerTemplate for the 11H1 Compatibility Release. When possible, always read a ServerTemplate's description in the MultiCloud Marketplace. The descriptions contain helpful information.
Because you should not have to customize this ServerTemplate, there is no need to clone and rename it. Simply leave the Input values as they are, they will get set correctly later at the Deployment level.
Add two load balancers to your Deployment.
Tips:
Set the following inputs at the deployment level.
Application
Name | Description | Example Values |
APPLICATION | Enter the name of the application. | text: 3tier |
DNS
Name | Description | Example Values |
WEBSITE_DNS | The Fully Qualified Domain Name (FQDN) that the Application Servers accept traffic for. | text: my-www.example.com |
Load Balancer
Name | Description | Example Values |
HEALTH_CHECK_URI | Enter the relative path and filename of the health check HTML file. Technically the filename is arbitrary, but it must be a valid filename and it must be consistent across all Servers in your Deployment. This Input should also match the HTML file created in the custom RightScript used by the Application Server Array in this tutorial. Best practice dictates that the filename include random alphanumeric characters. For example, /hc871938741134.html. For simplicity sake, we use /hc.html in this tutorial. | text: /hc.html |
Launch both of your load balancers. There should be no missing Inputs, nor should you have to override any of the Inputs.
Once the load balancers are operational, your Deployment includes:
Before you create a server array that will serve as the application tier of the 3-tier deployment, you must first customize the ServerTemplate that you will use to launch each application server in the array. In this example, we're going to use a ServerTemplate for hosting a PHP application.
Go to Design > MultiCloud Marketplace > ServerTemplates. Find and import the PHP5 App Server – 11H1 ServerTemplate. If possible, read the ServerTemplate description.
After you import the ServerTemplate, clone it so that you can make changes to its scripts. Change the name of the ServerTemplate to something descriptive, perhaps including your initials or first name.
By default, the ServerTemplate is configured to pull the application code from an SVN repository. If you are using the example application in this tutorial, we instructed you to upload the example application to an S3 bucket. Because of this, you need to make a minor change to the ServerTemplate so that it can get the application code from this location. The next steps add a new RightScript to the ServerTemplate that checks out the application code from S3. The steps also delete the default RightScript that checks out the code from SVN.
Go to Design > MultiCloud Marketplace > RightScripts. Find and import the WEB Application s3 code checkout – 11H1 RightScript.
Add the script to your ServerTemplate as a Boot Script. Drag the new S3 code checkout script and place it before the WEB Application svn code checkout – 11H1 script. To do this, use the Arrow icon that appears on the right at the end of the script line to drag and drop the script into the appropriate position.
Delete the WEB Application svn code checkout – 11H1 script from the ServerTemplate.
Create a New RightScript
After you launch the all of the servers, we recommend you perform a quick test of the load balancers to see how incoming requests are sent to the application servers in a rotating fashion.
Important: It's important that the OPT_SESSION_STICKINESS input is set to "false" in order for the test to work properly. You will set this Input when you configure the Deployment's Inputs in a later step.
To perform the load balancing test, you need to create a new RightScript that installs a few basic HTML files that are used to test your load balancers. As always, try to name things in a descriptive manner (e.g. Load Balancer Test). In the script text box, copy and paste the following Bash code snippet:
#!/bin/bash -ex
cat > /home/webapps/$APPLICATION/current/hc.html << EOF
OK
EOF
cat > /home/webapps/$APPLICATION/current/servername.html << EOF
<html><body><center><h1>This is server <font color="blue">
EOF
cat /var/spool/ec2/meta-data/instance-id >> /home/webapps/$APPLICATION/current/servername.html
cat >> /home/webapps/$APPLICATION/current/servername.html << EOF
</font></h1></center></body></html>
EOF
After you paste the code into the script text box, click the Identify action button. You should see that one Input was discovered in the code called, APPLICATION, which is actually used by other scripts and is already defined at the Deployment level. As a best practice, whenever you create a new RightScript, you should provide a helpful tooltip description for the value that should be entered for an Input (e.g. “Name of the application”). Leave the “Value type” of the script set to “Any” so that you can enter a text value when setting the Input.
Look over the RightScript to make sure the formatting looks correct. Click Save when you are ready to save your new RightScript. Since you are testing this Deployment for the first time, do not commit the script and leave it as a HEAD version so that you can make changes later if necessary.
Add your new script as a Boot Script to your ServerTemplate. Since you are adding a private script that you have not published, you will be able to find the script using the 3-column selector under the “Unpublished” category. Place your new script before the LB Application to HAProxy connect – 11H1 boot script.
Important! The placement of your script before the LB Application to HAProxy connect – 11H1 script is critical.
The cloned ServerTemplate’s Scripts tab should look like the following screenshot.
Now that you've customized the ServerTemplate for your Application Servers to pull the application code from an S3 bucket and added a new script for testing the load balancers at the end of the tutorial, you are ready to create and configure a Server Array for horizontally auto-scaling the application tier.
First, you need to create a new alert-based Server Array. Go to Manage > Arrays and perform the following steps that follow.
Note: A Server Array must be associated with a particular Deployment; a Deployment can have multiple Server Arrays associated with it.
Click Save when ready.
Note: You should receive a message that your server array was successfully created. However, you may also receive a warning similar to the one that follows. Receiving this message is not a problem because you are going to clean up the remaining inputs soon.
"Some of the Input parameters for boot scripts are missing. Please update them to launch instances successfully."
Now that you’ve set up how the Server Array will automatically grow and shrink, the next step is to configure when the array changes size by defining the appropriate Alert specifications. There are actually two different ways to set up auto-scaling for this example. The most important thing to keep in mind is that any server that you think needs to be able to vote for grow/shrink actions must have the appropriate Alert specifications for triggering auto-scaling. Remember, a server can inherit Alert specifications from the ServerTemplate or Server Array levels. Because you might use the cloned application ServerTemplate in other Deployments, we’re going to add the Alert specifications at the Server Array level.
You need to add two new Alert specifications to trigger auto-scaling. Under the Server Array’s Next Alerts tab, you can add your new specifications to the existing Alert specifications that were inherited from the ServerTemplate. For this tutorial, you can use the suggested parameters that follow, but when you set up your own custom Deployment, you will want to pick appropriate metrics and thresholds that make sense for auto-scaling your own application.
The server array's Next Alerts tab should now list two new alerts and look like the following screenshot:
Important! Be sure to use the same values for inputs that you used when you set up the database servers.
Application
Name | Description | Example Values |
APPLICATION_CODE_BUCKET | Enter the name of the S3 bucket that contains the application code file. | text: myappbucket |
APPLICATION_CODE_PACKAGE | Enter the name of the file containing the application code. If you are using the example file provided in this tutorial, enter ‘myapp.tgz’ for this Input. | text:myapp.tgz
For the example 'world' database provided above, use the name of the .tar.gz file as downloaded from Github |
Cloud
Name | Description | Example Values |
AWS_ACCESS_KEY_ID | Select the predefined Credential for the AWS Access Key ID. | cred:AWS_ACCESS_KEY_ID |
AWS_SECRET_ACCESS_KEY | Select the predefined Credential for the AWS Secret Access Key. | cred:AWS_SECRET_ACCESS_KEY |
Database
Name | Description | Example Values |
DBADMIN_PASSWORD | Select the Credential you created for the password of the admin user in the database. | cred:DBADMIN_PASSWORD |
DBADMIN_USER | Select the Credential you created for the username of the admin user in the database. | cred:DBADMIN_USER |
DBAPPLICATION_PASSWORD | Select the Credential you created for the password of the application user in the database. | cred:DBAPPLICATION_PASSWORD |
DBAPPLICATION_USER | Select the Credential you created for the username of the application user in the database. | cred:DBAPPLICATION_USER |
DBREPLICATION_PASSWORD | Select the Credential you created for the password of the replication user in the database. | cred:DBREPLICATION_PASSWORD |
DBREPLICATION_USER | Select the Credential you created for the username of the replication user in the database. | cred:DBREPLICATION_USER |
DB_SCHEMA_NAME | Enter the name of the database schema. | text:myschema
For the example "world" database provided above, use the value:
text:world |
Load Balancer
Name | Description | Example Values |
LB_HOSTNAME | Enter the fully qualified hostname for your load balancers. In a previous step you created A Records with your DNS provider that point to your load balancers. | text:my-www.example.com |
OPT_SESSION_STICKINESS | Set the HAProxy session stickiness. Enter ‘true’ if you want the HAProxy to reconnect a session to the last server it was connected to. Enter ‘false’ if you want the HAProxy to establish a new session with the next available server. For this tutorial, set the stickiness to ‘false’ so that you can perform a test of the load balancers. | text:false |
Now that you have operational load balancers on the frontend that are ready to accept requests, and master and slave database servers on the backend, you are ready to start up the server array to run your application. Typically, you might want to launch a test server before you enable the entire array. The Launch action button allows you to manually launch a single server instance into an array. If you are using this tutorial as a learning tool, simply enable the server array.
Navigate back to the top level of your Deployment and select the server array name (this will be a hyperlink). Click the Enable action link on the Info tab (see the Status field). Because you set the Server Array’s Default Min Count to 2, two new servers will be automatically launched into the array. By default, resize actions are displayed in the Events pane. It may take a few minutes before the new servers are actually launched because RightScale's elasticity daemon evaluates server arrays every minute or so.
After you enable the array, the Events pane should show the two servers in your array coming up. You may have to wait a few minutes before the new servers are actually launched because RightScale's elasticity daemon evaluates server arrays every minute or so.
To quickly test your Deployment, open a browser and enter the main public URL for your Deployment. This URL is specified by the LB_HOSTNAME Input parameter and should be something like (http://my-www.example.com).
To see the Application Servers that are available to your Load Balancers, use SSH to log into one of the Load Balancer Servers and view the contents of the HAProxy configuration file. The configuration file is located on the servers at /etc/haproxy/haproxy.cfg.
In the RightScale Dashboard, navigate to your Deployment and click the SSH icon next to one of the Load Balancer Servers. After you are connected to the server, go to the /home/haproxydirectory (cd/home/haproxy). Use the less command to view the contents of the rightscale_lb.cfgfile (less rightscale_lb.cfg).
Scroll to the bottom of the file using the spacebar. You should see entries similar to the following for each application server in the load balancer pool.
server i-9c8859f1 10.203.85.169:8000 check inter 3000 rise 2 fall 3 maxconn 255
server i-8a8859e7 10.204.97.84:8000 check inter 3000 rise 2 fall 3 maxconn 255
Note: The file maps the AWS ID of the servers in the array to their internal, private IP addresses. If you examine the private IP addresses, you can see that traffic to these servers is routed over port 8000 (10.203.85.169:8000). To allow communication between servers, this port must be open in the Security Group to which the Server Array belongs. For the purposes of this tutorial, that’s not important since all servers are in the same Security Group and can talk to each other because you added the Security Group to itself. However, if you required additional security, you might need to take this fact into consideration. For example, you might want to create separate Security Groups for each layer in your architecture (e.g. load balancers, application servers, and database servers). This approach provides additional control and server isolation. For more information, see Configuring Multiple Security Groups for a Multi-Tiered Deployment.
You can use the HAProxy Status page to check the status of the Application Servers in the load balancing pool. The page is located off of the main URL for the Deployment at haproxy-status (e.g. http://my-www.example.com/haproxy-status).
When you access the page, you will see the Application Servers in the pool. The load balancers will only establish client connections with "green" application servers that have passed the health check test (HEALTH_CHECK_URI). Application servers that are highlighted in "red" will not receive any traffic because it is not in a serviceable state. For example, the server is still booting up or it was unable to properly connect to the load balancer servers because the firewall permissions are not set up properly.
Note: The operational servers shown in the status table should have the same server IDs displayed in the servername.html page that you checked earlier.
Use the following instructions to verify that your Load Balancer Servers are properly sending requests to the Application Servers in your Server Array in a round-robin fashion.
Earlier in the tutorial you created a RightScript to install the servername.html page on each of the Application Servers in the Server Array (see Create and configure a scalable Server Array). This is a simple page that shows which server in the array is responding to the request. The servername.html page is located directly off of the main URL for your Deployment and should be something like http://my-www.example.com/servername.html.
To test that your load balancing is working correctly and that requests are being sent to each of the servers in your array, open a browser and access the servername.html page. The page displays the unique AWS ID for the server responding to the request. Take note of the ID and then refresh your browser. Again take note of the server ID.
You should see that each page request gets handled by a different server in the array. For example, if you had two servers in the array, you might see something like the following:
This test confirms thatrequests are getting routed through your Load Balancers and that responses are coming back from your Application Servers in round-robin fashion.
Note: Due to some differences in how some browsers cache pages, it's recommended that you perform this test using Firefox.
You can also perform a quick test using SSH to see which application servers are connected to your load balancer.
/etc/haproxy/haproxy.cfg
At the Deployment's show page, click on the SSH icon next to one of the load balancers.
Type the following UNIX commands:
cd /home/haproxy/
less rightscale_lb.cfg
server i-9c8859f1 10.203.85.169:8000 check inter 3000 rise 2 fall 3 maxconn 255
server i-8a8859e7 10.204.97.84:8000 check inter 3000 rise 2 fall 3 maxconn 255
This shows a mapping of the Resource ID of the array servers with their Internal, Private IP Address. You can see that traffic to these servers is routed over port 8000. Hence this port must be open in the security group that the server arrays belong to. For the purposes of this tutorial that's not important, since all servers are in the same security group and can talk to each other as we added the security group to itself. However, if you required additional security, you might need to take this fact into consideration. For example, you might want to create separate security groups for each layer in your site architecture (e.g. load balancers, application server, database servers) for additional control and server isolation. See Configuring Multiple Security Groups for a Multi-Tiered Deployment.
Follow the Adding Httperf Load Tester tutorial to launch an HTTP Perf Server that you can use to send traffic to your Deployment and trigger a scale up action that will launch additional Application Servers into the Server Array. When you run the script to send traffic, be sure to set the PERF_SERVER1 Input parameter to the main URL for your Deployment (my-www.example.com).
After a few minutes of running the traffic generating script, you should start to see a scale up action in the Events pane of the RightScale Dashboard. The Events will show additional servers being added to the Server Array. Likewise, when you stop the traffic generation script, the Events pane will show servers being terminated as the array scales down.
Time and interest permitting, SHH into the Master Database Server and view the contents of the database manually. To do this, use the MySQL commands in the graphic below.
Note: Remember to use your database schema name, which may not be “photo_demo_production” as seen in the following screenshot.To check if the database is communicating with the Application Server correctly, create a new RightScript called ‘3TierTestScript’ and copy and paste the following PHP.
#!/bin/bash -ex cat > /home/webapps/$APPLICATION/current/3tier.php << EOF <html> <head> <title>Application Node and MySQL Table Viewer</title> </head> <body bgcolor="#C0C0C0"> <center><h1>Instance Resource ID: <font color="blue"> EOF cat /var/spool/ec2/meta-data/instance-id >> /home/webapps/$APPLICATION/current/3tier.php cat >> /home/webapps/$APPLICATION/current/3tier.php << EOF </font></h1> EOF cat >> /home/webapps/$APPLICATION/current/3tier.php << EOF <center><h1>Availability Zone: <font color="blue"> EOF cat /var/spool/ec2/meta-data/placement-availability-zone >> /home/webapps/$APPLICATION/current/3tier.php cat >> /home/webapps/$APPLICATION/current/3tier.php << EOF </font></h1> EOF cat >> /home/webapps/$APPLICATION/current/3tier.php << EOF <center><h1>Security Group(s): <font color="blue"> EOF cat /var/spool/ec2/meta-data/security-groups >> /home/webapps/$APPLICATION/current/3tier.php cat >> /home/webapps/$APPLICATION/current/3tier.php << EOF </font></h1> <h1>Below is the contents of the Database</h1> <?php \$dbhandle = mysql_connect("$MASTER_DB_DNSNAME", $DBADMIN_USER, $DBADMIN_PASSWORD); if (!\$dbhandle) { die('Could not connect: ' . mysql_error()); } mysql_select_db("$DB_SCHEMA_NAME", \$dbhandle); \$result = mysql_query("SELECT * FROM phptest"); ?> <table border='1'> <tr> <th>ID</th> <th>Firstname</th> <th>Lastname</th> </tr> <? while(\$row = mysql_fetch_array(\$result)) { echo "<tr>"; echo "<td>" . \$row['id'] . "</td>"; echo "<td>" . \$row['firstname'] . "</td>"; echo "<td>" . \$row['lastname'] . "</td>"; echo "</tr>"; } echo "</table><br/>"; mysql_close(\$dbhandle);?> <form action="insert.php" method="post" style="width:440px;"> <fieldset> <legend>Add a Record</legend> ID: <input type="text" name="id"><br> Firstname: <input type="text" name="firstname"><br> Lastname: <input type="text" name="lastname"><br> <input type="Submit"> </fieldset> </form><br/> <form action="delete.php" method="post" style="width:440px;"> <fieldset> <legend>Remove a Record</legend> ID: <input type="text" name="id"><br>\ <input type="Submit"> </fieldset> </form> </center> </body> </html> EOF cat > /home/webapps/$APPLICATION/current/insert.php << EOF <?php \$dbhandle = mysql_connect("$MASTER_DB_DNSNAME", "$DBADMIN_USER", "$DBADMIN_PASSWORD"); if (!\$dbhandle) { die('Could not connect: ' . mysql_error()); } mysql_select_db("$DB_SCHEMA_NAME", \$dbhandle); \$sql="INSERT INTO phptest (id, firstname, lastname) VALUES ('\$_POST[id]','\$_POST[firstname]','\$_POST[lastname]')"; if (!mysql_query(\$sql,\$dbhandle)) { die('Error: ' . mysql_error()); } echo "1 record added"; echo "<br />"; echo "<a href=\"3tier.php\">Click here to return to previous page.</a>"; mysql_close(\$dbhandle); ?> EOF cat > /home/webapps/$APPLICATION/current/delete.php << EOF <?php \$dbhandle = mysql_connect("$MASTER_DB_DNSNAME", $DBADMIN_USER, $DBADMIN_PASSWORD); if (!\$dbhandle) { die('Could not connect: ' . mysql_error()); } mysql_select_db("$DB_SCHEMA_NAME", \$dbhandle); \$sql="DELETE FROM phptest WHERE id = ('\$_POST[id]')"; if (!mysql_query(\$sql,\$dbhandle)) { die('Error: ' . mysql_error()); } echo "1 record deleted"; echo "<br />"; echo "<a href=\"3tier.php\">Click here to return to previous page.</a>"; mysql_close(\$dbhandle); ?> EOF
After you've pasted this into the RightScript, click the Identify action button to retrieve the Inputs.
Then click the Save action button.
When you are ready, click the Save action button to save the new script.
Now go back to your Deployment and access the attached Server Array. Under the array’s Scripts tab, use the Any Script option to run the new RightScript on all the servers in the array. Select the script entitled “3TierTestScript” from within the Unpublished section. When prompted for the servers that you want to run the script against, select the run on all action button. The script reuses the Inputs that you've already defined so the appropriate credentials and values are automatically pre-selected on the Input confirmation screen. Click the Run action button to run the script.
Open a browser and access the 3tier.php page off of the main URL for the Deployment (e.g. my-www.example.com/3tier.php). After you access the page, refresh your browser a few times. With each refresh you should see a simple page that shows the Application Server in the array that is responding to the request as well as the contents of the database. Enter some new entries to the database and you should see the user table reflect your additions.
Go to Shutting Down a Multi-tiered Deployment to review best-practice considerations for shutting down multi-tiered deployments such as the one created in this tutorial.
Go to Starting up a Multi-tiered Deployment to review best-practice considerations for starting up multi-tiered deployments such as the one created in this tutorial.
You may find the need to perform some clean up, either to minimize costs, or to perform the tutorial again from a clean slate. Follow these high level steps to do so:
·
© 2006-2014 RightScale, Inc. All rights reserved.
RightScale is a registered trademark of RightScale, Inc. All other products and services may be trademarks or servicemarks of their respective owners.