Charms contain the intelligence necessary for connecting different applications together. These inter-application connections are called relations, and they are formed by connecting the applications’ endpoints. Endpoints can only be connected if they support the same interface and are of a compatible role (requires to provides, provides to requires, peers to peers).
For example, the ‘wordpress’ charmed operator supports, among others, an ‘http’ interface (“provides” the website) and a ‘mysql’ interface (“requires” a database). Any other application which also has such interfaces can connect to this charmed operator in a meaningful way.
Below we see WordPress with relations set up between both MySQL and Apache (a potential relation is shown with HAProxy):
Some of the above application units show unused interfaces. It is the overall purpose of the installation which will dictate what interfaces get used. Some relation types are required by the main charm (‘wordpress’ here) while some relation types are optional. A charmed operator’s entry in Charmhub (e.g., Wordpress) will expose such details.
Relations are not direct connections between charms. They’re implemented on top of the connections that the unit agents establish with the controller at startup. The Juju controller acts as a message broker within a virtual star topology. This allows units to send data via relations that might not have connectivity with each other.
Relations can also work across models, even across multiple controllers and clouds. These are called cross-model relations (sometimes just ‘CMR’) and they enable, for example, scenarios where your databases are hosted on bare metal, to take advantage of I/O performance, and your applications live within Kubernetes, to take advantage of scalability and application density.
A cross-model relation between two models, say Model A and Model B, can be:
- On the same cloud where the two models have the same controller, or
- On the same cloud, but with separate controllers, or
- On different clouds, where the controllers are also inherently separate (since a controller does not work with models across multiple clouds).
These three cases are illustrated below. The red line denotes the cross-model relation in each case.