Juju has long provided the model as the best way to describe, in a cross cloud and repeatable way, your infrastructure. Often times, your infrastructure consists of shared resources outside of the different models that are operated. Examples might be a shared object storage service providing space for everyone to backup important data, or perhaps a shared nagios resource providing the single pane of glass that operators need to make sure that all is well in the data center.
Juju 2.2 provides a new feature behind a feature flag that we’d like to ask folks to test. It’s called Cross Model Relations and builds upon the great unique feature of Juju known as relations. Relations allow components of your architecture to self-coordinate across each other passing information required to operate. This could just be the IP addresses of each other so that config files can be written such that a front end application can speak to the back end service correctly. It could also be as complicated as passing actual payloads of data back and forth.
Cross Model Relations allows these relations to take place beyond the boundary of the current model. The idea is that I might have a centrally operated service that is made available to other models. Let’s walk through an example of this by providing a centrally operated MySQL service to other folks in the company. As the MySQL expert in our hypothetical company I’m going to create a model that has a scaled out, monitored, and properly sized MySQL deployment.
First, we need to enable the CMR (Cross Model Relations) feature flag. To use a feature flag in Juju we export an environment variable JUJU_DEV_FEATURE_FLAGS.
$ export JUJU_DEV_FEATURE_FLAGS=cross-model
Next we need to bootstrap the controller we’re going to test this out on. I’m going to use AWS for our company today.
$ juju bootstrap aws crossing-models
Once that’s done let’s setup our production grade MySQL service.
$ juju add-model prod-db $ juju deploy mysql --constraints "mem=16G root-disk=1T" $ juju deploy nrpe......and more to make this a scale out mysql model
Now that we’ve got a proper scaled MySQL service going let’s look at offering that database to other models. Now we’re able to use a new Juju command juju offer.
$ juju offer mysql:db mysqlservice Application "mysql" endpoints [db] available at "admin/prod-db.mysqlservice"
We’ve offered to other models the db endpoint that the MySQL application provides. The only bit of our entire prod-db model that’s exposed to other folks is the endpoint we’ve selected to provide. You might provide a proxy or load balancer endpoint to other models in the case of a web application, or you might provide both a db and a Nagios web endpoint out to other models if you want them to be able to query the current status of your monitored MySQL instance. There’s nothing preventing multiple endpoints from one or more applications from being offered out there.
Also note that there’s a URL generated to reference this endpoint. We can ask Juju to tell us about offers that are available for use.
$ juju find-endpoints URL Access Interfaces admin/prod-db.mysqlservice admin mysql:db
Now that we’ve got a database let’s find some uses for it. We’ll setup a blog for the engineering team using Wordpress which leverages a MySQL db back end. Let’s setup the blog model and give them a user account for managing it.
$ juju add-model engineering-blog $ juju add-user engineering-folks $ juju grant engineering-folks write engineering-blog
Now they’ve got their own model for managing their blog. If they’d like, they can setup caching, load balancing, etc. However, we’ll let them know to use our database where we’ll manage db backups, scaling, and monitoring.
$ juju deploy wordpress $ juju expose wordpress $ juju relate wordpress:db admin/prod-db.mysqlservice
This now sets up some interesting things in the status output.
$ juju status Model Controller Cloud/Region Version SLA engineering-blog crossing-models aws/us-east-1 2.2.1 unsupported SAAS name Status Store URL mysqlservice unknown local admin/prod-db.mysqlservice App Version Status Scale Charm Store Rev OS Notes wordpress active 1 wordpress jujucharms 5 ubuntu Unit Workload Agent Machine Public address Ports Message wordpress/0* active idle 0 22.214.171.124 80/tcp Machine State DNS Inst id Series AZ Message 0 started 126.96.36.199 i-0cd638e443cb8441b trusty us-east-1a running Relation Provides Consumes Type db mysqlservice wordpress regular loadbalancer wordpress wordpress peer
Notice the new section above App called SAAS. What we’ve done is provided a SAAS-like offering of a MySQL service to users. The end users can see they’re leveraging the offered service. On top of that the relation is noted down in the Relation section. With that our blog is up and running.
We can repeat the same process for a team wiki using Mediawiki which will also use a MySQL database backend. While setting it up notice how the Mediawiki unit complains about a database is required in the first status output. Once we add the relation to the offered service it heads to ready status.
$ juju add-model wiki $ juju deploy mediawiki $ juju status ... Unit Workload Agent Machine Public address Ports Message mediawiki/0* blocked idle 0 188.8.131.52 Database required $ juju relate mediawiki:db admin/prod-db.mysqlservice $ juju status ... SAAS name Status Store URL mysqlservice unknown local admin/prod-db.mysqlservice App Version Status Scale Charm Store Rev OS Notes mediawiki 1.19.14 active 1 mediawiki jujucharms 9 ubuntu ... Relation Provides Consumes Type db mediawiki mysqlservice regular
We can prove things are working by actually checking out the databases in our MySQL instance. Let’s just go peek and see they’re real.
$ juju switch prod-db $ juju ssh mysql/0 mysql> show databases; +-----------------------------------------+ | Database | +-----------------------------------------+ | information_schema | | mysql | | performance_schema | | remote-05bd1dca1bf54e7889b485a7b29c4dcd | | remote-45dd0a769feb4ebb8d841adf359206c8 | | sys | +-----------------------------------------+ 6 rows in set (0.00 sec)
There we go. Two remote-xxxx databases for each of our models that are using our shared service. This is going to make operating our infrastructure at scale so much better!
Please go out and test this. Let us know what use cases you find for it and what the next steps should be as we prepare this feature for general use. You can find us in the #juju irc channel on Freenode, the Juju mailing list, and you can find me at @mitechie
As this is a new feature it’s limited to working within a single Juju Controller. It’s also a current work in progress so please watch out for bugs as they get fixed, UX that might get tweaked as we get feedback, and note that upgrading a controller with CMR to a newer version of Juju is not currently supported.