Deploying web applications using Juju on EC2 (Part 1/3)

Canonical

on 26 September 2013

Tags: Tutorial

This article was last updated 8 years ago.


The goal of this tutorial series is to demonstrate the power of Juju service orchestration for deploying web applications and infrastructure services in the cloud, in this case on Amazon EC2.

Juju is a service orchestration framework that is designed to make it very easy for application designers to deploy their applications in an easy, repeatable and logical manner without all that tedious mucking about with custom configuration files and logging in to servers.

The key differentiation with Juju is that it focuses on “Services” and their “Relationships”, not on individual servers or configurations, like a typical configuration management tool would.

Setting up Juju-core

Juju-core is now the latest version of Juju that is recommended for testing and development and is fast approaching its 2.0 release. Currently (September 2013) we are on release version 1.13.3 and most of the functionality is available for deploying to EC2 and Openstack clouds.

I will assume that you already have access to an Ubuntu Desktop or Server machine running the latest version of Ubuntu 13.04, the Raring Ringtail release.  Although, the same steps can be carried out on any release from 12.04 LTS onwards.

So, let’s set up our Juju environment for Amazon EC2.

On your Ubuntu Desktop or Server run the following commands at the terminal:

sudo apt-get -y install python-software-properties
sudo add-apt-repository ppa:juju/stable
sudo apt-get update && sudo apt-get install juju-core

To generate an initial config file, you simply need to run:

juju init

This command will cause a file to be written to your ~/.juju directory if an environments.yaml file does not already exist. It will also create the ~./juju directory if that does not exist.

The contents of this file will look something like this:

## https://juju.ubuntu.com/get-started/amazon/
amazon:
type: ec2
admin-secret: 989b97c439357947449d994720
# globally unique S3 bucket name
control-bucket: juju-a28403f89d8245543d3cab01f1ca4a3e
# override if your machine is on a different series than what you're deploying
# default-series: precise
# region defaults to us-east-1, override if required
# region: us-east-1
# Usually set via the env variable AWS_ACCESS_KEY_ID, but can be specified here
# access-key:
# Can be set via the env variable AWS_SECRET_ACCESS_KEY, or specified here
# secret-key:

Values for the default setting can be changed simply by editing this file, uncommenting the relevant lines and adding your own settings. All you need to do to get this configuration to work is to either set the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY via environment variables, or uncomment and add the values to the configuration file.

You also want to create your own admin-secret as this is used to gain access to your environment on EC2 and so it should be a strong password of your own.  The control bucket needs to be globally unique, so you should not use this one, but also create your own unique name.

You can retrieve your AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY easily from your AWS Management Console at http://console.aws.amazon.com. Click on your name in the top-right and then the “Security Credentials” link from the drop down menu.

Under the “Access Keys” heading click the “Create New Root Key” button. You will be prompted to “Download Key File” which by default is named rootkey.csv. Open this file to get the access-key and secret-key for the environments.yaml configuration file.

You must also have an SSH key installed under the current users ~/.ssh/ directory. If you haven’t already got an SSH key, then generate one with:

ssh-keygen -t rsa -b 2048

If you are on an Ubuntu version that is not Precise Pangolin (i.e. 12.04 LTS) then uncomment the default-series value.

Then bootstrap the Juju environment, this starts the first Juju server that will have a state server of your entire Juju environment and will be responsible for deploying other juju services.

You will have to wait for this server instance to start and it normally takes approximately 10 minutes to complete on Amazon EC2.

Once completed you will be able to check with:

juju status

The status output should be something like this:

environment: amazon
machines:
"0":
agent-state: pending
dns-name: ec2-54-221-34-86.compute-1.amazonaws.com
instance-id: i-5a1fe130
instance-state: running
series: precise
hardware: arch=amd64 cpu-cores=1 cpu-power=100 mem=1740M root-disk=8192M
services: {}

Deploying Juju Gui

First we want to deploy the Juju GUI. When deploying new services Juju defaults to installing each new service on a separate server.

But, we can also tell Juju to co-locate a service on an already deployed server using the following syntax:
juju deploy juju-gui –to 0

This deploys the Juju-gui service to the server 0, which is the Juju bootstrap node.

During deployment you can check the status using:

 juju status

Which should look something like this:

environment: amazon
machines:
"0":
agent-state: started
agent-version: 1.13.3
dns-name: ec2-54-221-34-86.compute-1.amazonaws.com
instance-id: i-5a1fe130
instance-state: running
series: precise
hardware: arch=amd64 cpu-cores=1 cpu-power=100 mem=1740M root-disk=8192M
services:
juju-gui:
charm: cs:precise/juju-gui-76
exposed: false
units:
juju-gui/0:
agent-state: pending
agent-version: 1.13.3
machine: "0"
public-address: ec2-54-221-34-86.compute-1.amazonaws.com

We also need to make the security group allow connection to the Juju gui on the web port, 80.

We do this by exposing the service as follows:
juju expose juju-gui

Once deployment is completed juju status should look something like this:

environment: amazon
machines:
"0":
agent-state: started
agent-version: 1.13.3
dns-name: ec2-54-221-34-86.compute-1.amazonaws.com
instance-id: i-5a1fe130
instance-state: running
series: precise
hardware: arch=amd64 cpu-cores=1 cpu-power=100 mem=1740M root-disk=8192M
services:
juju-gui:
charm: cs:precise/juju-gui-76
exposed: true
units:
juju-gui/0:
agent-state: started
agent-version: 1.13.3
machine: "0"
open-ports:
- 80/tcp
- 443/tcp
public-address: ec2-54-221-34-86.compute-1.amazonaws.com

Now you can connect to Juju-gui using your web browser by connecting to the public-address.

You will be presented with a login screen for Juju-gui.

The username is “admin” and the password is the same as your ~/.juju/environments.yaml “admin-secret” entry.

Once you have logged in you will see a Juju-gui screen that looks like this:

Deploy Nagios Monitoring Service

Our first infrastructure service is going to be Nagios monitoring server, so we can monitor the state of our deployed services.

So, let’s deploy the server.

From the command line, it is as simple as:

juju deploy nagios

You should now see the Nagios monitoring server deployed in the Juju Gui with an icon and a yellow bar showing it is pending.

Once it is deployed the bar will turn green.

Then we need to expose the service, to open the security group to allow connection on port 80.

juju expose nagios

Juju status should now look like this:

environment: amazon
machines:
"0":
agent-state: started
agent-version: 1.13.3
dns-name: ec2-54-221-34-86.compute-1.amazonaws.com
instance-id: i-5a1fe130
instance-state: running
series: precise
hardware: arch=amd64 cpu-cores=1 cpu-power=100 mem=1740M root-disk=8192M
"1":
agent-state: started
agent-version: 1.13.3
dns-name: ec2-54-211-5-1.compute-1.amazonaws.com
instance-id: i-764a2e13
instance-state: running
series: precise
hardware: arch=amd64 cpu-cores=1 cpu-power=100 mem=1740M root-disk=8192M
services:
juju-gui:
charm: cs:precise/juju-gui-76
exposed: true
units:
juju-gui/0:
agent-state: started
agent-version: 1.13.3
machine: "0"
open-ports:
- 80/tcp
- 443/tcp
public-address: ec2-54-221-34-86.compute-1.amazonaws.com
nagios:
charm: cs:precise/nagios-4
exposed: true
units:
nagios/0:
agent-state: started
agent-version: 1.13.3
machine: "1"
open-ports:
- 80/tcp
public-address: ec2-54-211-5-1.compute-1.amazonaws.com

We will also need to retrieve the automatically configured password to connect.

You can do this by running the following command:

juju ssh nagios/0 sudo cat /var/lib/juju/nagios.passwd

This will print the password to your terminal window.

You can now connect to the Nagios web interface using the public-address from juju status above and the username “nagiosadmin” with the password you retrieved in the terminal window.

Nagios should display only 1 host, localhost, and associated services.

Deploying our First Web Application

So, now we have a monitoring server to monitor the services we deploy, let’s start by deploying a simple web application, like the ever popular, wordpress.

The services required to run a WordPress blog are:

  1. SQL database

  2. WordPress Application Server

We will use MySQL as the database server, so let’s deploy it.

This time rather than using the command line let’s use the Juju Gui to deploy the MySQL server.

First search for MySQL using the Search bar on the left hand side.

Then click on the MySQL server in the list.

Click on “Add to my Canvas”.

This will bring up a list of parameters you can modify on the right hand side.

Just click on “Confirm” to confirm the deployment.

Again, you will see a yellow bar when the service is “pending” and a green bar when it is “started”.

