Skip to main content

Chef – Available Testing Frameworks – InSpec and ChefSpec

Hands-On Lab

 

Photo of

Training Architect

Length

01:00:00

Difficulty

Intermediate

In this lab we will demonstrate an understanding of Chef Testing Frameworks by using InSpec and Chefspec with ChefDK, and then by using Chef Kitchen. First we'll install the ChefDK tools on a server and make sure that Docker is working. Then we need to ensure that Git is installed and has some basic configuration. Next we'll see how much we know about local cookbook development by creating one that installs software and uses InSpec and ChefSpec. At the end of this hands-on Lab, we will have installed ChefDK tools, configured it, and have a custom developed cookbook that we've tested with Docker and Kitchen.

What are Hands-On Labs?

Hands-On Labs are scenario-based learning environments where learners can practice without consequences. Don't compromise a system or waste money on expensive downloads. Practice real-world skills without the real-world risk, no assembly required.

Chef - Available Testing Frameworks - InSpec and ChefSpec

Introduction

In this lab we will demonstrate an understanding of Chef Testing Frameworks by using InSpec and Chefspec with ChefDK, and then by using Chef Kitchen.

First we'll install the ChefDK tools on a server and make sure that Docker is working. Then we need to ensure that Git is installed and has some basic configuration.

Next we'll see how much we know about local cookbook development by creating one that installs software and uses InSpec and ChefSpec.

At the end of this hands-on Lab, we will have installed ChefDK tools, configured it, and have a custom developed cookbook that we've tested with Docker and Kitchen.

Instructions

We have several tasks that need to be completed:

  1. Set up the environment for use with the rest of the tasks by installing Chef, Docker, Git and the Chef gem for Docker:
    • Install version 2.4.17 of the ChefDK tools.
    • Install Docker CE and all that it requires, start it up, then make it start at boot:
      • Modify our group membership so we don't need to run sudo all the time.
    • Install Git, and configure a name, email, and default editor.
    • Install the gem allowing Kitchen and Docker to work together.
    • Set SELinux to allow us to work through the rest of the steps.
      1. Create a cookbook called la_testing.
      2. Modify the default .kitchen.yml to use Docker and Centos 7.
      3. Update the default recipe to install Net Tools and Apache.
      4. Update the InSpec test to test Net Tools and Apache.
      5. Update the ChefSpec test to both remove Ubtuntu tests and add tests for Net Tools and Apache.
      6. Run the tests for ChefSpec via the rspec command. Tests should pass.
      7. Use the correct kitchen command to test whether or not the cookbook will converge properly.
      8. If there are problems, fix them and test again.

If you need help with these tasks, please see the accompanying video or hands-on lab guide.

Logging In

Using the credentials provided in the hands-on lab page, log into the server as cloud_user and we can get going.

On the Provided Server, Install Version 2.4.17 of the ChefDK Tools

We need to download the correct version of ChefDK, which is 2.4.17. In a command line, run:

wget https://packages.chef.io/files/stable/chefdk/2.4.17/el/7/chefdk-2.4.17-1.el7.x86_64.rpm

Now install it:

sudo rpm -ivh chefdk-2.4.17-1.el7.x86_64.rpm

Once it's installed, we need to make sure Chef uses the correct system locations for things:

echo 'eval "$(chef shell-init bash)"' >> ~/.bash_profile
source ~/.bash_profile

Now check to see if it worked with which ruby, and we should see /opt/chefdk/embedded/bin/ruby get returned.

Install What docker-ce Requires on This Server

We need Docker on our workstation, so we will need to install the yum-utils, add the Docker repository, and install Docker.

sudo yum -y install yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum -y install docker-ce

Now let's set Docker to start now, and on system boot:

sudo systemctl start docker
sudo systemctl enable docker

We should also set your user to be able to use Docker without using the sudo command. Once we've done this, we have to log out and back in again:

sudo usermod -aG docker $USER
exit

Use SSH to get back in again, and check to make sure Docker is running:

docker ps

If we can do that without prefacing it with sudo, we're ready to continue.

Install Git and Set Some Global Defaults for Our User, Email Address, and Editor

When we use Kitchen, later in the lab, we need Git to be installed and set up with some basic information. These commands will make that happen:

Install it:

sudo yum -y install git

Configure some Git basics, like the username, email address, and a default text editor:

git config --global user.name "USERNAME"
git config --global user.email "YOUREMAIL@DOMAIN.COM"
git config --global core.editor vim

