- Integration (before Juju
- Cross-model integrations (before Juju
3.0, ‘cross-model relation (CMR))’
- How to manage a (same-model) integration
This document demonstrates the various steps involved in managing a cross-model integration. The step of adding the integration is the same as for a regular, same-model integration. However, as a cross-model integration may in principle cross controller, cloud, and administrative boundaries, there are additional steps before and after, for making an application accessible from another model, or offering it, and for relating to it from the other model, or consuming it.
- Create an offer
- View an offer’s details
- Control access to an offer
- Find an offer to use
- Integrate with an offer
- Allow traffic from an integrated application
- Inspect integrations with an offer
- Suspend, resume, or remove an integration
- Remove an offer
Create an offer
An offer stems from an application endpoint. This is how an offer is created:
juju offer <application>:<application endpoint>
By default, an offer is named after its underlying application but you may also choose to give it a different name:
juju offer <application>:<application endpoint> <offer name>
juju deploy mysql juju offer mysql:db hosted_mysql
To offer both the db and db-admin endpoints:
juju deploy mysql juju offer mysql:db,db-admin hosted_mysql
Although an offer may have multiple (offer) endpoints it is always expressed as a single URL:
If the above mysql offer were made in the
prod model by user
admin, the URL would be:
If the ‘controller’ portion is omitted the current controller is assumed.
View an offer’s details
See also: show-offer
show-offer command gives details about a given offer.
juju show-offer <offer name>
juju show-offer default.mysql Store URL Access Description Endpoint Interface Role myctrl admin/prod.hostedmysql admin MySQL is a fast, stable and true multi-user, db mysql provider multi-threaded SQL database server. SQL (Structured Query Language) is the most popular database query language in the world. The ma...
For more details, including which users can access the offer, the the
juju show-offer default.mysql --format yaml myctrl:admin/prod.hosted_mysql: description: | MySQL is a fast, stable and true multi-user, multi-threaded SQL database server. SQL (Structured Query Language) is the most popular database query language in the world. The main goals of MySQL are speed, robustness and ease of use. access: admin endpoints: db: interface: mysql role: provider users: admin: display-name: admin access: admin everyone@external: access: read
A non-admin user with read/consume access can also view an offer’s details, but they won’t see the information for users with access.
Control access to an offer
Offers can have one of three access levels:
- read (a user can see the offer when searching)
- consume (a user can relate an application to the offer)
- admin (a user can manage the offer)
These are applied similarly to how standard model access is applied, via the
juju grant and
juju revoke commands:
juju grant <user> <access-level> <offer-url>
juju revoke <user> <access level> <offer-url>
Revoking a user’s consume access will result in all relations for that user to that offer to be suspended. If the consume access is granted anew, each relation will need to be individually resumed. Suspending and resuming relations are explained in more detail later.
To grant bob consume access to an offer:
juju grant bob consume admin/prod.hosted_mysql
To revoke bob’s consume access (he will be left with read access):
juju revoke bob consume admin/prod.hosted_mysql
To revoke all of bob’s access:
juju revoke bob read admin/prod.hosted_mysql
Find an offer to use
See also: find-offers
Offers can be searched based on various criteria:
- URL (or part thereof)
- offer name
- model name
The results will show information about the offer, including the level of access the user making the query has on each offer.
To find all offers on a specified controller:
$ juju find-offers foo: Store URL Access Interfaces foo admin/default.hosted-mysql admin mysql:db foo admin/default.mysql-admin admin mysql-root:db-admin, mysql:db foo admin/default.postgresql admin pgsql:db
As with the list-offers command, the
yaml output will show extra information, including users who can access the offer (if an admin makes the query).
juju find-offers --offer hosted-mysql --format yaml foo:admin/prod.hosted-mysql: access: admin endpoints: db: interface: mysql role: provider users: admin: display-name: admin access: admin everyone@external: access: read
To find offers in a specified model:
juju find-offers admin/prod juju find-offers foo:admin/prod
To find offers with a specified interface on the current controller:
juju find-offers --interface mysql
To find offers with a specified interface on a specific controller:
juju find-offers --interface mysql foo:
To find offers with “sql” in the name:
$ juju find-offers --offer sql foo:
Integrate with an offer
juju integrate was
If a user has consume access to an offer, they can deploy an application in their model and establish an integration with the offer by way of its URL. The controller part of the URL is optional if the other model resides in the same controller.
juju integrate <application>[:<application endpoint>] <offer-url>[:<offer endpoint>]
Specifying the endpoint for the application and the offer is analogous to normal integrations. They can be added but are often unnecessary:
juju integrate <application> <offer-url>
When you integrate with an offer, a proxy application is made in the consuming model, named after the offer.
juju deploy mediawiki juju integrate mediawiki:db admin/prod.hosted_mysql
An offer can be consumed without integration. This workflow sets up the proxy application in the consuming model and creates a user-defined alias for the offer. This latter is what’s used to subsequently relate to. Having an offer alias can avoid a namespace conflict with a pre-existing application.
juju consume <offer-url> <offer-alias> juju integrate <application> <offer alias>
juju consume admin/prod.hosted_mysql mysql-alias juju integrate mediawiki:db mysql-alias
Offers which have been consumed show up in
juju status in the SAAS section.
The integrations (relations) block in status shows any relevant status information about the integrations to the offer in the Message field. This includes any error information due to rejected ingress, or if the relation is suspended etc.
$ juju status --relations Model Controller Cloud/Region Version SLA test foo lxd 2.9.0 unsupported SAAS Status Store URL hosted_mysql active acme admin/prod.hosted_mysql App Version Status Scale Charm Store Rev OS Notes mediawiki 1.19.14 active 1 mediawiki charmhub 19 ubuntu Unit Workload Agent Machine Public address Ports Message mediawiki/0* active idle 0 10.200.103.121 80/tcp Ready Machine State DNS Inst id Series AZ Message 0 started 10.200.103.121 juju-16fc34-0 trusty Running Relation provider Requirer Interface Type Message hosted_mysql:db mediawiki:db mysql regular
To remove a consumed offer:
juju remove-saas <offer alias>
Allow traffic from an integrated application
When the consuming model is behind a NAT firewall its traffic will typically exit (egress) that firewall with a modified address/network. In this case, the
--via option can be used with the
juju integrate command to request the firewall on the offering side to allow this traffic. This option specifies the NATed address (or network) in CIDR notation:
juju integrate <application> <offer url> --via <cidr subnet(s)>
juju integrate mediawiki:db ian:admin/default.mysql --via 220.127.116.11/8
--via value is a comma separated list of subnets in CIDR notation. This includes the /32 case where a single NATed IP address is used for egress.
It’s also possible to set up egress subnets as a model config value so that all cross model integrations use those subnets without needing to use the
juju model-config egress-subnets=<cidr subnet>
juju model-config egress-subnets=18.104.22.168/8
To be clear, the above command is applied to the consuming model.
To allow control over what ingress can be applied to the offering model, an administrator can set up allowed ingress subnets by creating a firewall rule.
juju set-firewall-rule juju-application-offer --whitelist <cidr subnet>
Where ‘juju-application-offer’ is a well-known string that denotes the firewall rule to apply to any offer in the current model. If a consumer attempts to create a relation with requested ingress outside the bounds of the whitelist subnets, the relation will fail and be marked as in error.
The above command is applied to the offering model.
juju set-firewall-rule juju-application-offer --whitelist 22.214.171.124/16
juju set-firewall-rule command only affects subsequently created relations, not existing ones. Only new relations will be rejected if the changed firewall rules preclude the requested ingress.
To see what firewall rules have currently been defined, use the list firewall-rules command.
juju firewall-rules Service Whitelist subnets juju-application-offer 126.96.36.199/16
Beyond a certain number of firewall rules, which have been dynamically created to allow access from individual integrations, Juju will revert to using the whitelist subnets as the access rules. The number of rules at which this cutover applies is cloud specific.
Inspect integrations with an offer
offers command is used to see all connections to one more offers.
juju offers [--format (tabular|summary|yaml|json)] [<offer name>]
offer name is not provided, all offers are included in the result.
tabular output shows each user connected (relating to) the offer, the
relation id of the relation, and ingress subnets in use with that connection. The
summary output shows one row per offer, with a count of active/total relations. Use the
yaml output to see extra detail such as the UUID of the consuming model.
The output can be filtered by:
- interface: the interface name of the endpoint
- application: the name of the offered application
- connected user: the name of a user who has an integration to the offer
- allowed consumer: the name of a user allowed to consume the offer
- active only: only show offers which are in use (are related to)
juju help offers for more detail.
juju offers mysql Offer User Relation id Status Endpoint Interface Role Ingress subnets mysql admin 2 joined db mysql provider 188.8.131.52/32 juju offers --format summary Offer Application Charm Connected Store URL Endpoint Interface Role hosted_mysql mysql ch:mysql-57 1/1 myctrl admin/prod.hosted_mysql db mysql provider
All offers for a given application:
juju offers --application mysql
All offers for a given interface:
juju offers --interface mysql
All offers for a given user who has related to the offer:
juju offers --connected-user fred
All offers for a given user who can consume the offer:
juju offers --format summary --allowed-consumer mary
The above command is best run with
--format summary as the intent is to see, for a given user, what offers they might relate to, regardless of whether there are existing integrations (which is what the tabular view shows).
Suspend, resume, or remove an integration
Before you can suspend, resume, or remove an integration (relation), you need to know the integration (relation) ID.
Given two related apps (app1: endpoint, app2), the integration (relation) ID can be found as follows:
juju exec --unit $UNIT_FOR_APP1 -- relation-ids endpoint
<ENDPOINT>:<REL_ID>, gives you the relation id.
Once you have the integration (relation) id:
To suspend an integration (relation), do:
juju suspend-relation <id1>
Suspended integrations (relations) will run the relation departed / broken hooks on either end, and any firewall ingress will be closed.
And, to resume an integration (relation), do:
juju resume-relation <id1>
Finally, to remove an integration (relation) entirely:
juju remove-relation <id1>
Removing an integration on the offering side will trigger a removal on the consuming side. An integration can also be removed from the consuming side, as well as the application proxy, resulting in all integrations being removed.
In all cases, more than one integration id can be specified, separated by spaces.
juju suspend-relation 2 --message "reason for suspension" juju suspend-relation 3 4 5 --message "reason for suspension" juju resume-relation 2
Remove an offer
An offer can be removed providing it hasn’t been used in any integration. To override this behaviour the
--force option is required, in which case the integration is also removed. This is how an offer is removed:
juju remove-offer [--force] <offer-url>
Note that, if the offer resides in the current model, then the shorter offer name can be used instead of the longer URL.
Similarly, if an application is being offered, it cannot be deleted until all its offers are removed.
For more on cross-model integrations, see the following scenarios:
- Scenario #1 A MediaWiki deployment, based within the same controller, used by the admin user, but consumed by multiple models.
- Scenario #2 A MediaWiki deployment, based within multiple controllers, used by a non-admin user, and consumed by a single model.