Conditional execution for custom resources


#1

In custom resource, is the conditional execution using only_if/not_if
supported? I tried but didn’t work for me. Is there any Chef defined mechanism
for conditional execution of custom resources?

Lets take scenario : Install RPM if it is already not installed.

So defined new custom resource in ‘definitions’ directory under cookbook

define :remote_execute, :command => false, :condition => false do
execute “remote_command” do
command “#{params[:command]}”

not_if “#{params[:condition]}” <<<< Ideally, I don’t want

to pass condition parameter; but one can achieve similar functionality by doing
this.
end
end

In my recipe I am calling remote_execute as below.

remote_execute “rexe_rpm” do
command "sudo rpm -ivh
/home/aditya/Downloads/libyaml-0.1.4-1.el6.rf.x86_64.rpm"
not_if “rpm -qa | grep yaml” <<<< this is not honored in
case of custom resource.

condition “rpm -qa | grep yaml” <<<< If I pass condition parameter,

it works as expected.
end

Thanks,
Aditya Nitsure


#2

Definitions aren’t proper resources this should work as an LWRP tho.

On Mar 19, 2013, at 1:54 AM, adityanitsure@yahoo.co.uk wrote:

In custom resource, is the conditional execution using only_if/not_if
supported? I tried but didn’t work for me. Is there any Chef defined mechanism
for conditional execution of custom resources?

Lets take scenario : Install RPM if it is already not installed.

So defined new custom resource in ‘definitions’ directory under cookbook

define :remote_execute, :command => false, :condition => false do
execute “remote_command” do
command “#{params[:command]}”

not_if “#{params[:condition]}” <<<< Ideally, I don’t want

to pass condition parameter; but one can achieve similar functionality by doing
this.
end
end

In my recipe I am calling remote_execute as below.

remote_execute “rexe_rpm” do
command "sudo rpm -ivh
/home/aditya/Downloads/libyaml-0.1.4-1.el6.rf.x86_64.rpm"
not_if “rpm -qa | grep yaml” <<<< this is not honored in
case of custom resource.

condition “rpm -qa | grep yaml” <<<< If I pass condition parameter,

it works as expected.
end

Thanks,
Aditya Nitsure


#3

On Tue, Mar 19, 2013 at 12:22 PM, Jesse Nelson spheromak@gmail.com wrote:

Definitions aren’t proper resources this should work as an LWRP tho.

Perhaps it’s time to deprecate definitions and start deorbiting them in
time for Chef 12?

Those of us who have been using Chef for a while and following the list
know that they are the poor step-brothers of LWRPs, but new users are still
confused and start using them, only to be told to stop.

Is there any strong argument to keeping them? I’m not aware of any good
reason.

My proposal is to to:

  • remove them from the documentation, or at least clearly mark them as “do
    not use in new code”;
  • have Chef 11 log a warning;
  • remove them in time for Chef 12.

Thoughts?

Andrea


#4

Think this would be a great plan :slight_smile:

On Tue, Mar 19, 2013 at 5:37 AM, Andrea Campi
andrea.campi@zephirworks.comwrote:

On Tue, Mar 19, 2013 at 12:22 PM, Jesse Nelson spheromak@gmail.comwrote:

Definitions aren’t proper resources this should work as an LWRP tho.

Perhaps it’s time to deprecate definitions and start deorbiting them in
time for Chef 12?

Those of us who have been using Chef for a while and following the list
know that they are the poor step-brothers of LWRPs, but new users are still
confused and start using them, only to be told to stop.

Is there any strong argument to keeping them? I’m not aware of any good
reason.

My proposal is to to:

  • remove them from the documentation, or at least clearly mark them as “do
    not use in new code”;
  • have Chef 11 log a warning;
  • remove them in time for Chef 12.

Thoughts?

Andrea


#5

For given scenario LWRP worked for me. Thanks!

Yeah, if some of the functionalities or features are not supported for ‘definitions’ and if both (LWRP & definitions) are serving same purpose then its better to depricate ‘definitions’.
For new users its confusing.

Thanks,
Aditya Nitsure


From: Jesse Nelson spheromak@gmail.com
To: chef chef@lists.opscode.com
Sent: Tuesday, 19 March 2013 6:22 PM
Subject: [chef] Re: Re: Re: Conditional execution for custom resources

Think this would be a great plan :slight_smile:

On Tue, Mar 19, 2013 at 5:37 AM, Andrea Campi andrea.campi@zephirworks.com wrote:

On Tue, Mar 19, 2013 at 12:22 PM, Jesse Nelson spheromak@gmail.com wrote:

Definitions aren’t proper resources this should work as an LWRP tho.

Perhaps it’s time to deprecate definitions and start deorbiting them in time for Chef 12?

Those of us who have been using Chef for a while and following the list know that they are the poor step-brothers of LWRPs, but new users are still confused and start using them, only to be told to stop.

Is there any strong argument to keeping them? I’m not aware of any good reason.

My proposal is to to:

  • remove them from the documentation, or at least clearly mark them as “do not use in new code”;
  • have Chef 11 log a warning;
  • remove them in time for Chef 12.

Thoughts?

Andrea


#6

Agreed. Anything to make the introduction to Chef easier is a +1 of
paramount importance, IMO.

Mat


#7

Is there still a case for just making a definition a wrapper around making resources and providers?

Adam

From: Andrea Campi [mailto:andrea.campi@zephirworks.com]
Sent: Tuesday, March 19, 2013 5:38 AM
To: chef@lists.opscode.com
Subject: [chef] Re: Re: Conditional execution for custom resources

On Tue, Mar 19, 2013 at 12:22 PM, Jesse Nelson <spheromak@gmail.commailto:spheromak@gmail.com> wrote:
Definitions aren’t proper resources this should work as an LWRP tho.

Perhaps it’s time to deprecate definitions and start deorbiting them in time for Chef 12?

Those of us who have been using Chef for a while and following the list know that they are the poor step-brothers of LWRPs, but new users are still confused and start using them, only to be told to stop.

Is there any strong argument to keeping them? I’m not aware of any good reason.

My proposal is to to:

  • remove them from the documentation, or at least clearly mark them as “do not use in new code”;
  • have Chef 11 log a warning;
  • remove them in time for Chef 12.

Thoughts?

Andrea


#8

Definitions are perfectly fine as macros - functions which, when called,
declare resources and add them to the resources-collection. So describe
them as macros
, not as resources, in the docs. That will stop most of the
confusion.

Definitions are useful for when you simply need a lightweight grouping of
two or more resource declarations, macro-like, where custom resources &
providers (including LWRPs) are too heavyweight.

Using custom providers like glorified definitions is poor form. If you have
a provider which simply declares some sub-resources, why is that a
provider? That should be a definition (macro) instead.

Cheers,
Jay

On Tue, Mar 19, 2013 at 1:50 PM, Adam Jacob adam@opscode.com wrote:

Is there still a case for just making a definition a wrapper around
making resources and providers?****


Adam****


From: Andrea Campi [mailto:andrea.campi@zephirworks.com]
Sent: Tuesday, March 19, 2013 5:38 AM
To: chef@lists.opscode.com
Subject: [chef] Re: Re: Conditional execution for custom resources****


On Tue, Mar 19, 2013 at 12:22 PM, Jesse Nelson spheromak@gmail.com
wrote:****

Definitions aren’t proper resources this should work as an LWRP tho.****



Perhaps it’s time to deprecate definitions and start deorbiting them in
time for Chef 12?****


Those of us who have been using Chef for a while and following the list
know that they are the poor step-brothers of LWRPs, but new users are still
confused and start using them, only to be told to stop.****


Is there any strong argument to keeping them? I’m not aware of any good
reason.****


My proposal is to to:****

  • remove them from the documentation, or at least clearly mark them as “do
    not use in new code”;****

  • have Chef 11 log a warning;****

  • remove them in time for Chef 12.****


Thoughts?****


Andrea****


#9

For the record, I agree with you.

Best,
Adam

From: yfeldblum@gmail.com [mailto:yfeldblum@gmail.com] On Behalf Of Jay Feldblum
Sent: Tuesday, March 19, 2013 11:21 AM
To: chef@lists.opscode.com
Subject: [chef] Re: RE: Re: Re: Conditional execution for custom resources

Definitions are perfectly fine as macros - functions which, when called, declare resources and add them to the resources-collection. So describe them as macros, not as resources, in the docs. That will stop most of the confusion.

Definitions are useful for when you simply need a lightweight grouping of two or more resource declarations, macro-like, where custom resources & providers (including LWRPs) are too heavyweight.

Using custom providers like glorified definitions is poor form. If you have a provider which simply declares some sub-resources, why is that a provider? That should be a definition (macro) instead.

Cheers,
Jay

On Tue, Mar 19, 2013 at 1:50 PM, Adam Jacob <adam@opscode.commailto:adam@opscode.com> wrote:
Is there still a case for just making a definition a wrapper around making resources and providers?

Adam

From: Andrea Campi [mailto:andrea.campi@zephirworks.commailto:andrea.campi@zephirworks.com]
Sent: Tuesday, March 19, 2013 5:38 AM
To: chef@lists.opscode.commailto:chef@lists.opscode.com
Subject: [chef] Re: Re: Conditional execution for custom resources

On Tue, Mar 19, 2013 at 12:22 PM, Jesse Nelson <spheromak@gmail.commailto:spheromak@gmail.com> wrote:
Definitions aren’t proper resources this should work as an LWRP tho.

Perhaps it’s time to deprecate definitions and start deorbiting them in time for Chef 12?

Those of us who have been using Chef for a while and following the list know that they are the poor step-brothers of LWRPs, but new users are still confused and start using them, only to be told to stop.

Is there any strong argument to keeping them? I’m not aware of any good reason.

My proposal is to to:

  • remove them from the documentation, or at least clearly mark them as “do not use in new code”;
  • have Chef 11 log a warning;
  • remove them in time for Chef 12.

Thoughts?

Andrea


#10

On Tuesday, March 19, 2013 at 11:29 AM, Adam Jacob wrote:

For the record, I agree with you.

Best,
Adam

From: yfeldblum@gmail.com [mailto:yfeldblum@gmail.com] On Behalf Of Jay Feldblum
Sent: Tuesday, March 19, 2013 11:21 AM
To: chef@lists.opscode.com (mailto:chef@lists.opscode.com)
Subject: [chef] Re: RE: Re: Re: Conditional execution for custom resources

Definitions are perfectly fine as macros - functions which, when called, declare resources and add them to the resources-collection. So describe them as macros, not as resources, in the docs. That will stop most of the confusion.

Definitions are useful for when you simply need a lightweight grouping of two or more resource declarations, macro-like, where custom resources & providers (including LWRPs) are too heavyweight.

Using custom providers like glorified definitions is poor form. If you have a provider which simply declares some sub-resources, why is that a provider? That should be a definition (macro) instead.

Cheers,

Jay

Are they really better for that use case though? The amount of boilerplate is about the same, and the use cases are the same, no?

Can you elaborate on what you mean by LWRPs being too heavyweight? Is it just a matter of having two files? Is it the conceptual overhead of thinking in terms of resources and providers?

IMO, making a group of resources a LWRP makes sense as a conceptual grouping. With the use_inline_resources feature in Chef 11, notifications and the like should just work the way a user would expect.


Daniel DeLeo


#11

Daniel,

Lightweight resources & providers take two files which must be kept in
sync. (You could do it in one file in a library, but then you lose the DSL.
The fact that it’s easy is not in dispute. The point is that it’s
unnecessary.) The interface and the implementation are forcibly separated,
regardless of whether you actually need that separation.

The inline-resources feature is certainly helpful in this context. But that
introduces another problem: notifications. Recipe-level resources can’t
notify inline-resources declared in a provider action. Sometimes what one
needs is for the recipe to notify a resource declared from within a macro
(or subscribe to one).

When something requires the convenience of grouping but does not require
the wall of abstraction, then resources & providers do too much.

Cheers,
Jay

On Tue, Mar 19, 2013 at 2:41 PM, Daniel DeLeo dan@kallistec.com wrote:

On Tuesday, March 19, 2013 at 11:29 AM, Adam Jacob wrote:

For the record, I agree with you.****


Best,****

Adam****


From: yfeldblum@gmail.com [mailto:yfeldblum@gmail.comyfeldblum@gmail.com]
On Behalf Of Jay Feldblum
Sent: Tuesday, March 19, 2013 11:21 AM
To: chef@lists.opscode.com
Subject: [chef] Re: RE: Re: Re: Conditional execution for custom
resources
**


Definitions are perfectly fine as macros - functions which, when called,
declare resources and add them to the resources-collection. So describe
them as macros
, not as resources, in the docs. That will stop most of
the confusion.

Definitions are useful for when you simply need a lightweight grouping of
two or more resource declarations, macro-like, where custom resources &
providers (including LWRPs) are too heavyweight.****


Using custom providers like glorified definitions is poor form. If you
have a provider which simply declares some sub-resources, why is that a
provider? That should be a definition (macro) instead.****


Cheers,****

Jay

Are they really better for that use case though? The amount of boilerplate
is about the same, and the use cases are the same, no?

Can you elaborate on what you mean by LWRPs being too heavyweight? Is it
just a matter of having two files? Is it the conceptual overhead of
thinking in terms of resources and providers?

IMO, making a group of resources a LWRP makes sense as a conceptual
grouping. With the use_inline_resources feature in Chef 11, notifications
and the like should just work the way a user would expect.


Daniel DeLeo


#12

On Tuesday, March 19, 2013 at 12:05 PM, Jay Feldblum wrote:

Daniel,

Lightweight resources & providers take two files which must be kept in sync. (You could do it in one file in a library, but then you lose the DSL. The fact that it’s easy is not in dispute. The point is that it’s unnecessary.) The interface and the implementation are forcibly separated, regardless of whether you actually need that separation.

The inline-resources feature is certainly helpful in this context. But that introduces another problem: notifications. Recipe-level resources can’t notify inline-resources declared in a provider action. Sometimes what one needs is for the recipe to notify a resource declared from within a macro (or subscribe to one).

When something requires the convenience of grouping but does not require the wall of abstraction, then resources & providers do too much.

Cheers,
Jay

Thanks for the feedback.

The bit about having two files and such seems like just an interface issue. This can be solved with a little bit of design effort.

As for notifying resources that are defined by a macro, that feels a bit ugly because you’re crossing the abstraction layers. Can you explain a bit more about how you’re using this profitably? Would it be a huge burden to implement this in a hypothetical “extra lightweight RP” that defined the resource and provider in a single file?


Daniel DeLeo


#13

Daniel,

If what you need is an abstraction, absolutely use resources & providers.

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.

But it is not useful to think of this example as an abstraction - it’s
better to think of this as a helper method which is not an abstraction.
Attempting to force that into a resource/provider may be much more effort
than it’s worth; attempting to get rid of the definition and simply rewrite
all the call sites seems to me to be going backwards.

Cheers,
Jay

On Tue, Mar 19, 2013 at 5:11 PM, Daniel DeLeo dan@kallistec.com wrote:

On Tuesday, March 19, 2013 at 12:05 PM, Jay Feldblum wrote:

Daniel,

Lightweight resources & providers take two files which must be kept in
sync. (You could do it in one file in a library, but then you lose the DSL.
The fact that it’s easy is not in dispute. The point is that it’s
unnecessary.) The interface and the implementation are forcibly separated,
regardless of whether you actually need that separation.

The inline-resources feature is certainly helpful in this context. But
that introduces another problem: notifications. Recipe-level resources
can’t notify inline-resources declared in a provider action. Sometimes what
one needs is for the recipe to notify a resource declared from within a
macro (or subscribe to one).

When something requires the convenience of grouping but does not require
the wall of abstraction, then resources & providers do too much.

Cheers,
Jay

Thanks for the feedback.

The bit about having two files and such seems like just an interface
issue. This can be solved with a little bit of design effort.

As for notifying resources that are defined by a macro, that feels a bit
ugly because you’re crossing the abstraction layers. Can you explain a bit
more about how you’re using this profitably? Would it be a huge burden to
implement this in a hypothetical “extra lightweight RP” that defined the
resource and provider in a single file?


Daniel DeLeo


#14

In this case what’s the advantage of definition over a plain method. If you want to wrap some reusable resources you may as well just use a plain method. I think the increase in noise by definitions is detracting.

On Mar 19, 2013, at 2:34 PM, Jay Feldblum y_feldblum@yahoo.com wrote:

Daniel,

If what you need is an abstraction, absolutely use resources & providers.

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.

But it is not useful to think of this example as an abstraction - it’s better to think of this as a helper method which is not an abstraction. Attempting to force that into a resource/provider may be much more effort than it’s worth; attempting to get rid of the definition and simply rewrite all the call sites seems to me to be going backwards.

Cheers,
Jay

On Tue, Mar 19, 2013 at 5:11 PM, Daniel DeLeo dan@kallistec.com wrote:

On Tuesday, March 19, 2013 at 12:05 PM, Jay Feldblum wrote:

Daniel,

Lightweight resources & providers take two files which must be kept in sync. (You could do it in one file in a library, but then you lose the DSL. The fact that it’s easy is not in dispute. The point is that it’s unnecessary.) The interface and the implementation are forcibly separated, regardless of whether you actually need that separation.

The inline-resources feature is certainly helpful in this context. But that introduces another problem: notifications. Recipe-level resources can’t notify inline-resources declared in a provider action. Sometimes what one needs is for the recipe to notify a resource declared from within a macro (or subscribe to one).

When something requires the convenience of grouping but does not require the wall of abstraction, then resources & providers do too much.

Cheers,
Jay

Thanks for the feedback.

The bit about having two files and such seems like just an interface issue. This can be solved with a little bit of design effort.

As for notifying resources that are defined by a macro, that feels a bit ugly because you’re crossing the abstraction layers. Can you explain a bit more about how you’re using this profitably? Would it be a huge burden to implement this in a hypothetical “extra lightweight RP” that defined the resource and provider in a single file?


