On Tue, Mar 19, 2013 at 9:34 PM, Jay Feldblum y_feldblum@yahoo.com wrote:
But a definition is essentially a parameterized recipe template (macro).
Not an abstraction. That's why I talked about resources and providers being
an abstraction, but talked about definitions being merely a grouping of
related resource declarations.
An example of something suited to be a definition would be: the
apache_conf definition in the apache2 cookbook. The right level of
abstraction for this particular case is to call a procedure (macro) that
simply declares another resource with some predefined attributes and some
other parameterized attributes. Every apache config file change needs to
trigger a reload or restart of the service, and there may be many such
config files, so wrapping that up in a definition (macro) is useful.
This is a good example. Some others, that I've used...
- Accumulating template variables
This pattern is documented here:
http://docs.opscode.com/essentials_cookbook_definitions_example_one_definition.html
- Setting node attributes or run state
In this case, the definition might not contain any resources, but instead
wraps up setting some attributes, or stashing some data for other recipes
to use later. Why not use plain old ruby methods, defined in libraries?
They're much harder for those new to ruby to write in the first place, and
the syntax in recipes is different (which has pro's and con's).
- "How do I run a recipe multiple times with different data?"
I've heard this question a number of times, on IRC and from co-workers.
After working through getting a recipe to work (at all), the next
requirement is to "run" it more than once, with different data. The
smallest increment required to achieve this involves changing the recipe
into into a definition. Could they move straight to LWRPs? Sure, but
that's a bunch more to learn, particularly for folks who are early on the
ruby learning curve, and have not yet properly apprehended the
resource/provider model.
To my mind, "Definitions are just crappy LWRPs" is the second most
irritating meme in the Chef community. If we were to remove them just
because they can be misused, what of all the other Chef features that fall
into that category? I've seen terrible sins committed using execute/script
when more appropriate resources were available - should they go? A whole
class of criticism of Chef is the ability to use arbitrary ruby in our
recipes. Should that ability go away too?
Definitions have their own place in Chef's conceptual model, separate from
Resources and Providers. Some new users do struggle with their purpose,
which isn't at all surprising - the docs are not amazing, apache_site is a
poor example (that probably should be an LWRP), and many people seem to
think that Definitions should be ignored entirely, in favour of LWRPs. I
think the problem is communication: the feature is sound, the guidance
needs improvement.
So, my arguments in favour of keeping definitions are that they have a
distinct (albeit under-appreciated) purpose, and that they can ease the
learning curve for new users.
Zac