Opinionated / sensible / recommended default tools for charms

Adam Gandelman adamg at canonical.com
Tue Nov 8 19:37:33 UTC 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.

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.

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.

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





More information about the Juju mailing list