Getting started with Juju


This guide introduces you to Juju on MS Windows, macOS and Linux. You’ll be deploying a simple web application. Later on, you’ll be able to use those same commands to deploy the app into the cloud, whether private or public.

Watch this guide

Would you prefer to watch, rather than type? This recording goes through the entire tutorial:


Juju concepts primer

Working with Juju productively involves understanding some of its terminology.

Hosting environment

Juju interacts with a cloud to provide your workload.

  • Machines are compute resources, whether bare-metal servers, virtual machines or containers.

  • Providers, or cloud providers, are the businesses that provide clouds and APIs to access them.

  • Clouds are targets that Juju can deploy to. Public clouds include AWS, Google Compute Engine and Microsoft Azure.

Juju architecture

Juju uses an active agent architecture, the core of which is a controller. These terms describe how Juju gets its work done.

  • Charms are software packages that are invoked during phases of an application’s lifecycle by Juju. They implement installation, scaling and configuration negotiation.

  • Client is a term used for the tool that users use to interact with Juju, such as the juju executable.

  • Controllers are software agents running in a cloud that manage models.

  • Agents are running instances of Juju with responsibility to manage an application, a unit, machine or controller. They interact as a distributed system. Commands that you execute are sent to the controller, which then delegates the command to the responsible agent.

Software modelling

Within the Juju ecosystem, an “application” is an abstract entity. These terms describe how Juju enables you to define your software model, so that it can be implemented.

  • Applications are instances of a charm. Applications do not necessarily corespond to a software package running on a machine, but what the charm defines.

  • Models are user-defined collections of applications. Models are wrappers for all of the components that support the applications running within them, such as relations, storage and network spaces.

  • Units are instances of the software running within an applications. An application’s units occupy machines.

  • Relations are protocols facilitated by Juju that allow applications to auto-negotiate their configuration. An application’s relations are defined by its charm.

If you encounter any unfamiliar terms, the Juju project provides a full glossary.

Setting up

Instructions for MS Windows and macOS

Install Multipass

If you’re not running Ubuntu, visit Multipass is a tool for quickly running virtual machines from any host operating system. This will allow you to create a fully-isolated test environment that won’t impact your host system.

Multipass provides a command line interface to launch, manage and generally fiddle about with instances of Linux. The downloading of a minty-fresh image takes a matter of seconds, and within minutes a VM can be up and running.
The Register

Create virtual machine

We want to be able to experiment with Juju and evaluate it without the testing impacting on the rest of our system. To enter a shell within a virtual machine microcloud that has 8 GB RAM allocated to it, execute this command:

$ multipass launch -n microcloud -m 8g -c 2 -d 20G 
Launched: microcloud

Once multipass has downloaded the latest Long Term Support version of the Ubuntu operating system, you will be able to enter a command-line shell:

$ multipass shell microcloud
Need to install snap?

Visit the snapcraft homepage for installation instructions. Snap makes software installation trivial and secure.

Install Juju

Install Juju locally with snap:

$ sudo snap install juju --classic
juju 2.6.8 from Canonical✓ installed

Create a cloud on localhost

LXD manages operating system containers and makes the the “localhost” cloud available to Juju.

LXD is a next generation system container manager. It offers a user experience similar to virtual machines but using Linux containers instead.

It’s image based with pre-made images available for a wide number of Linux distributions
and is built around a very powerful, yet pretty simple, REST API.

LXD website

Ensure LXD is installed

Install LXD with snap:

$ sudo snap install lxd
lxd 3.17 from Canonical✓ installed

If LXD is already installed, you’ll receive this warning:

snap "lxd" is already installed, see 'snap help refresh'

Configure LXD

LXD needs to be configured for its environment:

$ lxd init --auto

If you omit the --auto option, you can tailor your LXD installation. Use lxd help init for a list of all the options.

Verify that the localhost cloud is available

Our localhost cloud is now established. We can verify that by running juju clouds. Juju should have detected the presence of LXD and has added it as the localhost cloud.

$ juju clouds
localhost             1  localhost        lxd         LXD Container Hypervisor

Bootstrap the controller

Juju uses an active software agent, called the controller, to manage applications. The controller is installed on a machine through the bootstrap process.

During the bootstrap process, Juju connects with the cloud, then provision a machine to install the controller on, then install it.

$ juju bootstrap localhost overlord
Creating Juju controller "overlord" on localhost/localhost
Looking for packaged Juju agent version 2.6.8 for amd64

Accessing help: The juju bootstrap command takes several parameters. Use juju help bootstrap to review them.

First workload: Hello Juju!

