I'm attempting to create a Chef cookbook that, for now, is mostly just a wrapper cookbook for another cookbook (the audit cookbook). I'm still learning Chef, but from what I can gather from the About Recipes documentation and the Resources Reference documentation, Chef recipes should execute in the order that they're defined (via Ruby code and/or Chef resources).
In the About Recipes documentation, it mentions that
When a recipe is included, the resources found in that recipe will be inserted (in the same exact order) at the point where the include_recipe keyword is located.
In the Resources Reference documentation, they have an apt_update resource that presumably executes before the include_recipe method due to the fact that it's defined earlier in the recipe.
My wrapper cookbook has a single recipe, default.rb, which is literally these two lines:
package 'ruby-dev'
include_recipe 'audit'
However, during a chef-client or chef-solo run I see that the audit::inspec recipe runs before the security::default recipe which causes things to break because InSpec has some other dependencies that need to be installed beforehand. Before I used the package resource I was using the execute resource to explicitly run apt-get install ruby-dev
or yum install ruby-dev
depending on the platform using a case statement, but same problem (all that code was skipped and the include_recipe method called first).
In case it's useful, I'm using Chef 12 which I realize is EOL but I have other dependencies that require me to stick with this version of Chef for now.
I may very well just be misunderstanding how Chef converges work and the order in which execution occurs, but it's causing me a lot of grief so I'd really appreciate some pointers! Does include_recipe always occur before other code within your recipe? Is there any way around this? Am I missing something?
-- EDIT --
I was able to get the desired functionality (install other packages and gems before an include_recipe
call triggered installation of a dependency gem) using the following code in my cookbook recipe:
package 'build-essential' do
action :nothing
end.run_action(:install)
chef_gem 'train' do
version "1.4.4"
action :install
end
chef_gem 'signet' do
version "0.11.0"
action :install
end
include_recipe 'audit'
Note that I ended up installing the build-essential
package rather than the ruby-dev
package from my original code snippet, and also installed two gems for Chef client to use. This all gets installed in the order I expected during the compile phase of the Chef run.
Sources: