Chef: Upload and re-apply a cookbook to a Node - ruby

This is kind of a n00b question, but the Chef docs don't help.
Say I changed the code of a cookbook. I upload it to my chef server. Ho do I apply the changes to my nodes using this cookbook?

As Draco commented, you run Chef on your node(s). They will automatically download the changed files in the cookbook from the server.
sudo chef-client
If you're running Chef as a service (setup via Opscode's chef-client cookbook service recipe or otherwise), it will automatically run at some point. Since you're using a Chef Server, you can also use knife ssh to perform a search and run the command on multiple nodes at one time.
knife ssh "*:*" "sudo chef-client" -x youruser
Replace ":" with any Chef Search Query.
Also, this is where Environments are useful, in that you can pin particular versions of cookbooks to nodes in an environment, so they don't get the changes that were made in the cookbook until you modify the version they're allowed to use. For example, if you have version 1.0.0 of your cookbook, and pin "production" to that ("= 1.0.0"), then increment the version (1.0.1) before uploading, then production nodes won't get the new version until the version in the environment is updated to the newer version.

Related

Unable to configure non-latest chef-dk install

Our organization has not upgraded to Chef 13 or 14, so we have to pin all our cookbooks to version 12. This means pinning to chef-dk version 1.6.11.
I'm spinning a centos7 vm in Vagrant with a cookbook and have set the version, but it will only install the Latest of chefdk, which results in the machine getting Chef 14. I've added a dependency in metadata.rb of chef_version ~> 12, so the provision fails, as Chef 14 is installed but the cookbook demands 12.
I should mention that the VM is for cookbook dev, so i want the right version of chef on it.
What am i missing to get the right version installed?
Thanks.
recipes/default.rb:
node.default['chef_dk']['version'] = '1.6.11'
node.default['chef_dk']['global_shell_init'] = true
include_recipe 'chef-dk'
metadata.rb:
depends 'chef-dk'
chef_version '~> 12.0'
berksfile:
cookbook 'chef-dk'
The part that is failing is the "outer" Chef, the thing running the recipe, not the ChefDK install (it never gets that far). We don't generally recommend using Chef to install ChefDK because installing both the chef-client and ChefDK installers on the same machine can lead to confusion as there are overlapping command line tools. I would provision the dev VM using a simpler system, probably a bash script or similar. We also do provide chef/chefdk Docker images on Hub for this kind of thing. (also we don't recommend doing cookbook development inside a VM at all, but I would guess that ship has sailed for you)

Testing chef cookbooks with Vagrant

I want to test my cookbooks on different environments using Vagrant.
As I've found, there are chef-client and chef-solo provisioners, used to respectively download cookbooks from chef-server and to serve cookbooks locally.
I want to provide Vagrantifle inside each cookbook in order to provide way to test it for all knife developers. If cookbook was standalone, I'd just use chef-solo provisioner, but what if it has (multiple) dependencies of cookbooks stored on chef-server?
What's the best idea to resolve this problem:
Download all cookbooks locally and copy it to Vagrant
Push only tested cookbook and download rest of them from chef-server
What are advantages and disadvantages? How should I test my cookbooks on different systems?
This is indeed what Test Kitchen is for. It has a driver for Vagrant, or you can use almost any other VM/cloud system imaginable via another driver plugin. It integrates with Berkshelf and the Policyfile system to handle dependency management, so you would use one of those (which hopefully you already are).

Chef-client run half copying cookbooks from site-cookbooks directory into cookbooks directory

I've got a custom cookbook that configures my Jenkins servers. There are 3 recipes in a custom cookbook. I'm using librarian-chef to manage my cookbook dependencies. Chef is being run in local mode and I use terraform to provision my nodes with Chef.
When I run chef-client -z it tries to copy my custom cookbook in the site-cookbooks directory into the cookbooks directory. The reason I say "tries" is because it only copies one of the recipes over, it doens't copy the other recipes or other cookbook files like metadata.rb. Ultimately I get errors on including the java cookbook in my recipe because it can't resolve that cookbooks dependencies.
If I manually log into the node and copy the directory over myself, everything runs perfectly.
This bug is resolved in latest stable version of chef. You can try that

chef workstation setup softwares required

I am trying to execute chef commands and build the server for that I did below setup on MacOS but observed that I need to have vagrant and virtualbox but I am not sure if I need to install it on host macOS machine or Virtual machine. Could you please suggest on this.
Setup which I did so far is as below:
On Mac OS I have installed VirtualBox and created a base ubuntu Virtual Machine
Then Inside virtual machine having ubuntu as OS installed ChefDk, Hosted chef server setup, knife and git
created chef-repo repository
In order to complete setup, Do I need to install vagrant and one more instance of Virtualbox inside virtual machine on ubuntu OS and do I need any additional installation?
Install ChefDK and Vagrant as well as VirtualBox on your workstation. This allows you to use any editor/IDE to edit cookbooks and then provision a VM using Vagrant and Virtualbox (or other supported hypervisors).
In general, I would recommend to follow Learn Chef.
Honestly, the question is a little confusion on your objective. But from a high level, i can assume that you are trying to get started with chef using the hosted chef server. First i agree with #StephenKing pointing you to the learn chef site. That's a good starting point. But here are some things that should clear up your question:
Typically there will be a development workstation. In your case its the MacBook. This is where you will install chefDK and write your fancy cookbooks. It should have the chef-repo, knife.rb etc to talk with the chef server.
Once your initial cookbook writting is over, you upload the cookbook and other params like environment, data_bags, roles etc to the chef server (in the chef-org)
Its here you need a node to apply your cookbook. As a starter, use some nodes from a VPS that's far more easier rather then trying to use vagrant nodes or something. As the saying goes "one step at a time". Do not try to learn chef and vagrant or even more (which is what you will encounter with chef) at the same time.
Once you have the node, bootstrap the node to your chef-org where the cookbooks were uploaded. Then run chef-client on the node.
And you are on your way to the chef world.

Where is the PATH in a Chef Run (Omnibus installation) enforced/configured?

I am trying to build a development box via Vagrant/Chef-solo, based on Centos 6.4 and using vagrant-omnibus (1.1.2) to ensure the box is using the latest Chef (while creating/putting together the cookbooks, then I'll probably freeze the version). Currently it installs 11.8.2.
One of the cookbooks is using ruby_build to install Ruby 2.0.0-p353 and then create symlinks under /usr/local/bin so that Ruby is available to all users after the chef run is complete. It also installs some gems which installation I want to enforce system-wide.
The thing is that using the gem_package resource after the ruby_build execution installs the gem in the embedded ruby from the Chef Omnibus installation. Until now I worked around that using the gem_binary option to force the detection of the system-wide Ruby environment but it got me thinking and so I checked which PATH is used during the Chef run (using a shell_out to print the PATH to a file) and found out it shows the following:
/usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/opt/chef/embedded/bin:/opt/chef/embedded/bin:/usr/local/bin
Where does that come from? How/Why is /opt/chef/embedded/bin added before /usr/local/bin?
The answer is:
Vagrant uses ssh to log in to the guest box as the 'vagrant' user. This adds the sshd_config secure path. In CentOS 6.4 that's:
/sbin:/bin:/usr/sbin:/usr/bin
Then it uses sudo to become the 'root' user. The profile get's sourced and in CentOS 6.4 that means sbin paths are prepended, while $HOME/bin is appended.
Then chef-solo runs and path sanity is enforced. Path sanity appends all paths (if not part of the existing $PATH) at the end, starting with ruby_bindir and gem_bindir (which refer to the Chef Omnibus installation). Then, every other sane path is appended if not part of $PATH already, which is why /usr/local/bin is at the very end.
As Mark O'Connor mentioned, for gem_package the gem_binary option can be used to for a certain gem. For other resources the full path can be specified. For shell_out! though, if a command is to be executed as a user with a login shell first the environment needs to be emptied (enviroment: { 'PATH' => nil } and bash -l -c used to execute the desired command.
I would recommend specifying the path to the gem command of the target ruby:
gem_package "mypackage" do
gem_binary "/path/to/my/ruby/distro/bin/gem"
end

Resources