We also want to deploy the wordpress application server, so again using the Gui search for wordpress and deploy it.

Once both services are deployed and the bars are green, you can start adding our first relationships.

Adding Relationships

Services are only really useful once they are aware of each other and that is where relationships come in.

We add relationships to make a service work with another service.

So, first we should add a relationship between our WordPress application server and the MySQL database, so that the WordPress blog has somewhere to store all its data.

We can do this from the command line using the command:

juju add-relation mysql wordpress

Alternatively, to do it from the Gui, click on the WordPress Icon and then select “Build relation” and join it to the Mysql Icon.

This will set up a Database relationship between the WordPress Application server and the MySQL database.

It will then configure the database for WordPress, set a user and password and configure the tables required, all automatically.

Now all we need to do is expose the WordPress Server so we can connect to it.

From the Gui click on the WordPress icon and select “view”.

Now click on the “Expose” slider on the top right of the screen.

Now click on the unit box to bring up the unit details screen.

This shows you the public address to connect to.

Copy and paste the address into your browser to access the new WordPress Blog.

Now you can access your new WordPress blog and configure the details, such as the name, e-mail address and password for the admin user.

Do this now and make sure you set a reasonable password.

Monitoring your new blog

Now we have a working WordPress Blog it is time to add the monitoring so that the monitoring server tests the services are available and detects any failures.

To do this we simply add a relation to the nagios monitoring server.

At the command line we would run the command:

juju add-relation mysql nagios
juju add-relation wordpress nagios

Or just add the relations using the gui like before, click the icon, select build relation and join the relationship.

Once this is done your screenshot should look like this:

Now if we wait for the relationships to build and then check the Nagios server, we should find that the MySQL server and WordPress server are now being monitored by Nagios.

Deploy NRPE Subordinate Service

Now lets move on to the next service we need to deploy, NRPE.

NRPE is the Nagios Remote Plugin Executor and it is an agent that you install on each monitored server.

The purpose of the agent is to allow tests to run on the monitored server on request from the monitoring server.

So, for example, a local disk test to check for free space is run from NRPE when the Nagios server requests it, so that you can see when the disk is filling up and you need to take action. It allows for more detailed tests to be carried out on each monitored server.

Now, as the NRPE service is installed on the monitored server and not as a service itself, it is known as a Subordinate Service.

A Juju Subordinate Service is a service which is installed on a server in addition to its primary service and so it allows for units of different services to be deployed into the same container and to have knowledge of each other.

To deploy a subordinate service, first you deploy the service (which just sets up it’s configuration) and then you relate it to each service where you actually want to install it.

In this case, we first deploy the NRPE service, then relate it to the nagios server itself.

juju deploy nrpe
juju add-relation nrpe:monitors nagios:monitors

Now we add relationships to the monitored services:

juju add-relation nrpe:local-monitors mysql:local-monitors
juju add-relation nrpe wordpress

If we now go and check the nagios monitoring server we should now find extra NRPE tests are added for the MySQL and WordPress services.

Summary

In this tutorial, you learnt how to deploy a Juju environment, how to deploy the Juju web gui and how to deploy the Nagios monitoring server and your first web application, a wordpress blog.

Next time we will add some more infrastructure services, such as logging and graphing  and show you how to scale your web application under load.

Darryl Weaver

EMEA Cloud Sales Engineer, Canonical

Part 2

In part 2 we will set up the rsyslog log server, munin graphing server and landscape-client for managing packages.  Then add relationships to the mysql and wordpress services so they are logged, graphed and managed.

Read the second article

Ubuntu cloud

Ubuntu offers all the training, software infrastructure, tools, services and support you need for your public and private clouds.

Newsletter signup

Get the latest Ubuntu news and updates in your inbox.

By submitting this form, I confirm that I have read and agree to Canonical's Privacy Policy.

Related posts

DIY chiselled Ubuntu: crafting your own chiselled Ubuntu base image

In a previous post, I explained how we made our Ubuntu image 15 times smaller by chiselling a specific slice of Ubuntu for .NET developers. In this blog, I...

Open source cloud platform: meet OpenStack

Are you looking for an open source cloud platform and you don’t know where to start? Are you getting lost in all the independent rankings and cloud platform...

Let’s build a snap together – a complex snapcraft.yaml walkthrough

It has been a while since we talked about how to build snaps. In the past, we went through a number of detailed examples, focused on different programming...