Few applications you might want to run can do so completely independently - most of them rely on some other software components to be present and running too (e.g. a database). There would be little point in Juju making it supremely easy to deploy applications if it didn't also make it easy to connect them up to other applications they need to get running! The Juju magic in this case involves the hooks built in to each charm which allow them to communicate. Unless you are writing charms, there is no need to go into detail on hooks, but these are the parts that make creating relationships between applications so easy.
The charm for WordPress, for example, knows that it requires a database. It therefore has some code to deal with creating that connection and configuring the WordPress instance appropriately when it is told which database to connect to. Similarly, the MySQL charm knows that it is a database, and has code to create different types of database depending on what is required. The act of joining these applications together causes this code to run, the WordPress charm saying what tables, users and data it requires, and the MySQL charm fulfilling that and acknowledging the task. As you will see though, adding a relationship is much easier than even this brief explanation.
Creating relationships is usually very straightforward. Simply deploy the two applications:
juju deploy wordpress juju deploy mysql
Then you create the relationship by specifying these two applications with the
juju add-relation mysql wordpress
These applications will then communicate and establish an appropriate connection, in this case WordPress using MySQL for its database requirement, and MySQL is generating and providing the necessary tables required for WordPress.
In some cases, there may be ambiguity about how the applications should connect. For example, in the case of specifying a database for the Mediawiki charm.
juju add-relation mysql mediawiki error: ambiguous relation: "mediawiki mysql" could refer to "mediawiki:db mysql:db"; "mediawiki:slave mysql:db"
The solution is to specify the nature of the relation using the relation interface identifier. In this case, we want MySQL to provide the backend database for mediawiki ('db' relation), so this is what we need to enter:
juju add-relation mysql mediawiki:db
We can check the output from
juju status to make sure the correct
relationship has been established:
Model Controller Cloud/Region Version SLA default lxd localhost/localhost 2.3.1 unsupported App Version Status Scale Charm Store Rev OS Notes mediawiki 1.19.14 active 1 mediawiki jujucharms 19 ubuntu mysql 5.7.20 active 1 mysql jujucharms 58 ubuntu Unit Workload Agent Machine Public address Ports Message mediawiki/0* active idle 2 10.55.126.152 80/tcp Ready mysql/0* active idle 1 10.55.126.253 3306/tcp Ready Machine State DNS Inst id Series AZ Message 1 started 10.55.126.253 juju-d4f415-1 xenial Running 2 started 10.55.126.152 juju-d4f415-2 trusty Running Relation provider Requirer Interface Type Message mysql:cluster mysql:cluster mysql-ha peer mysql:db mediawiki:db mysql regular
The final section of the status output shows all current established relations.
There are times when a relationship just isn't working and it is time to move on. Fortunately, it is a simple single-line command to break off these relationships:
juju remove-relation mediawiki mysql
In cases where there is more than one relation between the two applications, it is necessary to specify the interface at least once:
juju remove-relation mediawiki mysql:db
Relations can also work across models, even across multiple controllers. See Cross model relations for more information.