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