The first workload that you’ll deploy is a simple web application. You’ll deploy an application that uses the Flask microframework to send “Hello Juju!” via HTTP.

$ juju deploy ~hello-juju
Located charm "cs:hello-juju-2".
Deploying charm "cs:hello-juju-2".

The charm name hello-juju is resolved into an actual charm version by contacting the Charm Store. This charm is then downloaded by the controller and used as the source of the application that was created with the same name.

Checking the deployment

Now that a workload is in place, use juju status to inspect what is happening:

$ juju status
Model    Controller  Cloud/Region         Version  SLA          Timestamp
default  overlord    localhost/localhost  2.6.8    unsupported  16:24:04+12:00

App         Version  Status  Scale  Charm       Store       Rev  OS      Notes
hello-juju           active      1  hello-juju  jujucharms    4  ubuntu  
Unit           Workload  Agent  Machine  Public address  Ports   Message
hello-juju/0*  active    idle   0   80/tcp  
Machine  State    DNS            Inst id        Series  AZ  Message
0        started  juju-646ac9-0  bionic      Running

Connecting to the application

The juju status output above provided the “Public address” of the hello-juju/0 unit as and its Ports column as 80/tcp. Let’s connect!

$ curl
Hello Juju!
Connection refused?

On non-localhost clouds, the connection may be refused. This is normal. To configure the necessary security groups and firewall rules, use juju expose:

juju expose hello-juju

Access a secure shell

Juju provides some useful functionality for SREs and operators who need to interact with units and machines out of the box.

The ssh command accepts unit (and machine) names. They will be substituted for the relevant IP address.

Access the machine via the unit name:

$ juju ssh hello-unit/0

Or via the machine ID:

$ juju ssh 0

Once you’ve connected, you can access the hello-juju web server:

$ curl localhost
Hello Juju!

Relating another application: adding PostgreSQL to the deployment

Relations are Juju’s defining concept and its main point of difference with other systems in its class. They enable the simplicity, security and stability offered by the whole project.

The hello-juju web server maintains a count for each greeting that it has sent out via the /greetings endpoint.

$ curl
{"greetings": 2}

By default, this state is maintained within a SQLite database that is set up by the hello-juju charm itself. To move to PostgreSQL as the data store, two commands are required:

$ juju deploy postgresql
Located charm "cs:postgresql-199".
Deploying charm "cs:postgresql-199".
$ juju relate postgresql:db hello-juju

About relations and how they work

hello-juju includes support for the pgsql relation, which is provided by the postgresql charm and others that present the same interface, such as pg_bouncer.

Relations are protocols that enable applications to auto-configure. In the case of pgsql, the requiring charm (hello-juju) requests that a database be created on its behalf and the provider charm (postgresql) carries that step out and also creates the user account. postgresql then sends the

The data sent between charms is facilitated by the Juju controller. The Juju controller establishes a certificate authority and ensures that all data transported is fully encrypted. Relations prevent secrets from being stored insecurely because they’re not needed by application developers.

What relations are not

Relations are not a networking construct, such as a tunnel between two applications. Instead, they’re a data sharing protocol defined for charm to charm negotiation. As charms are executed by Juju agents, data is shared between agent to agent.

Re-checking the deployment status

Now that the new application and a relation are in place, the juju status output has expanded. Add the --relations option include relations infomation.

$ juju status --relations
Model    Controller  Cloud/Region         Version  SLA          Timestamp
default  overlord    localhost/localhost  2.6.8    unsupported  16:24:04+12:00

App         Version  Status  Scale  Charm       Store       Rev  OS      Notes
hello-juju           active      1  hello-juju  jujucharms    3  ubuntu  
postgresql  10.10    active      1  postgresql  jujucharms  199  ubuntu
Unit           Workload  Agent  Machine  Public address  Ports    Message
hello-juju/0*  active    idle   0   80/tcp  
postgresql/0*  active    idle   0   5432/tcp  Live master (10.10)
Machine  State    DNS            Inst id        Series  AZ  Message
0        started  juju-646ac9-0  bionic      Running
1        started  juju-646ac9-1  bionic      Running

Relation provider       Requirer                Interface    Type     Message
postgresql:coordinator  postgresql:coordinator  coordinator  peer
postgresql:db           hello-juju:db           pgsql        regular
postgresql:replication  postgresql:replication  pgpeer       peer

Juju documentation

@nottrobin any suggestions for embedding JS? I would like to include the following external resources in this page ideally:

<script id="asciicast-267811" src="" async></script>
<script src=""></script>


Both scripts have been added the discourse theme. You should be able to use either the cards or asciinema now.