Lately I've been pretty deep into the Chef weeds and the more I end up working on it, the more I keep finding these little tips and tricks on how to get something done, some of these come from Seniors that passed them on to me and some of them I either end up finding online or figuring them out so would like to share them in case someone finds them useful.
Need to run a command and use the output for something?
There is the execute
or ruby_block
resources but what if you need the output of something to determine if a resource should run or not?. Maybe its a guard for another resource in your recipe, simple, use the mixlib/shellout
library. Should be installed since it's part of Chef SDK.
require 'mixlib/shellout'
find = Mixlib::ShellOut.new("find . -name '*.rb'")
find.run_command
# Grab the output either good or bad
puts find.stdout
puts find.stderr
Copy a local cookbook to a node with chef installed
If you ever need to see how your cookbook will be applied to a machine but you are not ready yet to push it out to your chef server?. I gotchu, you can simply zip the entire cookbook and copy it over to a node and then apply a new runlist!.
- Copy the tarball and put it somewhere
- Modify the client.rb to point to a directory holding the cookbooks (it must contain the metadata.rb)
- Edit the client.rb so it fetches from a local path, the cache location is a good spot since it already has your cookbooks.
cookbook_path /var/cinc/cache/cookbooks
- Run cinc client in solo mode and specify the runlist, it is important you run this with
-z
so its done insolo
mode. Meaning it won't reach out to the chef server to fetch data.
cinc-client -z -r "yourcookbook::recipe"
Your cookbook should now be applied to the instance, hack away!
Test a resource before putting it in a cookbook
In a node with cinc installed you can enter into the shell and go inside recipe_mode
to test out resources. If you are happy with them you can later run run_chef
to actually execute them against a node. This is great to test and design cookbooks.
cinc-shell -s
cinc (17.9.26)> recipe_mode
cinc:recipe > git '/tmp/dotfiles' do
cinc:recipe > repository 'https://github.com/mvaldes14/dotfiles.git'
cinc:recipe (17.9.26)> end
=> <git[/tmp/dotfiles] @name: "/tmp/dotfiles" @before: nil @params: {} @provider: nil @allowed_actions: [:nothing, :sync, :checkout, :export, :diff, :log] @action: [:sync] @updated: false @updated_by_last_action: false @source_line: "(irb#1):1:in `<main>'" @guard_interpreter: nil @default_guard_interpreter: :default @elapsed_time: 0 @declared_type: :git @cookbook_name: nil @recipe_name: nil @repository: "https://github.com/mvaldes14/dotfiles.git">
cinc:recipe (17.9.26)> run_chef
[2022-10-12T20:56:21-05:00] INFO: Processing git[/tmp/dotfiles] action sync ((irb#1) line 1)
[2022-10-12T20:56:22-05:00] INFO: git[/tmp/dotfiles] cloning repo https://github.com/mvaldes14/dotfiles.git to /tmp/dotfiles
[2022-10-12T20:56:23-05:00] INFO: git[/tmp/dotfiles] checked out reference: 5c362e70aaa0c51055df0c7015582d89ab3e1017
=> true
See attributes on instance
This is useful to debug if an attribute does not behave as you expected or if you have a lot of overrides and don't know which one is the final one being kept. Also helpful in case ohai
replaces something you were expecting.
If its in a kitchen converge do
cd /tmp/kitchen
cinc-shell -c client.rb -j dna.json
node['attribute']
If it is an already bootstraped instance then
cinc-shell -z
node['attribute']
Run systemd inside of test kitchen with dokken
This is pretty useful if you are not using vagrant to test out your kitchen instances and prefer something quicker like Docker, which works great except when you need to interact with systemd to actually start/enable a service you just installed. For those scenarios you can simply pass or mount
part of your cgroups so systemd runs inside the container.
NOTE: This only applies if you are using NIX as the base machine to develop your cookbooks, for other OS I honestly have no clue... maybe just use vagrant.
Your kitchen.yml should looks something like this.
driver:
name: dokken
transport:
name: dokken
provisioner:
name: dokken
verifier:
name: inspec
platforms:
- name: centos-7
driver:
image: centos:7
privileged: true
pid_one_command: /usr/lib/systemd/systemd
volume:
- /sys/fs/cgroup:/sys/fs/cgroup:ro
Those are some of my most precious tips so hopefully they serve you well.
If you got more tips on how to do magic things in Chef please do let me know so I can learn and include them into my blogs and wikis!.
Until the next one, adios 👋