Devops may be a constant challenge for you, or maybe the concept has never crossed your mind. Regardless, you've made your way to Juju and hopefully see why we think it's service orchestration at its finest.
Orchestration needs brains, so we combine services and smarts to create Juju Charms. Juju can deploy charms to your local machine or into a variety of clouds; once there, Juju will intelligently manage these charms (scaling up, down, or sideways) and all the service interactions that go along with them.
In this walkthrough, we'll show you how to create a simple charm and deploy it to your local machine. Once your whistle's wet, we'll talk about some next steps to consider for more advanced charm authoring. But first...
You'll be creating a local Juju environment on your computer. We're using local LXC containers for this example since that's simple and allows us to focus on the charming process rather than the intricacies of public cloud deployment. Later, we can get much fancier and move to a cloud if we want.
!!! Note: this walk-through assumes you are running Ubuntu and have no local Juju environment. If you have already installed and bootstrapped a local environment (or if you are using our Vagrant development workflow), please skip the first two steps and join us at step 3.
- Install required packages
From a terminal, enter the following to install the necessary packages:
sudo apt-get install juju juju-local charm-tools
If you prefer to use the Ubuntu Software Center, search for and install the following: * juju * juju-local * charm-tools
The charm-tools package is technically optional. It's a plugin for Juju that makes authoring and maintaining charms easier. We assume you want to do things the easy way, so we include it here as one of the required packages.
- Initialize the environment
You can setup and configure Juju locally with just a few quick commands. Once complete, Juju will handle subsequent actions like setting up new containers and deploying your charm. Simply enter the following in your terminal (you'll be prompted for your sudo password):
juju init
juju switch local
juju bootstrap
!!! Note: New Juju installations use 'amazon' as the default deployment environment. We issued the juju switch local
command to change this so we use local LXC containers.
- Create a local charm repository
The recommended convention for charm development is to create a working directory with sub-directories for each operating system series you wish to target. In this example, we'll be creating a charm for Ubuntu Trusty (14.04). From your terminal, create the appropriate directory structure by entering:
cd ~
mkdir -p charms/trusty
cd charms/trusty
- Create your charm
There are a variety of control files that provide metadata and handle the full life cycle of a charm -- everything from installing to configuring to destroying it. Juju supports writing these controls in many different languages (Python, Ruby, shell, to name a few).
Fortunately, all this flexibility doesn't correspond to a complex authoring experience. The charm-tools plugin we installed earlier can create a bare-bones charm that we can easily modify to suit our needs. Even better, charm-tools has lots of language templates for us to choose from. Let's create our example charm based on the 'bash' template. Enter the following into your terminal:
juju charm create -t bash hello-juju
cd hello-juju
Examining the output from tree
, we see the directory structure and control files that make up our newly created 'hello-juju' charm.
.
├── config.yaml
├── hooks
│ ├── config-changed
│ ├── install
│ ├── relation-name-relation-broken
│ ├── relation-name-relation-changed
│ ├── relation-name-relation-departed
│ ├── relation-name-relation-joined
│ ├── start
│ ├── stop
│ └── upgrade-charm
├── icon.svg
├── metadata.yaml
├── README.ex
└── revision
The only control files you need to modify are metadata.yaml
and ./hooks/install
. Everything else is optional and described in more detail later.
* The metadata.yaml
file describes your charm. In our example, we'll just include some basic info. Overwrite the auto-generated metadata.yaml
by entering the following into your terminal:
```
cat << EOF > ./metadata.yaml
name: hello-juju
summary: A modest Hello World charm
maintainer: Your Name <your@email.address>
description: |
Our first charm. It deploys the apache web server
and alters the homepage to tell the world how much
Juju rocks.
EOF
```
* The `./hooks/install` control file (called a hook in Juju parlance) installs your charm on a machine; in our case, that's a local LXC container. For this exercise, we'll install apache, change the default homepage, and start the webserver. Overwrite the auto-generated `./hooks/install` by entering the following into your terminal:
```
cat << EOF > ./hooks/install
#!/bin/bash
# Set some bash flags so we get more verbose output
set -eux
# Install apache2 without prompting
apt-get -y install apache2
# Enable the default site
a2ensite 000-default
# Overwrite the default homepage with our own
echo "<html><body>Juju Rocks, World!</body></html>" \
> /var/www/html/index.html
# Start the apache webserver
service apache2 restart
EOF
```
- Deploy your Charm
We'll now use Juju to deploy our charm. Enter the following into your terminal to have Juju spin up an Ubuntu Trusty container and install your charm into it:
juju deploy --repository ~/charms local:trusty/hello-juju
Since this is your first deployment, Juju will download a Trusty cloud image template and use that as the basis for your charm's LXC container. This may take a few minutes, but it's a one time hit; subsequent charm deployments for Trusty will re-use this template. Monitor the status of the deployment by entering the following in your terminal:
juju status
!!! Note: you may want to run watch juju status
to refresh the output automatically. Kill watch
when you're ready by pressing Ctrl-C.
Once you see the agent-state for 'hello-juju/0' change to started
, your charm is deployed. You'll see a public-address
in the same output. Navigate to that address with a web browser to see your creation in action!
Sample output of a successful deployment:
environment: local
machines:
...
services:
hello-juju:
...
agent-state: started
...
public-address: 10.0.3.128
- Destroy your environment
When you're done patting yourself on the back, you may want to destroy the environment that you just created. Enter the following into your terminal to get rid of all containers and services deployed in your local environment:
juju destroy-environment local
Don't worry -- the charm source that you wrote in your ~/charms directory won't be touched. If you ever want to re-create the environment and deploy again, just re-run the steps above.
Feels good, doesn't it? Granted, this example doesn't really need sophisticated devops tooling, but we hope it showcases how easy it is to get started writing Juju charms.
Our in-depth walkthroughs will introduce you to more advanced Juju concepts. We'll cover everything you need to become a seasoned charm author, including:
- Testing
A charm is only as good as its tests. We'll use charm-tools to help us write and execute unit tests for our charms.
- Control files
We hinted at a number of control files in the auto-generated charm source. We'll describe these and how to handle relationships with other charms.
- Cloud deployment
We'll build off the concepts you used here to take your local deployment to the cloud.
- Publishing
You'll probably want share your work and be famous! We'll discuss charm licensing and publishing options. We'll even go over how to add a beautiful icon to attract people in the Charm Store.
We hope your interest is piqued and you continue your authoring experience by following our in-depth walkthroughs. We're excited to see what you come up with!
Great document Kevin. I wanted to make the comment that for Juju to provide a trusty image the version must be trusty or later (I don't think a precise install will give you trusty containers). Do we need to call out trusty as requirement in the beginning? I do not want to give people using precise false hopes.
Otherwise that document looks good, very good conversational tone! Thanks for writing it up!