Get Cookin’ with Chef
Hello, Level1Techs!
During this guide you will become intimately familiar with Chef, a configuration management system. Chef targets nodes in your control with status files and configures those nodes to meet the state declared in those files, if not already there. Phew, what a mouthful. But! After this walkthrough and demonstration, I hope you are as excited to get started with Chef and configuration management as I am!
First, for this demonstration, you will need three computers. All three can be VMs, physical, whatever. This guide is going to use RedHat Linux derivatives, but hopefully I can write well enough to provide enough understanding that you can go Debian or Windows based OS’es if you so choose.
So, here we go!
The Workstation
I am using Fedora 28 for my workstation. From a vanilla install, you’ll need the Chef Development Kit. To get the most recent version head on over to https://downloads.chef.io/chefdk and find the link for your operating system.
Being a fan of wget, I used that to fetch the source.
wget https://packages.chef.io/files/stable/chefdk/2.5.3/el/7/chefdk-2.5.3-1.el7.x86_64.rpm
From here, I used dnf to install the rpm. Why dnf? The cool bit about DNF is it checks for dependencies missing that are needed for the rpm, and it will install those as well. If you prefer rpm, or aren’t using Fedora, but RHEL or CentOS, check out the second command.
sudo dnf install chefdk-2.5.3-1.el7.x86_64.rpm
Or
sudo rpm -Uvh chefdk-2.5.3-1.el7.x86_64.rpm
If you’re not familiar with rpm, the U will check if the software is installed and update it to the latest version or install the latest version if it’s not there. The v is for verbose, and the h is for the “hashtag” progression.
You’ve got your workstation up and running. Fantastic! To confirm success, go ahead and run
chef --version
w00t! WHO’S THE (WO)MAN?! YOU ARE!
*Chest bump bro out fist smash keg party*
Now let’s get your server up and running.
The server
You’ll need wget installed:
sudo yum install wget -y
Then you’ll pull the latest Chef server installation. (https://downloads.chef.io/chef-server)
wget https://packages.chef.io/files/stable/chef-server/12.17.33/el/7/chef-server-core-12.17.33-1.el7.x86_64.rpm
The server is a lot beefier than the DK, so don’t be concerned if it takes a bit longer to download.
sudo rpm -Uvh chef-server-core-12.17.33-1.el7.x86_64.rpm
With this install comes a template, and your server is not in the desired state. To reach that desired state, you’ll want to run:
sudo chef-server-ctl reconfigure
This could take a while, depending on the specs of your server. Don’t worry, just sit back and enjoy the console output, or go get a cup of coffee.
Now that that is done, we’ll want to install the GUI, which is a web front end.
sudo chef-server-ctl install chef-manage
Then, you’ll run reconfigure for chef-server (again) and you’ll reconfigure chef-manage. The second time around, chef-server doesn’t take nearly as long because most of the desired state is set.
sudo chef-server-ctl reconfigure
sudo chef-manage-ctl reconfigure
Nice, still in the game? GOOD!
Let’s create our admin user. The format is:
chef-server-ctl user-create userName userFirstName userLastName userEmailAddress ‘password’
You’ll want to put your password in single quotes. There are a couple of optional variables, but this is the base template to get you into the web front end.
Open a browser and hit up your chef-server IP Address
A note about firewalls and DNS
If you’re doing this exercise as an “on prem” exercise, versus Azure, AWS, or another cloud platform, you might run into some DNS issues.
The easiest way to remedy that is add an entry to /etc/hosts for the Chef server.
ip-address-of-chef-server chef-serv
That should do it for you. So, mine is
10.0.0.110 chef-serv
You can always add an entry to your DNS server, but that is outside the scope of this demonstration (you sysadmin, you ).
Next, if you’re having an issue accessing the Chef server from the browser, either disable the firewall on the server or add a public zone entry for http and https. Again, unfortunately, that is outside the scope of this demonstration. I just wanted to offer a heads up in case you ran into an issue.
Once you log into the Chef server with your new user, you’re going to have to create an organization. The first entry can be as elaborate as you want.
“Super Awesome Tech Company, LLC”
The next line you’ll want to have something small and simple.
“awesome-tech”
Next, you’ll be given two links, one to download the starter kit and another to “Learn Chef”. Hopefully I’m doing an okay job, so go ahead and click Download Starter Kit. You’ll get a zip file on your workstation, which you can unzip with… unzip.
unzip chef-starter.zip
That is going to extract a chef-repo directory, which you can move wherever you desire.
I strongly recommend creating a ~/chef directory and moving the chef-repo there. You can also create a ~/Projects directory if that makes you feel better
Either way, once you have your chef-repo directory where you desire it most, we can create our first cookbook!
The Node
At this point you’re going to want to fire up a third VM. This can be whatever you want, but for this example, I am using CentOS 7. It is the base install, with nothing on it.
From our workstation, we are going to bootstrap the node. The bootstrap process primes the node for receiving communication from the Chef server. You’ll also name the node for configuration purposes.
From the workstation, run:
knife bootstrap *IP Address of Node* -N *name you desire for your node* -x *user with sudo permissions* --sudo
Knife is an awesome command, it allows you to interface with the Chef server from your workstation. In the above command, you’re essentially sending the chef-client payload instructions to the server and directing the execution of the command on the node. You’ll need to enter the password a couple of times in some instances, once for ssh connection and another for sudo permission.
Watch the command execute, and you can check the server by either checking your Chef server GUI for the node or ssh into the node and run
chef-client
You can also run, from the workstation:
knife node show *name you gave to the node*
Great job! Almost there! But, we kind of have a node reporting to Chef server, and not much else… So, let’s give a desired state.
Remember the chef-repo directory? Good, go ahead and cd into that and go into the cookbooks directory.
From here, you’ll want to pwd and make sure you’re in ~/…/chef-repo/cookbooks
Go ahead and create your first cookbook. We’ll call it apache, for demonstration purposes.
chef generate cookbook apache
Ta-da! Magnifique!
Now, we’ll cd into apache/recipes, and you’ll have your default.rb file. This is kind of like “main” for big programming languages.
Use your favorite editor, Sublime, Atom, vim, Emacs, Visual Studio Code, whatever, and open up that file.
It’s blank, with some generic comments as the templates. No biggie. We’re going to create some cool stuff.
package 'httpd' do
action :install
end
service 'httpd' do
action [:enable, :start]
end
This is one of the beautiful things about Ruby and Chef, is the above needs little to no explanation. We have a package called httpd, and we want to install it. Then, we have a service called httpd, and we want to enable and start that service.
This is the equivilant to running
sudo yum install httpd -y
sudo systemctl enable httpd && sudo systemctl start httpd
But, we have reusable, scalable code that we can use and tailor to fit any series of servers and workstations that we see fit. You can use some cool features of ruby and Chef to see if the code checks out.
ruby -c default.rb
foodcritic default.rb
Foodcritic might have given some weird errors. Does it make sense? What do you think the issue is?
Hint:
Checkout the README.md in the apache directory, I’m sure you’ll find something TODO.
So, how do we use our recipe?
First, we need to upload the cookbook to the server. Backup a few directories, so you’re in the ~/chef-repo directory.
Then, use knife to upload the cookbook.
knife upload cookbook apache
And you’re set.
Syncing Recipes to Nodes
At the basic level, you can create a run list with a series of recipes for nodes. At a complex level, you can assign various cookbooks, recipes, and dependecies into roles and create a run list with a series of roles for nodes. This early, we’re just going to go over the single recipe.
From your workstation
knife node run_list add *name of node* 'recipe[apache]'
knife node show *name of node*
The first command will associate your recipe from the apache cookbook to your node, and the second command will verify that the recipe is now part of the run list.
Now, to execute chef-client, we can use knife.
knife ssh 'name:*node name*' 'sudo chef-client' --ssh-user *user with sudo permissions* --identity-file *This will be in ~/chef-repo/.chef/user.pem* --attribute ipaddress
For --attribute you want to actually type in “ipaddress”, you don’t need to type in the number, this is telling knife what it’s using to ssh into. Your identify file came with the Starter Kit. It’s name_of_user.pem, so whatever your user’s name is, it’s probably that with a .pem appended.
But! From here you can see that httpd was successfully installed, enabled, and started successfully. If you have a firewall disabled, you can go ahead and visit the IP Address of the node for the landing page. If you have a firewall, you can disable it, or add some code to your “default.rb” in ~/chef-repo/cookbooks/apache/recipes/default.rb
execute 'firewalld_rule' do
command '/usr/bin/firewall-cmd --permanent --zone=public --add-service=http'
end
execute 'firewalld_rule' do
command '/usr/bin/firewall-cmd --permanent --zone=public --add-service=https'
end
execute 'firewalld_reload' do
command '/usr/bin/firewall-cmd --reload'
end
cd back to ~/chef-repo/cookbooks and do a knife upload cookbook apache to upload the current cookbook. If you want to do what the pros do, edit ~/chef-repo/cookbooks/apache/metadata.rb and change the version, since you did a pretty decent update. Then upload the cookbook.
From there, we’ll do another knife ssh
knife ssh 'name:*node name*' 'sudo chef-client' --ssh-user *user with sudo permissions* --identity-file *This will be in ~/chef-repo/.chef/user.pem* --attribute ipaddress
And, check out the IP Address of the node in the browser. BAM! Apache landing page!
What’s REALLY cool is, later on, when you get roles, you can knife ssh based on role instead of node names, so every node with the role in the run list will receive that ssh command.
Chef is an amazing tool, and the service is free for up to 25 nodes. I hope you enjoyed this intro demonstration. If this garners enough attention I will definitely add to it. Others feel free as well, we can get the whole LAMP stack built.
Useful Links
https://downloads.chef.io/chefdk
https://downloads.chef.io/chef-server
https://linuxacademy.com/devops/training/learningpath/name/certified-chef-developer