Cross Model Relations

Cross Model Relations allow creating relations between applications in different models. This applies to models hosted on different controllers, and thus also in different clouds.

We will show an example of deploying a Moodle application, where a Postgres database is hosted on one cloud (SWITCHengines) and the Moodle front end is hosted in another cloud (GARR).

Clouds

To create our clouds, we prepare a file clouds.yaml, which describes them:

clouds:
  SWITCHengines:
    type: openstack
    auth-types: [userpass]
    regions:
      ZH:
        endpoint: https://keystone.cloud.switch.ch:5000/v3
      LS:
        endpoint: https://keystone.cloud.switch.ch:5000/v3

  GARR:
   type: openstack
   auth-types: [access-key, userpass]
   regions:
     garr-ct1:
       endpoint: https://keystone.cloud.garr.it:5000/v3
     garr-pa1:
       endpoint: https://keystone.cloud.garr.it:5000/v3

We create a cloud on the SWITCHengines cloud with:

$ juju add-cloud SWITCHengines clouds.yaml

and specify the credentials to use:

$ juju add-credential SWITCHengines -f credentials.yaml

where credentials.yaml contains:

credentials:
  SWITCHengines:
    default-credential: <switch-user>
    <switch-user>:
      auth-type: userpass
      project-domain-name: Default
      user-domain-name: Default
      tenant-name: <project-name>
      username: <username>
      password: <password>

  GARR:
    default-credential: <garr-user>
    <garr-user>:
      auth-type: userpass
      project-domain-name: cloudusers
      user-domain-name: cloudusers
      tenant-name: <project-name>
      username: <username>
      password: <password>

Similarly we create a GARR cloud with:

$ juju add-cloud GARR clouds.yaml
$ juju add-credential GARR -f credentials.yaml

To use Google Compute Engine (GCE), you add these to the credentials file:

google:
  default-credential: <googleuser>
  <googleuser>:
    auth-type: jsonfile
    file: <credential.json>
    project-id: <project-id>

where <credential.json> is the absolute path to the json key file for the project, obtained from https://console.developers.google.com/apis/credentials, selecting the type Service account key. More details in Using the Google Compute Engine public cloud.

You can then add these credentials to Juju with:

juju add-credential google -f credentials.yaml

To use Amazon AWS, you add credentials like these:

aws:
  <USER>:
    auth-type: access-key
    access-key: <ACCESS-KEY>
    secret-key: <SECRET-KEY>

where the keys can be obtained form the AWS Console for <USER>.

Controllers and Models

Example Cloud 1: SWITCHengines

First we deploy a controller in the SWITCHengines cloud. The networking configuration for this cloud (basically the names of internal and public networks) is described in the file config-switch.yaml:

network: private
use-floating-ip: true
external-network: public

In SWITCHengines cloud the simplestream service is not yet available. Therefore we must define the image metadata locally, following the instructions described in the previous link. Basically we need to issue commands like:

$ juju metadata generate-image -d ~/metadata/ -i <IMAGE_ID>  -s xenial -r LS -u https://keystone.cloud.switch.ch:5000/v3

where <IMAGE_ID> is the ID of the Ubuntu-16 (Xenial) image on the cloud.

This command will create the following folders and files in ~/metadata:

images
-- streams
   -- v1
      com.ubuntu.cloud-released-imagemetadata.json
      index.json

We can now bootstrap the controller. We choose the region LS (Lausanne DC):

$ juju bootstrap --credentials <switch-user> --metadata-source ~/metadata/ --config config-switch.yaml \
  SWITCHengines/LS switchengines-ls

We create a model on switchengines-ls:

$ juju add-model --config config-switch.yaml moodle

Example Cloud 2: GARR

We deploy a controller on the GARR cloud region garr-pa1 (Palermo DC) with:

$ juju bootstrap --config config.yaml --credential <garr-user> GARR/garr-pa1 garr-pa1 --constraints "mem=8G"

where config.yaml contains:

network: default
use-floating-ip: true
external-network: floating-ip

We create a model on garr-pa1:

$ juju add-model --config config.yaml moodle

Example Cloud 3: GCE

To create a controller on Google, you can specify an optional region, with:

juju boostrap google europe-west3

Applications

Now we are ready to deploy applications that use VMs on multiple clouds. In the example we will deploy a Moodle application that will use a PostGres databalse on the SWITCHengines cloud and a web front end on the GARR cloud:

$ juju switch switchengines-ls:moodle
$ juju deploy cs:postgresql
$ juju offer postgresql:db
$ juju switch garr-pa1:moodle
$ juju deploy cs:~csd-garr/moodle

and finally we connect the two applications:

$ juju add-relation moodle:pgsql-db switchengines-ls:<switch-user>/moodle.postgresql

By exposing the Moodle application, you will ve able to access it with a browser:

$ juju expose moodle

You should see the following status:

$ juju status
Model    Controller     Cloud/Region   Version  SLA
alberto  GARR-garr-pa1  GARR/garr-pa1  2.3.8    unsupported

SAAS        Status  Store           URL
postgresql  active  alberto-switch  admin/alberto.postgresql

App     Version  Status       Scale  Charm   Store       Rev  OS      Notes
moodle           active      1  moodle  jujucharms    4  ubuntu  exposed

Unit       Workload  Agent  Machine  Public address  Ports   Message
moodle/0*  active    idle   1        90.147.188.235  80/tcp  Unit is Ready

Machine  State    DNS             Inst id                               Series  AZ    Message
1        started  90.147.188.235  e5f6ce63-099e-4767-b906-7cc43f38ba3b  xenial  nova  ACTIVE

Relation provider  Requirer         Interface  Type     Message
postgresql:db      moodle:pgsql-db  pgsql      regular

You should now be able to see who is allowed to access the offer and what ingress subnets are required to allow traffic from the consuming model:

$ juju offers -m switchengines-ls:moodle --format yaml
postgresql:
  application: postgresql
  store: alberto-switch
  charm: cs:postgresql-175
  offer-url: admin/alberto.postgresql
  endpoints:
    db:
      interface: pgsql
      role: provider
  connections:
  - source-model-uuid: 6366c149-bac1-4c54-89cc-2c7ab74f361f
    username: admin
    relation-id: 11
    endpoint: db
    status:
      current: joined
      since: 8 minutes ago
    ingress-subnets:
    - 90.147.188.235/32
  users:
    admin:
      display-name: admin
      access: admin
    everyone@external:
      access: read