There is a subtle difference in how only_if
and end if
behave when a node is converged (in Chef speak). In simple terms, when chef-client
starts, it compiles the cookbooks and creates a collection of resources that will converge on the node.
For the sake of example, let's say we have a cookbook cookbook1
with only 1 resource in the recipe. When we run such cookbook in below scenarios:
Scenario 1:
Using do .. end if
:
The resource is removed from the compilation when the condition is not matched. So there will be no resources to run. Example output from chef-client run when node['platform']
is not ubuntu
.
Compiling Cookbooks...
Converging 0 resources
Scenario 2:
Using only_if
guard
The resource remains in the collection, but it is skipped when node['platform']
is not ubuntu
.
Compiling Cookbooks...
Converging 1 resources
Recipe: cookbook1::default
* resource[foo] action run (skipped due to only_if)
In short, pure Ruby code, such as if
conditions will run during "compile" phase itself. Chef resources run during the "converge" phase. See the Chef Infra Client documentation for details.