Note: We can use fake email information, since we don't actually use it for this lab. It just needs to be set or we will get errors later.

Install the Gem Required for Using Docker with the Test Kitchen

Docker requires a gem for this all to work. Install it with this:

gem install kitchen-docker

Update SELinux to Be Permissive

To perform the tasks properly you should change SELinux so that it is permissive:

sudo setenforce permissive

We should also /etc/selinux/config and change things to permissive there too:

sudo vim /etc/selinux/config

Create a Cookbook for Use with These Tasks, and Call It la_testing

Create the cookbook with this command:

chef generate cookbook la_testing

Now get into the newly created directory:

cd la_testing

Edit Our Kitchen File

We need to change some things in kitchen.yml, so let's edit it:

vim .kitchen.yml

In the top section, we're going to replace vagrant with docker, and add some things. When we're done, that top section should look like this:

---
driver:
  name: docker
  privileged: true
  use_sudo: false

Remember that this is YAML, so we need to make sure we have the right number of spaces in spots. Those lines under driver are all indented two spaces.

Down in the provisioner section, we need to add a name and version. It should look like this when we're done:

provisioner:
  name: chef_zero
  # You may wish to disable always updating cookbooks in CI or other testing environments.
  # For example:
  #   always_update_cookbooks: <%= !ENV['CI'] %>
  always_update_cookbooks: true
  product_name: "chef"
  product_version: "13.8.5"

We're on a CentOS machine, so we need to get rid of ubuntu from the file. Just delete (or comment out) the line in the platforms section that reads:

  - name: ubuntu-16.04

That's it for kitchen.yml edits. Write and quit, so that we can get back to the command prompt.

Edit Our Recipe

We need to get the net-tools and httpd packages installed, so add this text to the end of the recipe. So run this:

vim recipes/default.rb

And add this to the end of the file:

['net-tools','httpd'].each do |pkg|
  package pkg do
   action :install
  end
end

Update the InSpec test to test Net Tools and Apache

Edit the Inspec test:

vim test/smoke/default/default_test.rb

Down at the end of this file, we need to add:

['net-tools','httpd'].each do |pkg|
  describe package(pkg) do
   it { should be_installed }
  end
end

Update the ChefSpec Test, Removing Ubuntu Tests and Adding Tests for Net Tools and Apache

We've finished the InSpec portion of our tests, now let's edit the ChefSpec test so that it does what we need it to.

vim spec/unit/recipes/default_spec.rb

Here, we want to remove any reference to Ubuntu tests. So let's erase lines 10-22 (the whole first context section):

  context 'When all attributes are default, on Ubuntu 16.04' do
    let(:chef_run) do
      # for a complete list of available platforms and versions see:
      # https://github.com/customink/fauxhai/blob/master/PLATFORMS.md
      runner = ChefSpec::ServerRunner.new(platform: 'ubuntu', version: '16.04')
      runner.converge(described_recipe)
    end

    it 'converges successfully' do
      expect { chef_run }.to_not raise_error
    end
  end

We should just have a CentOS section now. Let's add our test to this (for Net Tools and Apache). The whole section should look like this:

describe 'la_testing::default' do
  context 'When all attributes are default, on CentOS 7.4.1708' do
    let(:chef_run) do
      # for a complete list of available platforms and versions see:
      # https://github.com/customink/fauxhai/blob/master/PLATFORMS.md
      runner = ChefSpec::ServerRunner.new(platform: 'centos', version: '7.4.1708')
      runner.converge(described_recipe)
    end

    it 'converges successfully' do
      expect { chef_run }.to_not raise_error
    end

    it 'installs httpd' do
      expect(chef_run).to install_package('httpd')
    end
    it 'installs net-tools' do
      expect(chef_run).to install_package('net-tools')
    end
  end
end

Save this file, and let's run some tests!

Run the ChefSpec Test

We're going to run the ChefSpec test that we just altered, with this command:

chef exec rspec --color -fd

If everything passes, we can move on.

Trust, but Verify, with Kitchen

To test if this cookbook works, we'll run:

kitchen verify

You may also notice, in the end of the output, that our InSpec test gets run. If that all looks good, we're done. Clean up the mess with this:

kitchen destroy

Conclusion

Well, we've done what we set out to do. We took a fresh server, built some framework, and were able to develop a simple cookbook that will install a couple of packages. But people don't just have to take our word for it. We actually tested with InSpec and ChefSpec. Congratulations!