Ever since I started learning to remediate my InSpec test failures, I started learning bits and pieces of Chef. I started out in the Test Kitchen, quite appropriately, and since then I’ve been learning how to zoom out little by little to see the forest for the trees.
And because this blog serves selfishly as a place to store all of my notes for future use but also a place where noobs ( I really prefer newbs, but whatev) like me can benefit, I’m going to share my current notes for how I started from scratch and now currently maintain the process of Cheffing up my pipeline.
Here’s what I’ll do:
- Set up connection from local machine to Chef server
- Bootstrap the node
- Do the Real Work Now
- Install and upload policy to Chef server
- Converge the node
- Scan for compliance errors on Compliance server
Set up connection from local machine to Chef server
First, I need to have an account on manage.chef.io so that my local computer can talk to their server. This establishes a connection for communication. After that I’m able to upload all of my cookbooks to the server so that I can converge any node I want to with those cookbooks.
- Create
chef_repo
folder (You can call it whatever you want.) - Inside that, create
.chef
folder (You can’t call it whatever you want.) - On the Chef server in my web browser, click on Admin tab and click on my organization
- Click Generate Knife.rb
- Go to Users and select my user
- Click Reset key and click download
- Copy those files from the Download folder to the
.chef
folder - Run
knife ssl fetch
Bootstrap node
The next thing I need to do is set up a line of communication between my the node(s) and the Chef server. This, however,
is done on my local machine. The knife bootstrap
command installs chef-client
on the node that I’m bootstrapping.
This process now allows my node(s) to communicate with the Chef server. And the Chef server makes the cookbooks
available to the node(s) for convergence.
- On my local machine, I’m going to run
knife bootstrap
knife bootstrap <ipaddress> -x <nodeUsername> -P <nodePassword> --sudo --policy-group <PolicyGroupName> --policy-name <nameInPolicyfile> -N <NodeName>
- Now I’m going to go to my node, and I want to ensure that the following lines are in
/etc/chef/client.rb
policy_name "\<your-policy-name>\"
policy_group "\<your-policy-group-name>\"
use_policyfile true
Do the Real Work Now
This is where I’d start if I had already completed the setup of my connection to the Chef server and bootstrapped my node. So for all the rest of my check-ins, I’ll need to double-check that all of this is complete before I make any changes to my policy.
- Code changes for cookbook
- adding / editing cookbook files
- adding / editing InSpec profiles
- Make sure everything passes
- Converge all resources successfully in Test Kitchen.
- All tests pass.
- Update version in
metatdata.rb
- Commit and push to GitHub
- Now I’m ready to put this version into production
Install and upload policy to Chef server
First of all, I know that you have two options here. You can go the policy file route, or you can use Berkshelf. Michael taught me the policy file route because that’s his preference, and so I tasked him with writing his own blog post to explain why. I’ll update you when he does.
So anyway, when I install a Policyfile in a cookbook, I’m then able to tell it all the other cookbooks that I want to run at the same time and where to find them. So then the Chef server knows which cookbooks to put on which nodes because the nodes tell it which policy they have.
- On your command line, from your cookbook directory in which the Policyfile.rb is located, remove
the
Policyfile.lock.json
file if it exists by usingrm Policyfile.lock.json
- Run
chef install
- Run
chef show-policy
to get the Policy Group name as it shows the active policies for each group. It will be after the asterisk. - Run
chef push <policyGroup> Policyfile.rb
(may have to usesudo
) - Run
chef show-policy
again to show the active policies for each group. The ID it uses should match the ID inside the json file. (It’s the first numberrevision_id
, and it will only give you the first 10 digits.) - Commit to Git so that you can have a history of the json for every time you do this. (You can call it
updated policy
in your commit message.)
Converge the node
When I’m converging a node, I’m basically running the chef-client
command which runs all the recipes and cookbooks
that are in the Policyfile on the node(s).
- On a new terminal, open an ssh session to the node.
- Run
sudo chef-client
Scan for compliance errors on Compliance server
After I’ve converged the node(s), then I want to scan them so that I can see what, if anything, still needs to be remediated. You can go here to my Tour of Chef Compliance if you need help remembering how to set it up.
- Update your version number in the .yml file on your InSpec profile.
- Compress the profile directory.
- Upload the latest version of your profile to Compliance.
- Add your node(s) to be scanned (check if IP address of VMs changed)
- Scan your node(s) with the latest version of your profile.
Next Step…Get Jenkins to do this for me
Concluding Thoughts
I’ve had a few conversations recently about how I started my journey into technology in a bit of a backwards manner - learning the upper level stuff like automation instead of the foundational things like networks and hardware and a bunch of stuff that I don’t know. But I really just wanted to start where there was a lowered barrier to entry and where the greatest demand for skills was, and I see that to be automation. My hope is that the foundational things will come in time and that the further I go in this journey, the clearer it will become where I should spend my time learning.