Daniel DeLeo


#15

Jesse,

You’re right that the current implementation of definitions doesn’t have
too much over plain methods. The call-sites are nicer, which is one of the
benefits.

But the definitions DSL could be improved to make them more useful, for the
particular case, than plain methods. For example, pass-through guards (an
only_if in the call-site is automatically added to every resource declared
in the definition).

Plain methods can’t offer that, but definitions could offer that.

Cheers,
Jay

On Tue, Mar 19, 2013 at 6:18 PM, Jesse Nelson spheromak@gmail.com wrote:

In this case what’s the advantage of definition over a plain method. If
you want to wrap some reusable resources you may as well just use a plain
method. I think the increase in noise by definitions is detracting.

On Mar 19, 2013, at 2:34 PM, Jay Feldblum y_feldblum@yahoo.com wrote:

Daniel,

If what you need is an abstraction, absolutely use resources & providers.

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.

But it is not useful to think of this example as an abstraction - it’s
better to think of this as a helper method which is not an abstraction.
Attempting to force that into a resource/provider may be much more effort
than it’s worth; attempting to get rid of the definition and simply rewrite
all the call sites seems to me to be going backwards.

Cheers,
Jay

On Tue, Mar 19, 2013 at 5:11 PM, Daniel DeLeo dan@kallistec.com wrote:

On Tuesday, March 19, 2013 at 12:05 PM, Jay Feldblum wrote:

Daniel,

Lightweight resources & providers take two files which must be kept in
sync. (You could do it in one file in a library, but then you lose the DSL.
The fact that it’s easy is not in dispute. The point is that it’s
unnecessary.) The interface and the implementation are forcibly separated,
regardless of whether you actually need that separation.

The inline-resources feature is certainly helpful in this context. But
that introduces another problem: notifications. Recipe-level resources
can’t notify inline-resources declared in a provider action. Sometimes what
one needs is for the recipe to notify a resource declared from within a
macro (or subscribe to one).

When something requires the convenience of grouping but does not require
the wall of abstraction, then resources & providers do too much.

Cheers,
Jay

Thanks for the feedback.

The bit about having two files and such seems like just an interface
issue. This can be solved with a little bit of design effort.

As for notifying resources that are defined by a macro, that feels a bit
ugly because you’re crossing the abstraction layers. Can you explain a bit
more about how you’re using this profitably? Would it be a huge burden to
implement this in a hypothetical “extra lightweight RP” that defined the
resource and provider in a single file?


Daniel DeLeo


#16

Hi,

On Wed, Mar 20, 2013 at 5:20 AM, Jay Feldblum y_feldblum@yahoo.com wrote:

Using custom providers like glorified definitions is poor form. If you have
a provider which simply declares some sub-resources, why is that a provider?

If it is in a reusable cookbook then;

  • you want to be able to add notifications/subscriptions to it.
  • I find the ease of validating configuration passed into a LWRP much
    easier than definitions.
  • We started down the path of generating user documentation based on
    annotations in the resource aspect of the LWRP.

If it is not a reusable cookbook then definitions are fine but I often
find a raw ruby method easier to digest.

On Wed, Mar 20, 2013 at 8:11 AM, Daniel DeLeo dan@kallistec.com wrote:

As for notifying resources that are defined by a macro, that feels a bit
ugly because you’re crossing the abstraction layers. Can you explain a bit
more about how you’re using this profitably?

Here’s how we use this. I am not sure if it is “good practice” but we
have yet to find a better mechanism.

Almost all of our cookbooks with LWRP use the inline-resources
strategy. Some of our LWRPs define resources that they want external
elements to be able to subscribe to or notify on. Typically this is
something like a LWRP that defines a service and we want to be able to
restart service when configuration managed by other components gets
changed. i.e. We have to restart an application server when a hosted
application changes certain configuration elements.

We have solved this in a number of different ways. Typically we just
redefine the resource that we need to notify on with a :nothing action
and notify as appropriate. Mostly this works. Some of our cookbooks
redefine the same resource 10+ times in different LWRPs which is
annoying. In the case of services this is even more annoying because
we want to make the particular service provider configurable at
runtime (i.e. runit/upstart/…) which would mean some painful
configuration across LWRPs.

We have toyed with the idea of having a mechanism for allowing a LWRP
to “publish” some resources into a higher context and keep some inline
but it seemed complex to implement so we avoided it.


Cheers,

Peter Donald


#17

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…

  1. Accumulating template variables

This pattern is documented here:
http://docs.opscode.com/essentials_cookbook_definitions_example_one_definition.html

  1. 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).

  1. “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