0
votes

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:

1

1 Answers

1
votes

if you would examine the audit::inspec rescipe, you will find that it uses a compile time installation of the inspec rubygem (see the last line)

inspec_gem 'inspec' do
  version node['audit']['inspec_version']
  source node['audit']['inspec_gem_source']
  action :nothing
end.run_action(:install)

from chef documentation:

run_action

Use .run_action(:some_action) at the end of a resource block to run the specified action during the compile phase.