chef-infrachef-recipeberkshelf

Why can't chef resolve my cookbooks?


Intro I am learning Chef to automate the server management at work. I downloaded chefdk 3.0 from here and now I am trying to build my first cookbook using chef.

Important I am using this in a Windows environment for testing purpose, I do expect it to fail since Windows does not have iptables, but I do not expect it to fail saying that it can't find the cookbook. I've tried using Windows cookbook and it works.

The problem I am able to create the cookbook and run it, but I am not able to reference dependencies from supermarket.

I have tried two alternatives:

Alternative 1

I used the following command to create the cookbook

chef generate cookbook learn_chef_httpd

(from this tutorial)

I was able to complete the tutorial and now I would like to test referencing another cookbook, so I chose simple_iptables

I added this line

cookbook 'simple_iptables', '~> 0.7.0'

To my Berksfile, as described in the Supermarket.

Then I added these lines to my default.rb file:

include_recipe 'simple_iptables'

# Allow HTTP, HTTPS
simple_iptables_rule "http" do
  rule [ "--proto tcp --dport 80",
         "--proto tcp --dport 443" ]
  jump "ACCEPT"
end

And I run the cookbook using:

chef-client --local-mode --runlist 'recipe[learn_chef_httpd]'

The problem is that Chef doesn't find the cookbook

Chef::Exceptions::CookbookNotFound
----------------------------------
Cookbook simple_iptables not found. If you're loading simple_iptables from anoth er cookbook, make sure you configure the dependency in your metadata

I tried adding it to the metadata:

depends 'simple_iptables', '~> 0.7.0'

But I still get an error:

Error Resolving Cookbooks for Run List:
Missing Cookbooks:

No such cookbook: simple_iptables

Alternative 2

I am still trying to make it work so I also tried making it "the berkshelf way", so I created a new cookbook.

berks cookbook test

And I added this line

cookbook 'simple_iptables', '~> 0.7.0'

To my Berksfile, as described in the Supermarket.

Then I added these lines to my default.rb file:

include_recipe 'simple_iptables'

# Allow HTTP, HTTPS
simple_iptables_rule "http" do
  rule [ "--proto tcp --dport 80",
         "--proto tcp --dport 443" ]
  jump "ACCEPT"
end

Executed berks install:

berks install

and ran it:

chef-client --local-mode --runlist 'recipe[test]'

The same error came back

Chef::Exceptions::CookbookNotFound
----------------------------------
Cookbook simple_iptables not found. If you're loading simple_iptables from anoth er cookbook, make sure you configure the dependency in your metadata

I tried adding it to the metadata:

depends 'simple_iptables', '~> 0.7.0'

But I still get an error:

Error Resolving Cookbooks for Run List:
Missing Cookbooks:

No such cookbook: simple_iptables

I looked at the ~/berkshelf folder and the cookbooks are there.

** Alternative 3 **

I started a CentOS 6.5 EC2 instance on Amazon, installed Ruby 2.1.3 and Chef. created a ~/chef-repo/cookbooks folder

I created a cookbook using berkshelf, ran

bundle install

added the reference/code as in the other alterantives then

berks install

and ran the same way I did last time.

I got the same issues.

What am I missing? What do I need to make it work?


Solution

  • Make sure you have configured your chef_repo_path as described in the docs.

    Basically local-mode needs to know where to find your cookbooks, roles, environments, data bags, etc. Sadly, the documentation is not super clear on where/how you set chef_repo_path

    Here's what I can tell from the code.

    1. if client.rb is found and contains cookbook_path, chef_repo_path = "#{cookbook_path}/.."
    2. if knife.rb is found and contains cookbook_path, chef_repo_path = "#{cookbook_path}/.."
    3. Chef can try to divine the path. The code will search from pwd upward looking for a directory called cookbooks. If it finds it, then cookbooks/.. will be set as your chef_repo_path.
    4. If all else fails, pwd will be used as your chef_repo_path

    If you are using Berkshelf, your best bet is to do a berks vendor in order to get a single directory will ALL of the cookbooks you need. You can then point chef_repo_path to the parent of the cookbooks directory which holds your vendored cookbooks.

    Mind you, that's from 10 minutes of digging in the source code, so I may not have it quite right.