Use OpenStack with Juju

This guide covers:

  1. Add an cloud
  2. Add a credential
  3. Bootstrap a controller

1. Adding an OpenStack cloud

There are two methods to define a cloud for Juju.

A. Use an interactive prompt
B. Define a YAML file and provide that to Juju as a command-line argument

Both methods make use of the juju add-cloud command. You will need to supply a name you wish to call your cloud. It’s also useful to have OpenStack environment variables defined running it. Assuming that you have a “novarc” file available to you, load the variables into your environment:

source /path/to/novarc

To access detailed help about all of its options, run:

juju help add-cloud

A. Using an interactive prompt

Using the add-cloud command without providing its name or an API endpoint will begin an interactive session.

juju add-cloud --local

What does --local do?

Using the --local option instructs Juju to store the cloud definition on the machine that you’re executing the command from.

Omitting it will store the cloud definition on the controller machine. This enables controllers to control models on multiple clouds, but isn’t recommended while you are creating your first model.

Example user session specifying openstack-cloud as the cloud name:

Cloud Types
  lxd
  maas
  manual
  openstack
  vsphere

Select cloud type: openstack

Enter a name for your openstack cloud: openstack-cloud

Enter the API endpoint url for the cloud [https://x.x.x.x:5000/v3]:

Enter the filename of the CA certificate to access OpenStack cloud (optional) [/home/ubuntu/cacert.pem]:

Auth Types
  access-key
  userpass

Select one or more auth types separated by commas: userpass

Enter region [dev1]:

Enter the API endpoint url for the region [use cloud api url]:

Enter another region? (Y/n): n

Successfully read CA Certificate from /home/ubuntu/test_certs/cacert.pem
Cloud "openstack-cloud" successfully added

You will need to add credentials for this cloud (`juju add-credential openstack-cloud`)
before creating a controller (`juju bootstrap openstack-cloud`).

juju add-cloud command pre-populates the defaults with the following environment variables.

- OS_AUTH_URL becomes the default API endpoint URL
- OS_CACERT becomes the default path to the CA certificate file
- OS_REGION_NAME becomes the default region name

It is possible to choose more than one authorisation method by separating the values with commas.

B. Manually adding OpenStack clouds

The manual method makes use of configuration files defined in YAML. To define a configuration file that mimics the parameters provided by the interactive example, use this:

clouds:
    mystack:
      type: openstack
      auth-types: [access-key,userpass]
      regions:
        dev1:
          endpoint: https://openstack.example.com:35574/v3.0/

Adding a cloud manually can be done locally or, since v.2.6.0, remotely (on a controller). Here, we’ll show how to do it locally (client cache).

To add cloud ‘openstack-cloud’, assuming the configuration file is openstack-cloud.yaml in the current directory, we would run:

juju add-cloud --local openstack-cloud openstack-cloud.yaml

See the Adding clouds manually page for further information.

Confirm that you’ve added the cloud correctly

Ask Juju to report the clouds that it has registered:

juju clouds --local

2. Adding credentials

Use the add-credential command to interactively add your credentials to the new cloud:

juju add-credential openstack-cloud

For more information about credentials, read through the Credentials page.

Confirm that you’ve added the credential correctly

To view the credentials that Juju knows about, use the credentials command and inspect both remote and locally stored credentials:

juju credentials
juju credentials --local

3. Creating a controller

You are now ready to create a Juju controller for openstack-cloud:

juju bootstrap openstack-cloud

This provisions a instance on your OpenStack cloud and installs the Juju controller within it.

For a detailed explanation and examples of the bootstrap command see the Creating a controller and Configuring Controllers pages.

This operation may fail with some installations and require more configuration. Here are some tips for two scenarios:
- Images and private clouds
- Working with multiple networks

Images and private clouds

OpenStack requires access to images to provision instances. Configuring this correctly is covered on the Cloud image metadata page.

If your image metadata is available locally, the --metadata-source option is available to you.

juju bootstrap <cloud> <controller name> \
               --metadata-source /path/to/simplestream/images

Working with multiple networks

If there are multiple networks available, you will need to specify the intended network. Check your OpenStack networks with the openstack command:

openstack network list

Provide the preferred network’s name or choose the network you want the instances to boot from. You can use either the network name or the UUID with the ‘network’ configuration option when bootstrapping a new controller.

juju bootstrap <cloud> <controller-name> \
               --model-default network=<network-id>

If there is an external network configured for instances that are only accessible via floating IP, add the allocate-public-ip configuration option:

juju bootstrap <cloud> \
               --bootstrap-constraints="allocate-public-ip=true"

We should tell people to do

juju bootstrap ... --model-default use-floating-ip=true

instead of

juju bootstrap ... --config use-floating-ip=true

because the latter only affects the default model, whereas the former will affect all models the user will create. See Configuring models. I personally wasted a lot of time because of this. I was creating my own model right after bootstrapping the controller and couldn’t understand why that option had no effect.

Oh wow, I feel your pain. Thanks for taking the time to comment. I’ll update the recommendation. [Edit: I’ve made several changes to the document. Hopefully it’s easier to follow now.]

1 Like

@timClicks Thanks for the quick reaction! It’s actually --model-default, not --model-defaults (or do both work?). It’s easy to mix up with juju model-defaults which takes an ‘s’ :wink:

Fixed! Thanks for taking another look :slight_smile: