Reputation: 761
I have 2 cookbooks the first one installs some RPM and the second one adjusts some configurations. If the correct RPM is already installed and up to date cookbook1 doesn't do anything however cookbook2 is unaware of this and it is applied every-time.
include_recipe 'cookbook1'
include_recipe 'cookbook2' # < this cookbook should run only if cookbook1
is it possible to apply cookbook2 based on the fact that cookbook1 didn't do any changes?
This is my current solution: I'm checking if the current installed RPM version matches what I want and then use an if statement to decide if I need to apply cookbook2:
version_match = system "rpm -qa | grep yum-3.2.22-40.el5.centos"
include_recipe 'cookbook1'
if !version_match
include_recipe 'cookbook2'
end
Thanks!
Upvotes: 1
Views: 431
Reputation: 695
To answer your question - no. include_recipe is a method and not a resource. It's consumed during the compilation phase of the chef-client run and is unaware of state of the machine at that point.
My recommendation is to use not_if / only_if blocks in your 2nd recipe. https://docs.chef.io/resource_common.html#not-if-examples
The reason for this, is to control server state. Also, 'in real world' chef client runs on interval, typically every couple of minutes across thousands of servers.
If someone were to manually connect to any one server and make changes to config files, chef will have no way of knowing it because the whole recipe is skipped.
If on the other hand you write your recipes / resources following the best practices, you should be able to run through your entire run_list every time, and bring the system to a known state, as well as upload changes to chef server, and have your entire infrastructure come into compliance within a few minutes.
Upvotes: 1
Reputation: 2825
The best bet for passing transient data between recipes is node.run_state
(doc reference). It won't ever be saved back to the Chef server, which is a benefit over using the node
object.
However, most Chefs would point out that what you're doing isn't idempotent. Your second recipe should describe the final state of resources on your server, and then you should let chef decide if any action is necessary. Thus, as stated by the other poster, the 'chef way' to accomplish your task is to use a template for your configuration files. They won't be touched unless they don't match the desired end state.
Upvotes: 0