How to create a controller

See also:

This page includes examples that show the various ways a controller can be created. The examples demonstrate configurations that can be applied to a cloud environment.



To create a controller, you require:

If you are starting with Juju, they may not be available yet. Start by adding a cloud, then add credentials, and return to this page.

Basic process

Creating a controller is known as the “bootstrap process”. Controllers are created with the bootstrap command.

Common invocation

The most common uses of the bootstrap command use the following syntax:

juju bootstrap [--credential <credential>] <cloud>[/<region>] <controller-name>

Below is an example that specifies a cloud name and a controller name:

juju bootstrap aws aws-controller

Note that if a controller name is not specified one will be assigned based on the cloud name and the cloud’s default region.

Create a controller interactively

You can create a controller interactively by omitting a cloud name altogether:

juju bootstrap

You will be prompted for what cloud and region to use as well as the controller name. Do not use this method if you intend on specifying anything else.

Advanced Examples

During the bootstrap process, you are able to define many configuration options to tailor your deployment. Some examples are given below.

To learn more about configuration options available, see Juju | How to configure a controller , Juju | Model , or .

Set default model constraints

Default constraints can be set for every model within a controller. This, in turn, affects the machines that will be created within those models.

Here, every machine, including the controller itself, will have at least 4GiB of memory:

juju bootstrap --constraints mem=4G localhost

See page Using constraints for details on constraints.

Set constraints for a controller

To request at least 4GiB of memory and two CPUs for an AWS controller:

juju bootstrap --bootstrap-constraints "mem=4G cores=2" aws

If any of the constraints are also used with --constraints then the ones given via --bootstrap-constraints will be used.

Create a controller of a specific series

The controller will be deployed upon Ubuntu 18.04 LTS (Bionic) by default.

Here, we name the resulting LXD controller ‘lxd-bionic’ to reflect that:

juju bootstrap localhost lxd-bionic

To select a different series the --bootstrap-series option is used.

Below, a google (GCE) controller based on Ubuntu 16.04 LTS (Xenial) is requested explicitly (and is given the name ‘gce-xenial’):

juju bootstrap --bootstrap-series=xenial google gce-xenial

Set model configuration keys

Model configuration keys can be set using either of the following two options:

  • --config
  • --model-default

The --model-default option affects the initial models as well as any subsequently added models (add-model command) . The model-defaults command can be used once the controller is created in order to achieve the same result.

To create a controller (named “vsp”) for cloud “vsphere” while specifying the vSphere datastore “xtian-ds1” for every model, including any future ones:

juju bootstrap --model-default datastore=xtian-ds1 vsphere vsp

Set model configuration keys both with a file and individually

This example demonstrates how to use both a previously defined configuration file (~/config-rackspace.yaml) and individual configuration values. The latter values take precedence over those that may be included in the file:

juju bootstrap \
    --config=~/config-rackspace.yaml \
    --config image-stream=daily \
    rackspace controller-rackspace

Create a controller using a non-default region

The clouds command lists available clouds and denotes a default region for each. To specify a different region during controller creation:

juju bootstrap aws/us-west-2 mycontroller

This is where omitting a custom controller name could be appropriate, as doing so will result in a name based on the non-default region. Here the controller would be named ‘aws-us-west-2’:

juju bootstrap aws/us-west-2

Create a controller using a different MongoDB profile

MongoDB has two memory profile settings available, ‘default’ and ‘low’. The first setting is the profile shipped by default with MongoDB. The second is a more conservative memory profile that uses less memory. To select which one your controller uses when it is created, use:

juju bootstrap --config mongo-memory-profile=low

Use a custom charm store

Sometimes the charms you’re interested in do not yet reside in the default production charm store ( In this case you can configure Juju to pull charms from an alternate source at controller creation time. Below, we create an OCI controller and pass the staging store URL:

juju bootstrap --config charmstore-url= oci

Change timeout and retry delays

You can change the default timeout and retry delays used by Juju by setting the following keys in your configuration:

Key Default (seconds) Purpose
bootstrap-timeout 600 How long to wait for a connection to the controller
bootstrap-retry-delay 5 How long to wait between connection attempts to a controller
bootstrap-address-delay 10 How often to refresh controller addresses from the API server

For example, to increase the timeout between the client and the controller from 10 minutes to 15, enter the value in seconds:

juju bootstrap --config bootstrap-timeout=900 localhost lxd-faraway

Create a new controller without changing contexts

When a new controller is created, by default, the context will change to the ‘default’ model of that controller. In some cases (e.g. when scripting) this may not be desirable. The --no-switch option disables this behaviour:

juju bootstrap --no-switch localhost lxd-new

Configuring/enabling a remote syslog server

Create an Azure controller and configure for log forwarding:

juju bootstrap azure --config logconfig.yaml

To enable forwarding on all the controller’s models by default:

juju bootstrap azure --config logforward-enabled=true --config logconfig.yaml

See Remote logging for a more thorough treatment of log forwarding.

Placing a controller on a specific MAAS node

To create a controller and have it run on a specific MAAS node:

juju bootstrap maas-prod --to <host>.maas

Specifying an agent version

When a controller is created, it is possible to influence what agent version will be used across the controller and its models. This is covered in Agent versions and streams.

Passing a cloud-specific setting

A cloud setting can be done locally or remotely (on a live cloud). Here, we’ll show how to do it locally (client cache).

View if your chosen backing cloud has any special features and then pass the feature as an option.

Firstly, reveal any features:

juju show-cloud --local --include-config aws

The bottom portion of the output looks like this:

The available config options specific to ec2 clouds are:
  type: string
  description: Use a specific AWS VPC ID (optional). When not specified, Juju requires
    a default VPC or EC2-Classic features to be available for the account/region.
  type: bool
  description: Force Juju to use the AWS VPC ID specified with vpc-id, when it fails
    the minimum validation criteria. Not accepted without vpc-id

The VPC ID is obtained from the AWS web UI.

Secondly, create the controller by placing it (and its models) within it:

juju bootstrap --config vpc-id=vpc-86f7bbe1 aws

Cloud-specific features can also be passed to individual models during their creation (add-model).

Include configuration options at the cloud level

Any settings passed via the --config option can be included in the definition of a cloud. See General cloud management for how to do this.

1 Like

At the bottom of the page the bootstrap command has too man o’s :slight_smile:

juju boootstrap --config vpc-id=vpc-86f7bbe1 was

Fixed, thanks.

I have my controller behind a firewall with port forwarding of :17070 to the controller.

It seems that my manually added entry in the client ~/.local/share/juju/controllers.yaml" gets over-written.

How can make my client understand that is should reach my controllers from a different IP (for port forwarding) ?