Skip the recipe based on condition


#1

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.


#2

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


#3

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

#4

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


#5

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.