Opinionated / sensible / recommended default tools for charms

Clint Byrum clint at ubuntu.com
Tue Nov 8 21:28:18 UTC 2011

Excerpts from Adam Gandelman's message of Tue Nov 08 11:37:33 -0800 2011:
> On 11/08/2011 08:29 AM, Michael Nelson wrote:
> > On Tue, Nov 1, 2011 at 5:29 PM, Michael Nelson
> > <michael.nelson at canonical.com>  wrote:
> >> Just for anyone interested, here's part 1 of my juju+puppet experiment
> >> (with a 2min demo):
> >>
> >> http://micknelson.wordpress.com/2011/11/08/experimenting-with-juju-and-puppet/
> >>
> >> It's mostly pretty obvious - I just use the install/config-changed
> >> hooks to defer to puppet... but it helped me learn much more about
> >> puppet itself and how I can use it together with juju, as well as
> >> start thinking how I could provide an *optional* puppet-master (given
> >> that this will be nearly always private).
> >>
> >> -Michael
> >>
> * WARNING: this ended up much longer than I had anticipated.   *
> Michael-
> Cool!  I'm glad there are other people scratching their heads about this 
> one.  I've played around with a few different ways of doing this (mostly 
> exactly like yours) and ran into a couple of concerns.
> 1. Stuffing puppet manifests into charms and calling them in hooks via 
> 'puppet apply' loses the ability to maintain and share puppet types and 
> resources.  Unless you've set a constraint to only depend on puppet 
> primitives built into puppet-core, you cannot make use of Puppet's 
> shared name space for modules, types and resources(one of the features 
> that makes Puppet so powerful)  For example, lets say I've put together 
> a Puppet class that incorporates other custom types, providers and 
> modules.  When instantiated with a couple of parameters, it propagates a 
> huge chunk of system configuration that would otherwise be a nightmare 
> to deploy using shell scripts.   Now I want to make use of that class 
> from manifests contained within a Juju charm.  There is no way to do 
> that unless I also ship the custom module and all of its custom 
> dependencies within that charm alongside the manifests that called via 
> 'puppet apply'  If I want to use this in multiple juju charms, I need to 
> include the module and its dependencies in every Juju charm that uses 
> it.  This quickly becomes a nightmare to maintain and impossible to 
> avoid divergence.

So any files that need to be shared between charms should be packaged,
and put in a PPA which the charms share. If it has broad enough appeal,
put it in Ubuntu. I fully expect to have some debhelper-like tools that
we can embed in all charms to do common tasks.. once we learn what those
common tasks are, and what the best ways to do them are.

Anwyay, There's no need for the puppetmaster to do the distribution when
you don't need to keep track of exported configs or classify servers. You
already know what modules you want to make use of because the charm *is*
the classifier.

Any other way, and we won't have charms that are easily sharable.

> 2. Calling 'puppet apply' at hook execution only enforces that 
> configuration when the relation's state changes. Ie, I've deployed our 
> massive application stack on a Friday and gone on vacation for 2 weeks. 
> On Monday  Jr. SysAdmin deleted the wrong config file on our web 
> server.  With a puppetmaster in place, his mistake is corrected in ~30 
> minutes (or the next time the agent checks into the puppet master).  
> Without, I'd have to remove and re-add Juju relations to resync system 
> configuration with the Juju's view of the world.

This really has nothing to do with the puppet master, and everything to
do with the semantics of running puppet over and over to re-apply the
configuration... more on this further down.

> I'm not sure what the solution is. I've got a few ideas, but they all 
> mostly end up reproducing work across multiple domains.  What I 
> initially brainstormed:
> a. All data gathered from config-get is stuffed custom facts which are 
> persistent and updated every time the corresponding hooks are executed 
> (ie, $juju-relation-db_user, $juju-relation-db_passwd)  Hooks do the 
> bare minimum configuration necessary to get the service up and running 
> (seems to be the story of most charms currently)
> b. Units also get a custom fact that describes their service-unit, to be 
> used for node classification.
> c. The charm (or, possibly, a colocated puppet-agent charm), 
> authenticates the agent with a central puppet master and runs the puppet 
> agent in a typical polling configuration.
> d. The puppet master classifies nodes based on service unit, and 
> enforces the basic configuration (what is stored in facts) as well as 
> any other environment-specific configuration admins may want.
> This configuration ends up being maintained over time until the relation 
> changes, at which point the facts are updated.  The corresponding puppet 
> code on the master may be something as simple as using Augeas to manage 
> individual settings in a config file, or some more involved resources 
> that deploy large chunks of config that are too cumbersome to express 
> and maintain in the juju charm.
> However, saving information about the environment on disk (like relation 
> data) is a bad idea.  It would be much better if there were some way for 
> units to access that data outside of hook execution, so that puppet 
> could inspect it client-side dynamically via custom providers 
> (eliminating point a above)  It would also be great if Juju could be 
> used as an external node classifier (eliminating b above).   Then, we're 
> no longer coupled with Puppet and facter and the remaining items (c. and 
> d.) could be expressed in Chef-speak just as easily.

To be clear, charms which save data locally are really just caching
the relationship data locally so that other hooks can make use of it
later. I don't see where this is a "bad idea".. but, I understand why
it would seem to be a problem if you think of things in a puppet centric

> I think its important to think about the problem in more general terms.  
> To me, this isn't really about "how can we integrate this with Puppet," 
> but "how does configuration management fit into the Juju stack."  To 
> many people, there is a gap that needs to be filled before they'll 
> consider Juju.  Personally, I'd love to see Juju driving configuration 
> management (chef, puppet, whatever) similar to how it drives machine 
> providers (ec2, orchestra, whatever) There was some talk about this 
> topic at UDS and I expect there will be more as Juju gains a wider 
> audience.

Adam thanks for sharing your thoughts.

I'm worried that this is just old habits creeping back in where there
hasn't been a clear direction put forward.

I get that when the pager goes off, you login to the box first, and poke
at things, and sometimes that means screwing up conf files. Puppet running
over and over refreshing things tends to wipe this out, so the habit
dies when puppet is there to enforce that you only do things with it.

IMO, having this only happen when you've used puppet seems to miss
the point and lose the benefits for all users who don't use puppet in
their charms.

What if we just have the juju unit agent simply refresh the relationships
on a predefined interval? If the 'joined' and 'changed' hooks are just
simply re-executed once every X minutes, we get the benefit of the
polling puppet model with the benefit of Juju's event based model when
it makes sense.

This would help the junior admin to remember that what he should have
done is updated the charm.

More information about the Juju mailing list