The goal of this tutorial is to give new Juju operators a solid introduction to the command line client. In so doing, several important concepts are introduced. It also discusses the use of command prefixes and aliases. Further reading suggestions are included at the end.
The following prerequisites are assumed as a starting point for this tutorial:
- You're using Ubuntu 18.04 LTS (Bionic).
- Juju (stable snap channel) is installed. See the Installing Juju page.
- You have chosen a backing cloud and have created a controller for it. Refer to the Clouds page to get started with a cloud and controller.
This guide uses LXD (
v.3.9) as a backing cloud due to its accessibility and
low resource usage. Choose a local LXD cloud if you're not sure what to use
(see Using LXD with Juju).
As you gain more experience with the client, you will discover a common set of
Generally their meanings are self-evident but some require explanation. A good
example of this are the
remove- prefixes, such as in the
remove-user. These two prefixes differ in terms
of severity. Basically,
destroy- indicates a destructive action that is
difficult to reverse whereas
remove- does not.
There is a
kill- prefix but it is reserved for a single command:
kill-controller. The latter differs from
destroy-controller in that it has
the ability to terminate the controller machine directly via the cloud
provider, without cleaning up any machines that may be running in workload
list- prefix can often be omitted as there is usually a corresponding
command alias available. For instance,
clouds can be used instead of
list-clouds. The list of aliases can be obtained in this way:
juju help commands | grep Alias
show- prefix is used to drill down into an object to reveal details. It
is akin to the verb "describe".
Juju makes available to the operator a wide variety of commands. In this section, we'll cover the basic ones.
List the controller:
This will return a list of all the controllers known to your Juju client. Below, we have a controller named 'lxd':
Controller Model User Access Cloud/Region Models Machines HA Version lxd* default admin superuser localhost/localhost 2 1 none 2.5.0
A newly-created controller has two models: The 'controller' model, which should be used only for internal Juju management, and a 'default' model, which is ready for actual use.
Confirm the above by listing all the models in the currently active controller:
Our example's output:
Controller: lxd Model Cloud/Region Status Machines Access Last connection controller localhost/localhost available 1 admin just now default* localhost/localhost available 2 admin 2019-02-02
To see the currently active controller, model, and user:
Controller: lxd Model: default User: admin
Applications are contained within models and are installed via charms. By default, charms are downloaded from the online Charm Store during deployment.
To deploy a charm, such as 'redis', in the currently active model:
juju deploy redis
This results in an identically-named application ("redis") to be installed on a newly-created machine within the backing cloud. You can assign a custom name to the application by specifying that name as an argument:
juju deploy redis datastore
To create a model, named 'alpha', in the currently active controller:
juju add-model alpha
By default, when a model is created the currently active model becomes the new model.
To manually change to a different model, say the original 'default' model:
juju switch default
To request that two machines be created that are devoid of an application:
juju add-machine -m alpha -n 2
Here we've used the
-m option to explicitly select a model (i.e. we don't
want the currently active model, which at this time is 'default').
To change context to model 'alpha' and then list the model's machines:
juju switch alpha juju machines
Machine State DNS Inst id Series AZ Message 0 started 10.243.67.116 juju-ded876-0 bionic Running 1 started 10.243.67.53 juju-ded876-1 bionic Running
To deploy 'apache2' to a new LXD container on existing machine '0':
juju deploy apache2 --to lxd:0
It's not necessary to explicitly target an existing machine in order to deploy a charm upon on. To deploy 'mongodb' on the second available machine ('1'):
juju deploy mongodb
To scale out the 'apache2' application by creating another instantiation (unit) of it on a new machine:
juju add-unit apache2
add-machine command, the
-n option is available if multiple units
status command is one that you'll use often. It gives live information
for a given model.
Our example currently shows:
Model Controller Cloud/Region Version SLA Timestamp alpha lxd localhost/localhost 2.5.0 unsupported 21:28:33Z App Version Status Scale Charm Store Rev OS Notes apache2 unknown 2 apache2 jujucharms 26 ubuntu mongodb 3.6.3 active 1 mongodb jujucharms 52 ubuntu Unit Workload Agent Machine Public address Ports Message apache2/0* unknown idle 0/lxd/0 10.72.88.191 apache2/1 unknown idle 2 10.243.67.141 mongodb/0* active idle 1 10.243.67.53 27017/tcp,27019/tcp,27021/tcp,28017/tcp Unit is ready Machine State DNS Inst id Series AZ Message 0 started 10.243.67.116 juju-ded876-0 bionic Running 0/lxd/0 started 10.72.88.191 juju-ded876-0-lxd-0 bionic Container started 1 started 10.243.67.53 juju-ded876-1 bionic Running 2 started 10.243.67.141 juju-ded876-2 bionic Running
The output is broken up into four sections.
The top section mentions basic information such as the names of the current model and controller ('alpha' and 'lxd' respectively), followed by the cloud name ('localhost'), what version of Juju the model is running, whether Juju is being used in a third-party context (see Managed solutions), and finally, the timestamp of the current controller.
The App section contains information at the application level. It is closely related to the providence of an application's charm. The 'Scale' tells us how many units exist for an application while the 'Rev' column shows the charm's revision number.
The Unit section contains information at the unit level. It lists them, along with information that is passed back from the unit agent. The type of data available is is very charm-specific. For instance, the 'unknown' workload message for the apache2 units is not necessarily a bad thing. It's just that the associated charm was not written to give something more insightful.
The Machine section contains information at the machine level. It lists machines by their ID (e.g. '0/lxd/0' or just '1'). The 'Inst id' is the instance id of the machine that gets passed to the cloud provider as the instance name.
Notice how the
machines command output is a subset of the
Juju logs are inspected on a per-model basis using a specific utility.
To view (tail) the logs of the 'alpha' model:
juju debug-log -m alpha
There are a number of ways to configure the behaviour of the
The system user who created the controller (
bootstrap command) will
automatically have SSH access to all machines in the original two default
models ('controller' and 'default') and any models they create afterwards.
To connect to a machine simply refer to the machine ID (from the
command). Here we connect to machine '1' in the current model:
juju ssh 1
This command will always get you to the controller machine:
juju ssh -m controller 0
To remove the 'apache2' application, including all units, along with associated machines (provided they are not hosting another application's units).
juju remove-application apache2
To remove just a single unit, such as 'apache2/1':
juju remove-unit apache2/1
remove-application command, this command will also remove the
machine if it is now devoid of units.
To remove the machine whose ID is '1':
juju remove-machine 1
As a safety precaution, a machine cannot be removed if it is hosting a unit.
Either remove all of its units first or, as a last resort, use the
Destroying a model is a quick way to remove all applications and machines within that model. Begin anew with the creation of a new one.
To destroy the model called 'alpha':
juju destroy-model alpha
When a controller is destroyed, all its models, applications, and machines are as well.
To destroy the controller called 'lxd':
juju destroy-controller lxd
Based on the material covered in this tutorial, we suggest the following for further reading: