To create a 3-tiered production-like deployment from scratch using ServerTemplates published by RightScale for a Tomcat application.
Note: The tutorial uses RightScale's latest revisions of the v13 Infinity ServerTemplates that use Chef cookbooks and recipes instead of RightScripts.
Table of Contents
Although this end-to-end tutorial was originally designed as a hands-on exercise in an Instructor Led Training course, anyone can follow the tutorial and use it as a learning tool as well. The class environment influences naming conventions, hence we often precede names with initials or names in our examples. (For example, an A Record for John Doe named "jd-www", rather than simply "www"). Be sure to provide enough time for yourself to complete the end-to-end exercise. (Estimate: 1-3hrs)
This tutorial will demonstrate how to build a common 3-tier website architecture in the cloud using some of RightScale's ServerTemplates.
Disclaimers
It's recommended that you create a new deployment (Manage > Deployments) for each new project or reference architecture that you're going to build because you do not want to accidentally inherit any unknown configuration settings.
See Create a New Deployment. (Requires 'actor' user role privileges.)
Tip: It's recommended that you create a bookmark to the deployment's Servers tab for quick navigation back to the deployment at any time.
Prerequisites: Requires 'actor' user role privileges in the RightScale account to create SSH Keys and Elastic IPs, and 'security_manager' privileges to create/modify security groups.
Each cloud infrastructure is unique and requires different resources in order to launch a server in their cloud. Depending on the type of cloud infrastructure that you're going to use to launch servers, you will find it useful to create some of the required cloud-specific resources beforehand so that you can select them in the "Add Server Wizard" when you add servers into a deployment. Some cloud resources are also region-specific. For example, you cannot launch an EC2 instance in the 'us-east' region with a 'us-west' security group.
If the cloud does not require the use an SSH Key, you can ignore this step.
SSH Keys are used for authentication purposes to create SSH console sessions for root level access to the instance. Although you are required to associate an SSH Key to a server before you can launch it, the private key material is no longer required if managed SSH (Server Login Control) is enabled for the account (Settings > Account Settings > SSH). By default, Server Login Control is enabled at the account level, where a user's own unique RSA key pair (Settings > User Settings > SSH) is used for authentication purposes for establishing SSH console sessions on all RightLink-enabled instances.
You can either use an existing SSH Key or create a new one.
If the cloud does not support Security Groups, you can ignore this step.
Security groups are firewall settings that apply to instances within a cloud at the infrastructure layer. Security groups are typically used to control ingress communication (i.e. inbound communication to an instance over a particular port and protocol) however, some clouds support the use of security groups to also control egress communication (i.e. outbound requests from the instance). Once you create a security group you can create different firewall rules that control the level of access to instances launched with that particular security group(s). Firewall rules are enforced at the cloud (infrastructure) level using IP-based or Group-based permissions.
If you are building this deployment for demonstration and testing purposes, you can simply create a single security group for all servers in your deployment.
The steps for creating a single security group are different depending on the type of account and cloud that you are using.
Once you are successful setting up your first multi-tier deployment you can set up more secure firewall permissions that would be more realistic for production environments. See Configuring multiple Security Groups for a multi-tiered Deployment.
Some clouds support the use of public IP addresses that you can associate with a server at launch time or remap to another running server, as necessary for lifecycle management scenarios. It's recommended that you use this service, if available for front-end load balancer or web servers that are designed to be public facing. If you're using dedicated HAProxy load balancer servers, you should create/reserve one IP address for each load balancer server. Typically, you will have two HAProxy load balancer servers for high-availability and failover purposes. If you are using a cloud's load balancing service such as Amazon Elastic Load Balancers (ELB) or Rackspace Cloud Load Balancers (CLB) you cannot assign remappable IP addresses. In such cases, skip this step.
In a typical 3-tier architecture setup, DNS A records are used to create fully qualified domain names (FQDNs) that map to a particular server or tier of servers. The diagram below shows a typical example of a 3-tier website architecture.
In this type of architecure, the application servers and any "slave" database servers locate the "master" database server by using Master-DB's FQDN (e.g. db-master.example.com), which points to the Master-DB's private IP address. Similarly, front-end web traffic can be routed to a FQDN (e.g. www.example.com) where each load balancer server has a DNS record for that FQDN so that incoming requests are routed to one of the load balancer servers. Since the IP address of an instance in the cloud is often dynamically assigned at launch time, you are required to use a DNS provider that supports dynamic DNS (i.e. the ability to dynamically update the IP address of an A record) for the Master-DB server (at a minimum). You can also use the same DNS provider for creating FQDNs for the load balancer servers. However, since they do not require the use of dynamic DNS, any DNS provider can be used.
TTLs
When you create the DNS records, it's important to set appropriate TTLs to ensure that servers will not stay connected to an old IP address that is no longer assigned to a functional server. For example, the DNS record that points to the "master" database server should have a low TTL to ensure that the application servers will connect to the correct server within a reasonable amount of time. It's strongly recommended that you use a TTL of 60 seconds for the DNS record that points to the "master" database server. If you are also creating DNS records for the front-end load balancer servers, you can use a more conservative TTL than the database tier. (e.g. 1800 seconds)
Note: If you are using Rackspace's Cloud DNS service, you must use a TTL of 300 seconds because that is the lowest allowable TTL. Be sure to change the 'Database DNS TTL Limit' input from 60 (default) to 300.
You will need to create DNS records for the following servers:
RightScale's ServerTemplates contain scripts that support one of the following DNS providers. Create an account with one of the DNS providers below and set up the A records accordingly.
Prerequisites: Requires 'designer' user role privileges in the RightScale account to create a new credential.
Important!
Only the user who created the credential and any 'admin' users will be able to view and modify an existing credential.
Credentials are a way of passing sensitive information to a script (as an input) in a discrete manner without making the actual value visible in the Dashboard. As a best practice, many of the ServerTemplates published by RightScale are preconfigured to use certain credentials. It's recommended that you create these common credentials in your own account. If they already exist and apply to a different deployment, you might want to create a new set of credentials to avoid any conflicts. In such cases, it's helpful to use a common prefix to group the credentials together. (e.g. APP1_DBADMIN_USER)
If you try to launch a server where one of the inputs references a credential that does not exist in the RightScale account, you will receive an error message and will not be able to launch the server. Therefore, it's best to create any required credentials before you configure and launch a server. Depending on your cloud provider and backup storage selections, you may want to create additional credentials.
At a minimum, create the following credentials. See Create a New Credential for more information.
If you are going through a 3-tier tutorial you should create the following credentials with your own values or you can use the example values, if desired.
* If you use Amazon Route 53 or Rackspace Cloud DNS as your DNS provider, you do not need to set up separate DNS user name and password credentials because your cloud credentials are used for authentication purposes.
ServerTemplates published by RightScale have built-in support for several remote object storage (ROS) solutions. Valid cloud credentials are required to retrieve "private" files from an ROS container, create a new container, or store files in a container (such as a binary database backup files).
Set up your desired ROS service(s) and create the recommended user-defined credentials, which you will use when you define inputs for your deployments.
If you are using a source control management (SCM) system to host your application code, you will need to create the appropriate credentials to retrieve your source code from the specified repository.
You can also download application source code from rsync sources.
If you are using SSL to support HTTPS access, you should create credentials for any of the following values that apply. See How do I create an SSL certificate for my web server?
If you are using the public network to connect to the master database server, it's recommended that you use SSL to encrypt the data being transfered between the master database server and the associated slave and/or application servers. Note: SSL is currently only supported in the Database Manager for MySQL 5.1/5.5 ServerTemplates.
If you are setting up a database server for testing purposes or if you do not have your own dump file, you can use the following sample MySQL dump file to complete the tutorial. The sample is a bzip2 compressed file (.bz2) file.
Follow these steps to add a database server to the deployment.
The following inputs should be set at the deployment level. Go to the deployment's Inputs tab (Manage > Deployments > your deployment > Inputs) and click Edit.
Although you can enter values for missing inputs as text values, it's strongly recommended that you set up credentials for passing sensitive information to scripts such as passwords or any other sensitive data.
Required
Input Name | Description | Example Value |
Backup Lineage | The prefix that will be used to name/locate the backup of the MySQL database server. | text: mysql_test_lineage |
Device Count | The number of devices to create and use in the Logical Volume. | text: 2 |
Device Volume Size | Size of the volume or logical volume to create (in GB). | text: 10 |
Backup Schedule Enable | Enable or disable periodic backup schedule. | text: true |
Backup Schedule Hour | The hour to schedule the backup on. This value should abide by crontab syntax. Use '*' for taking backups every hour. | text: * |
Backup Schedule Minute | The minute to schedule the backup on. This value should abide by crontab syntax. | text: 30 |
MySQL Root Password | The root password for MySQL server. | cred: MYSQL_ROOT_PASSWORD |
Advanced
Input Name | Description | Example Value |
MySQL Database Name | The name of the application database. | text: app_db |
MySQL Application Password | The password of the application database user. The Application Username and Password will allow access to the database in a restricted fashion. | cred: MYSQL_APP_PASSWORD |
MySQL Application Username | Username to access the application database. | cred: MYSQL_APP_USERNAME |
MySQL Database FQDN | The fully qualified domain name of the MySQL master database server. | text: db.example.com |
DNS Secret Key | The secret key to access/modify the DNS records. In our example, this will be set to the ‘Secret Key’ from DNSMadeEasy. | cred: DNSMADEEASY_SECRET_KEY |
DNS User Key | The user key to access/modify the DNS records. In our example, this will be set to the ‘API Key’ from DNSMadeEasy. | cred: DNSMADEEASY_API_KEY |
Import Filename | Filename of the database dump file to import. | text: dumpfile_20140102.gz |
Import Secret Key | The private key to access the repository via SSH. | cred:DB_IMPORT_GIT_KEY |
Import Repository URL | The repository location containing the database dump file to import. | text: git://example.com/dbfiles/database_dumpfiles.git |
MySQL Slave Replication Password | The replication password set on the master database and used by the slave to authenticate and connect. If not set, ‘MySQL Root Password’ will be used. | cred: MYSQL_REPLICATION_PASSWORD |
After configuring your deployment inputs, launch your newly configured master database server.
Go to the deployment's Servers tab and launch the database server. When you view the input confirmation page, there should not be any missing values (highlighted in red) for inputs that are required by any of the server's boot scripts. If there are any inputs highlighted in red, cancel the launch and add the missing values at the deployment level before launching the server again. Refer to the instructions in Launch a Server if you are not familiar with this process. Click the Launch (not 'Save and Launch') button at the bottom of the input confirmation page.
Wait for the server to reach the "operational" state before proceeding. To view the status of a script run, go to the “current” server’s Audit Entries tab. Go to the “current” server’s Scripts tab, look in Operational Scripts, and run the following scripts, in order, to initialize the master database server.
It is strongly recommended to not run scheduled backups on your ‘master’ database server. Backups involves locking the database and freezing the filesystem. This will usually cause issues with applications writing to the database. Backups should only be done on the ‘slave’ database servers.
Since the Master-DB is up and running, and an initial backup was made, one more input should be set at the deployment level to be used by new Slave-DB servers. Go to the deployment's Inputs tab (Manage > Deployments > your deployment > Inputs) and click Edit.
Required
Input Name | Description | Example Value |
Restore Lineage | The lineage name to restore backups. | text: mysql_test_lineage |
Create a slave server in your deployment.
Make sure the following conditions are true before you launch the second database server.
Because the inputs are configured in the deployment level for slave database servers, there is no need to alter the inputs.
Go to the deployment's Servers tab and launch the “slave” database server. When you view the input confirmation page, there should not be any missing values (highlighted in red) for inputs that are required by any of the server's boot scripts. If there are any inputs highlighted in red, cancel the launch and add the missing values at the deployment level before launching the server again. Refer to the instructions in Launch a Server if you are not familiar with this process. Click the Launch (not 'Save and Launch') button at the bottom of the input confirmation page.
Wait for the server to reach the "operational" state before proceeding. To view the status of a script run, go to the “current” server’s Audit Entries tab. Go to the “current” server’s Scripts tab, look in Operational Scripts, and run the following scripts, in order, to initialize the slave database server.
Periodic backups should be done on a slave database since locking a slave database for writing should have little or no impact on applications that should be accessing the master database. Once the backup completes, the filesystem is unfrozen, and the databases is unlocked, the slave database will catchup with the master.
If you want to test the status of the "master" and "slave" database servers, see Check Database Status of Master or Slave.
Follow these steps to add a load balancer server to the deployment.
For production environments, it's strongly recommended that you have at least two load balancer servers (preferably in different availability zones or datacenters) for redundancy purposes. The easiest way to create a second load balancer is to simply clone and modify the first load balancer server.
The next step is to define the properties of your load balancer server or servers by entering values for inputs. As a best practice, you should define required inputs for the servers at the deployment level. For a detailed explanation of how inputs are defined and used in Chef recipes and RightScripts, see Inputs and their Hierarchy.
To enter inputs for the Chef recipes that will run on your load balancers, open the deployment's Inputs tab, click Edit, and use the following settings to configure input values. We recommend that you set up credentials for password values and any other sensitive data as shown in the examples.
Input Name | Description | Example Value |
Load Balance Pools | Comma-separated list of URIs or FQDNs for which the load balancer will create server pools to answer website requests. The last entry will be the default backend and will answer for all URIs and FQDNs not listed here. A single entry of any name (for example, default) will mimic basic behavior of one load balancer with one pool of application servers. This will be used for naming server pool backends. Note: Application servers can provide any number of URIs or FQDNs to join corresponding server pool backends (for example, www.mysite.com, api.mysite.com, /serverid, default). | text: www.mysite.com, api.mysite.com
For the standalone and 3-tier tutorials, use: text:default |
Load Balancing Algorithm | Defines which load balancing algorithm is used to establish connections with application servers in the load balancing pool.
| text: roundrobin |
Use Session Stickiness | Determines session stickiness. Set to 'True' to use session stickiness, where the load balancer will reconnect a session to the last server it was connected to (via a cookie). Set to 'False' if you do not want to use sticky sessions; the load balancer will establish a connection with the next available server. | text: true |
HAProxy SSL Certificate | PEM formatted string containing SSL certificates and keys for SSL encryption. To configure HAProxy without SSL encryption, do not set this input. | nil |
Statistics Page Password | Password to access HAProxy statistics page | nil |
Statistics URI | HAProxy statistics URI | text: /haproxy-status |
Statistics Page Username | The username that is required to access the load balancer statistics report page | nil |
If you are using Elastic IPs or already know the public IP addresses that will be used by the load balancer servers, you might have already set up the DNS records for the load balancing tier. However, if you do not know the public IP addresses that will be assigned to the load balancer servers, you must manually set up the DNS records after the servers have been launched. Once the servers become operational (and have been assigned their respective public IP addresses), create or update the DNS records with your DNS provider. Each load balancer server should have its own DNS record with the same hostname (e.g. www.example.com) that points to its public IP address.
The DNS records for the HAProxy load balancing tier should direct traffic from the associated hostname (FQDN) (e.g. www.example.com) to the application servers in its load balancing pool.
PHP App Server (v14 Infinity) - Tutorial
If you need an example application for testing purposes, you can use the application code from the following git repository.
Follow these steps to add an application server to the deployment.
The next step is to define the properties of your application server by entering values for inputs. It is best to do this at the deployment level. For a detailed explanation of how inputs are defined and used in Chef recipes and RightScripts, see Inputs and their Hierarchy.
To enter inputs for the Chef recipes that will run on your application servers, open the deployment's Inputs tab and click Edit, then follow the directions below to configure input values. We recommend that you set up credentials for password values and any other sensitive data as shown in the examples.
Note: Some inputs referenced in this tutorial are considered "advanced" are not initially displayed in the Dashboard. If you are unable to find an input in the Dashboard, be sure to use the "Show advanced inputs" option to view all related inputs of a particular input category.
Important! The ServerTemplate supports multiple configuration permutations. Read each input description carefully. You must provide appropriate values depending on your chosen configuration.
Input Name | Description | Example Value |
Database Schema Name | Enter the name of the database schema to which applications will connect to. The database schema should have been created when the initial database was first set up. This input will be used to set the application server's database configuration file so that applications can connect to the correct schema within the database. This input is also used for database dump backups in order to determine which schema will be backed up. | text: db_schema_name
For the 'app_test-201109010029.gz' MySQL dump file: text: app_test |
Application IP Type Given to Load Balancer | Specify the type of IP address that the application service will listen on. Before making this selection, make sure your firewall permissions are properly configured to accept requests on its public or private IP address.
| text: private |
Application Listen Port | The port that the application service listens on to accept requests from the load balancer. If you specify another port than the 8000 (default), be sure to add the port to the "Firewall Rule Port" input and make sure that the security group's settings also allow access (if applicable). | text: 8000 |
Many of the Tomcat-specific inputs have default values. Click the "Show advanced inputs" to view all of the inputs.
Input Name | Description | Example Value |
War file for ROOT | The full path, including filename, to the source application WAR file relative to the project root directory, which is defined by the 'Project App root' input (default /home/webapps/<app_name>). The retrieved WAR file will be renamed ROOT.war and placed into the 'Project App Root' directory. | text: /path/to/app.war For the provided sample application: |
Input Name | Description | Example Value |
Database Application Password Database Application Username | Database username and password to add to the MySQL database server for application access. | cred: DBAPPLICATION_USER cred: DBAPPLICATION_PASSWORD |
Database Master FQDN | Fully qualified domain name for the master MySQL database server. Application servers use this input to locate the "master" database server. | text: master-db.example.com |
Database Provider type | The type of database that the application will connect to on the client side. Select one of the predefined options in the dropdown menu or use the "Override" option to specify a custom option. The value must be a string that contains the name of the cookbook that contains the matching provider resource and version of the database (optional).
| text: db_mysql_5.5 |
Input Name | Description | Example Value |
Load Balance Provider | Select the type of load balancer (or service) that the application server(s) will connect to.
| text: lb_client |
Load Balance Pools | Specify the load balancing pool(s) to which the application server belongs. Typically, an application server will belong to one load balancing pool, however an HAProxy load balancing server can service multiple pools. An application server can also connect to multiple load balancing pools, if desired. Specify the load balancing pool that the application server will connect to or disconnect from by using one of the following types:
| text: default |
Load Balance Service ID Load Balance Service Secret | For CLB, specify the Rackspace username and API key to use for authentication purposes. For ELB, specify the Amazon access key ID and secret access key for authentication purposes. Note: For HAProxy, aiCache, and other load balancers launched with ServerTemplates, set to 'ignore'. | cred: RACKSPACE_USERNAME cred: AWS_ACCESS_KEY_ID |
Load Balance Service Name | The name of the Amazon Elastic Load Balancer (ELB) or Rackspace Cloud Load Balancer (CLB). Note: For HAProxy, aiCache, and other load balancers launched with ServerTemplates, set to 'ignore'. | text: my-lb-name |
Load Balance Service Region | Note: Input only applies to a Rackspace Cloud Load Balancer (CLB). For a CLB, select the Rackspace region of the Cloud Load Balancer. It's recommended that you create your CLB in a region as close to your application servers as possible.
| text: ORD |
The values that you use for the repository inputs will depend on where the application code will be retrieved from. The selection for the Repository Provider input will determine which inputs will be used to retrieve the application. Unrelated inputs are ignored.
The following inputs are used to retrieve the application from either a Git/SVN software repository or an ROS location. Specify the appropriate inputs based upon the selection for the 'Repository Provider' input.
Input Name | Description | Example Value |
Repository Provider | Specify where the application code should be checked out from.
| text: repo_ros For the provided sample application: |
Repository URL/ROS Container | The name of the Remote Object Storage (ROS) container where a tarball (.tgz) of the application code will be retrieved from or the URI that points to the location of the application code repository.
| text: my-container For the provided sample application: |
Project App root | The destination location where the application code will be placed on the local instance. If you want the application code to be placed in the root directory, use a forward slash (/) otherwise you will need to specify the full path (e.g. /path/to/code). If set to 'ignore' the default location (/home/webapps) will be used. The 'Application Name' input is used to name the destination folder into which the application code will be placed (e.g., /home/webapps/my_app/). Apache and Tomcat will look for the application in this path. | text: /home/webapps For the provided sample application: |
Action | Specify how the application code will be pulled from the specified repository.
| text: pull For the provided sample application: |
Known Hosts SSH Key | Use the credential you created earlier in the tutorial. This input will allow verification of the destination host by comparing its IP, FQDN and SSH-RSA with the record in the /root/.ssh/known_hosts file. This input provides improved security by preventing MiTM attacks. | cred:SSH_KNOWN_HOST_KEY |
Important!
If you are checking out code from a Git repository, specify values for the following inputs.
Input Name | Description | Example Value |
Account credential | In order to check out application code from a private (not public) Git repository, you must provide the repository's SSH key (e.g. Git SSH Key) for authentication purposes. Set to 'ignore' if you are using an application in a repository that allows 'public-read' access. | cred: GIT_SSH_KEY For the provided sample application: |
Repository Branch/Tag/Commit | The specific branch/tag/SHA of the specified Git repository that the application code should be checked out from. (e.g. mybranch) Use "master" to retrieve the master branch from the repository. | text: mybranch For the provided sample application: |
Important!
If you are checking out code from a SVN repository, specify values for the following inputs.
Input Name | Description | Example Value |
Account name | The username and password required to access and retrieve the application code from the specified SVN repository. | cred: SVN_USER cred: SVN_PASSWORD |
Repository Branch/Tag/Commit | The specific branch or tag of the specified SVN repository that the application code should be checked out from. (e.g. mybranch) Use "trunk" to retrieve the main branch from the repository. | text: mybranch |
Important!
If you are checking out code from a Remote Object Storage (ROS) location, specify values for the following inputs.
Input Name | Description | Example Value |
ROS Prefix | The prefix that will be used to locate the correct tarball of the application. For example, if you're using 'myapp.tgz' specify 'myapp' as the ROS Prefix. | text: myapp |
Account name | In order to retrieve a tarball of the application code that's a "private" object within the specified Remote Object Storage (ROS) location, you must provide proper cloud authentication credentials. For security reasons, it's recommended that you create and use credentials for these values instead of entering the text value.
| text: AWS_ACCESS_KEY_ID |
Account credential | In order to retrieve a tarball of the application code that's a "private" object within the specified Remote Object Storage (ROS) location, you must provide proper cloud authentication credentials. For security reasons, it's recommended that you create and use credentials for these values instead of entering the text value.
| cred: AWS_SECRET_ACCESS_KEY |
ROS Storage Account Provider | The Remote Object Storage (ROS) service where the tarball of the application code will be retrieved from.
| text: s3 |
Input Name | Description | Example Value |
Application Name | On your application servers, the server subdirectory where your application code files are stored. If you are using dedicated load balancer servers launched with RightScale's "Load Balancer with HAProxy" ServerTemplate, this value must match the Application Name input for your load balancer servers. | text: myapp |
Multi-Processing Module | Set to "worker" for a Tomcat application server. | text: worker |
After configuring your inputs, launch all of the Tomcat application servers. Refer to the instructions in Launch a Server if you are not already familiar with this process.
Once all of the servers are operational you can perform the following tests.
If you set up your DNS records and firewall permissions (e.g. security groups) correctly, incoming web requests to your hostname (e.g. www.example.com) will be sent to one of the load balancer servers. HAProxy will then take the request and forward it to one of the application servers in its load balancing pool.
Based on your DNS records, enter the hostname (FQDN) associated with your load balancer servers into a browser window. (e.g. www.example.com) You should see your application's default landing page. If you are using the sample PHP application from RightScale, you should see the following landing page.
To perform a standard health check test to make ensure proper communication between HAProxy load balancers and the application servers in its load balancing pool, see the Perform a Health Check Test tutorial.
To replace the static application servers in the deployment (under the deployment's Servers tab) with a scalable server array for dynamically autoscaling the application tier, follow the Add a Scalable Application Server Array to a Deployment tutorial.
If you completed the tutorial for testing purposes and no longer need the running servers, follow the steps below to safely shutdown the deployment.
© 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.