How to handle multiple bundles with relations?

Say we have two bundles that look like this:

Bundle #1

bundle: kubernetes
applications:
  charm1: charm: charm1
  charm2: charm: charm2
  charm3: charm: charm3

Bundle #2

bundle: kubernetes
applications:
  charm4: charm: charm4
  charm5: charm: charm5
  charm6: charm: charm6

With potentially many charms (like dozens or more) instead of just 3. Each one of those bundles can be deployed just fine, but then say you can deploy both bundles with integrations between them, i.e. something like this:

relations:
  - [charm1, charm4]
  - [charm1, charm5]
  - [charm1, charm6]
  - [charm2, charm4]
  - [charm2, charm5]
  - [charm2, charm6]
  - [charm3, charm4]
  - [charm3, charm5]
  - [charm3, charm6]

What’s more, say that there’s potentially more bundles like above that can integrate with one another, all requiring similar relations. How can this be handled gracefully in Juju? Particularly, how can I avoid having to tell someone "Now that you’ve got Bundle #1 deployed, do juju deploy bundle-2 && juju relate charm1 charm5 && ..."?

Here’s a couple of options that spring to mind, along with reasons they don’t work well:

  • Publish one overarching bundle stack and lots of sub-bundles
    • This handles the case well where you want to deploy one bundle or all bundles, but not where you just want say two out of N bundles
  • Publish only individual bundles
    • Runs into the problem listed above, where a user is stuck manually related a lot of applications to each other
  • Publish each subset of the bundles, along with overarching bundle stack
    • Not practical when talking about many different bundles, as you’d have to publish every bundle, plus every pair of bundles, plus every trio of bundles, plus …

The only real option that I can think of would involve extending the bundle syntax, and so would require changes to Juju, but this scenario should be handled well by something like this:

bundle: kubernetes
groups:
  bundle1:
    applications: [<charms here>]
    relations: [<intra-bundle relations here>]
  bundle2:
    applications: [<charms here>]
    relations: [<intra-bundle relations here>]
relations:
  - [bundle1:charm1, bundle2:charm4]
  <rest of inter-bundle relations here>

Then, someone could run juju deploy foo (or whatever the overarching bundle is called), or say juju deploy foo --groups bundle1,bundle2 and pick exactly what they want without having to do a bunch of manual grunt work.

As a real-world example, I would like to split the Kubeflow bundle up into multiple sub-bundles, and allow people to pick and choose which sub-bundles they’d like to use, without have to manually set up a bunch of relations. I.e., it would be nice if someone could do this:

juju deploy kubeflow --groups=base,katib,mlflow

Instead of this:

juju deploy kubeflow
juju deploy katib
juju relate <lots of things>
juju deploy mlflow
juju relate <lots of things>

Interesting proposal however I’m not sure we would want separate bundles to be so tightly coupled. What you’re effectively looking for is levels, or options for a bundle. This brings me back to one of the original bundle systems where you could have multiple bundles in a single bundle yaml (which had its own problems).

Have you seen bundle overlays? They might be a good stop-gap solution for you. You’d effectively have the base kubeflow bundle and then provide a series of overlays to add groups as you’ve called them.

I think @knkski has a pretty unusual ecosystem in Kubeflow, where all of this makes sense, but I don’t think it’s that common.

@knkski you might be interested in the work on ‘stacks’ which are, for want of a better term, ‘smart bundles’. Today, when you deploy a bundle, it’s really shorthand for a set of freeform deploys and relates. Juju forgets after the deploy that all those apps and relations came from a single place. With stacks, Juju would remember the identity of the bundle (stack) and that stack could then be manipulated as a thing.

In particular, a charm itself could manipulate the stack. This would allow you to define the flavours you are interested in expressing as config on that stack charm.

Thanks for the responses.

@hatch: I would actually push back on the idea that this is tight coupling. I was actually thinking that this would be a great way to share bundles. For example, the Charmed Istio bundle is developed separately from Charmed Kubeflow, but (given a bit of additional syntax to the proposed bundle.yaml above) it could be included in Charmed Kubeflow quite easily like this:

bundle: kubernetes
groups:
  kubeflow:
    <kubeflow bundle goes here>
  istio:
    bundle: istio
relations:
  - [istio:istio-pilot, kubeflow:katib-ui]
  ... more relations ...

Similarly, Charmed Istio could be included into any other bundle that needed it, without any tight coupling.

As far as overlays go, the biggest issue with them is that they’re not something that’s supported by the charm store, so it’s really hard for users of bundle to discover them. If we moved to something like above, it would be as easy as something like juju list-groups kubeflow.

@sabdfl: Thanks, stacks look interesting. Are bundles something that could be incrementally “stackified”? There’s a few related bundle features that would be nice to have in Charmed Kubeflow. For example as you mentioned, it would be nice if Juju knew that I’ve deployed say Charmed Kubeflow 1.0, and adding that feature to bundles seems like a reasonable incremental step towards stacks.

Yes, that is the proposed direction. First, a stack gets a persistent identity, later it gets a brain.

1 Like