Skip the recipe based on condition

Is there any way to skip the recipe execution based on some IF condition.

if the condition is true, then recipe should execute otherwise not.

You could do that by wrapping the whole thing in a big IF block, but that’s pretty ugly. If you have a recipe whose entire contents might be worth skipping, then your recipe might be better suited to a Custom Resource, where you could utilize the “current state” check, with the “converge_if_changed” clause.

Alternately, rather than calling your recipe directly in the run list, include it from another recipe using “only_if”.

Regards,
Dan-Joe Lopez

Sure. We do this sort of thing due to various needs in our environment to “guard” against misuse, combined with the total lack of time/staff to do it Perfectly™. It has suited our needs regardless of it being not ideal/clean/pretty. It allows one to not have to write and always remember to use a guard for every resource. I’m sure plenty of people will wrinkle their nose at the idea.

@Dan-Joe : I’m not aware of any way to include another recipe using only_if. Last I checked the include_recipe resource didn’t allow attributes like guards. That is, include_recipe 'foo::default' can’t have a do/end block where one specifies guards like only_if. Maybe this changed in Chef 13+ or something though.

Anyway, @priyanshu:

# some-cookbook-for-all-nodes/recipes/default.rb
return unless some-criteria

Simplistic Example:

# some-cookbook-for-all-nodes/recipes/default.rb
return if node['platform'] == 'redhat' && node['platform_version'].to_i < 6
# ...whole recipe here that should only run on redhat 6+...

instead of:

# some-cookbook-for-all-nodes/recipes/default.rb
some_resource 'noodle' do
  not_if { node['platform'] == 'redhat' && node['platform_version'].to_i < 6 }
end

some_resource 'noodle2' do
  not_if { node['platform'] == 'redhat' && node['platform_version'].to_i < 6 }
end

some_resource 'noodle3' do
  not_if { node['platform'] == 'redhat' && node['platform_version'].to_i < 6 }
end

some_resource 'noodle4' do
  not_if { node['platform'] == 'redhat' && node['platform_version'].to_i < 6 }
end

Hi Jeff,

What I was suggesting for the include is to use a pure ruby “if”:
Include_recipe ‘foo::bar’ if some_condition == desired_state

Regards,
Dan-Joe Lopez

1 Like

Yes, thats cleaner as well, have a parent recipe and include_recipe based on a condition, instead of not_if guard on individual resources. It also keeps the run_list shorter (ignored recipes/resources are not included in the resource list). The thing you have to ensure is that the guard clauses are evaluated during the compilation phase, not during the execution phase.