Skip to main content

Chef-Kitchen Do it simply..


If you are from agile background you would be already aware about the importance of testing your code as you develop. As DevOps SCM tools are maturing where we try to have our complete infrastructure as code it becomes a dire necessity to have our infrastructure code to be tested as well. In this blog I'll showcase how I'm using the testing capability of Chef to test our Chef code.

Prerequisites

This blog assumes that you have a basic understanding of Chef, Docker, Git and Vagrant. This blog is written in consideration with centos as platform. You can follow same procedure for ubuntu with some basic changes.

Setup Kitchen
Clone from our github repository to spin up a vagrant with kitchen and other chef tools.


  • Go to testkitchen directory.  

$ cd  Chef/centos/testkitchen


This directory includes a Vagrantfile, a cookbook and a knife.rb file.


  • View vagrantfile for provisioning.
This Vagrantfile have some basic vagrant provisioning with shell.
$ cat Vagrantfile

This file provision your vagrant using shell.


As this block contains a lot of stuff. FIrstly this need two rpm files to be placed in current directory (i.e. vagrant/chef/centos/testkitchen). Download these rpm using following commands. This vagrantfile uses centos/7 as base box.

$ wget ftp://195.220.108.108/linux/centos/7.2.1511/extras/x86_64/Packages/epel-release-7-5.noarch.rpm

Next in this block we are installing docker and rvm to manage our ruby version to 2.2.4.

  • Spin Up Vagrant box
$ vagrant up

This will perform everything for you. And creates a running vagrant with centos7 platform. Next login into this vagrant box using following command.

$ vagrant  ssh

Your testing environment is ready and you are all set to use kitchen to test and verify your cookbooks in different platforms using docker container.  

Test your first cookbook  

Change directory to /vagrant. /vagrant directory is shared between host and guest machine.

$ cd /vagrant

This cloned repo has its first cookbook “helloworld” in cookbooks folder. This cookbook creates a directory and place a hello.txt file in it.

Go to /vagrant folder and start using kitchen.
  • Initialize kitchen

$ kitchen init --driver=docker


This command initialize mandatory stuff to start with your kitchen. This creates  .kitchen.yml, chefignore file and a test folder.
.kitchen.yml file is the main configuration file for kitchen. This file contains mainly 4 blocks driver, provisioner, platforms and suites.
    • Driver:  This is the name of driver that is used to create new node for testing
    • Provisioner: This is the chef provisioner to simulate test, chef-zero and chef-solo are the options.
    • Platforms: This is the type of platform on which kitchen runs test eg. ubuntu-14.04 and centos-7.1
    • Suites: This is the collection of test suites with runlist and attributes.
       

Chefignore file determine which files to ignore when uploading cookbooks.
Test folder contains all test files running over the cookbooks.

  • Install required gems
Install required gems by using bundle. As your directory contains a Gemfile where gems are described with their specific version.  
$ bundle install

Then to verify run following command.

$ gem list kitchen
As this install two essential gems kitchen-docker and test-kitchen.

  • List all  your nodes.
$ bundle exec kitchen list
This command list all your nodes with last action performed on them.

Start kitchen cycle

  • Create your node using following command
$ bundle exec kitchen create

    • This command pulls image of docker if they are not present locally.
    • Install  openssh-server and other essential packages in newly created docker container.
if get “Kitchen is finished.” as final output. Now verify with kitchen list once again.


  • Converge your node
This step deploys your cookbook to newly created node. So let's tell kitchen which cookbook to run. Edit .kitchen.yml file and add recipe in runlist attribute of suits block.
Now run following command to converge your node.

$ bundle exec kitchen converge

    • Chef solo and dna.json got prepared and pushed into node /tmp/kitchen directory
    • This will put cookbook into the node and install chef by performing an Omnibus package installation.
    • Chef run initiated with information in .kitchen.yml file.
Verify again with kitchen list.

  • Login into node
$ bundle exec kitchen login  default-ubuntu-1404
&&
$ bundle exec kitchen login  default-centos
    • Login into node and manually verify /data directory and hello.txt file in it.

  • Verify your cookbook
Look into test directory structure.

As this directory contains “default” folder this is corresponding to your suit name i.e. default. Now create a directory structure to put files in particular location.

    • Use Bats to create test

$ mkdir -p test/integration/default/bats

Busser is the component which provides facility of testing in your node. Bats directory tells kitchen to which Busser runner plugin needs to be installed on the remote instance. In other words the bats directory name will cause Busser to installbusser-bats from RubyGems.

      • Write first test file.
$ vim  test/integration/default/bats/hellotest.bats

#!/usr/bin/env bats

@test "/data directory found in path" {
 run stat /data
 [ "$status" -eq 0 ]
}

@test "hello.txt file found in path" {
 run stat /data/hello.txt
 [ "$status" -eq 0 ]
}
      • Run kitchen verify

$ bundle exec kitchen verify

Now verify again with kitchen list, and see last action.

    • Use serverspec to create test
$ mkdir -p test/integration/default/serverspec

      • Write a test
$ vim  test/integration/default/serverspec/hellotest_spec.rb

require 'serverspec'

# Required by serverspec

set :backend, :exec

describe "file hello.txt status" do
 it "file hello.txt" do
   expect(file("/data/hello.txt")).to exist
 end
end

      • Run kitchen verify

$ bundle exec kitchen verify

Now verify again with kitchen list, and see last action.



  • Destroy your node
$ bundle exec kitchen destroy

This will destroy your node.

Kitchen test

$ bundle exec kitchen test

Kitchen test is an option to perform complete kitchen cycle with one command. This destroy existed nodes and then create, converge, verify node with your predefined suit in .kitchen.yml. And finally it destroy the node.

Now your cookbook is tested. So feel confident to use it.  

Comments

  1. Công ty vận tải chúng tôi chuyên cung cấp dịch vụ vận chuyển hàng hóa đi Nha Trang để đáp ứng nhu cầu chuyển hàng cho quý khách về Nha Trang trong dịp tết với dịch vụ vận chuyển quà Tết để đáp ứng nhu cầu đó.
    Các dịch vụ vận chuyển hàng hóa khác:
    - Dịch vụ vận chuyển hàng hóa đi Hà Nội
    - Dịch vụ vận chuyển hàng hóa đi Đà Nẵng
    - Dịch vụ vận tải hàng hóa đi Phú Quốc
    Liên hệ: Mr.Tài – 0166 944 5753 >< zalo
    skype: nguyentaiachau94
    mail:nguyentaiachau@gmail.com
    https://www.facebook.com/vt.bacnam/?ref=bookmarks

    ReplyDelete
  2. dù rằng còn hơn 1 tháng nữa mới tới Tết Nguyên đán 2017 nhưng tại Hà Nội, phổ biến cây đào bích, đào phai đã sớm khoe sắc trên giàn phơi đồ thông minh.

    Vừa tìm cành đào phai tại chợ hoa truyền bá, bà Nguyễn Thị Liên (51 tuổi, P.Bạch Mai, Q.Hai Bà Trưng) chia sẻ: “Tôi sắm cành đào phai giá 160.000 đồng. Năm nào vợ chồng tôi cũng đánh xe lên chợ này tậu cành đào về đón rằm tháng Chạp và Tết Dương lịch”.

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. This comment has been removed by the author.

    ReplyDelete

Post a Comment

Popular posts from this blog

EC2 Ssh Connection Refused

When ssh: connect to host ip_address port 22 Connection refused



Unable to access server???
Exactly when you see the error - “ssh: connect to host ip_address port 22: Connection refused” while connecting your AWS EC2 Instance. In order to find solution of the problem, you will go to AWS forum and other channels where you need to answers several questions first. But it's very difficult to find the actual problem. In order to get clues what the problem is, we should provide as many details as possible about what we have tried and the results we are getting. Because there are hundreds of reason why a server or service might not be accessible, also connectivity is one of the toughest issue to diagnose, especially when you are hosting something critical on your box. I've seen several topics on this problem, but none offers a solution to it.  I was not aware for what should I look at first. So I walk through from the very basics and investigated the following thing Use of verbose while ss…

jgit-flow maven plugin to Release Java Application

Introduction As a DevOps I need a smooth way to release the java application, so I compared two maven plugin that are used to release the java application and in the end I found that Jgit-flow plugin is far better than maven-release plugin on the basis of following points: Maven-release plugin creates .backup and release.properties files to your working directory which can be committed mistakenly, when they should not be. jgit-flow maven plugin doesn't create these files or any other file in your working directory.Maven-release plugin create two tags.Maven-release plugin does a build in the prepare goal and a build in the perform goal causing tests to run 2 times but jgit-flow maven plugin builds project once so tests run only once.If something goes wrong during the maven plugin execution, It become very tough to roll it back, on the other hand jgit-flow maven plugin makes all changes into the branch and if you want to roll back just delete that branch.jgit-flow maven plugin doesn…

VPC per envrionvment versus Single VPC for all environments

This blog talks about the two possible ways of hosting your infrastructure in Cloud, though it will be more close to hosting on AWS as it is a real life example but this problem can be applied to any cloud infrastructure set-up. I'm just sharing my thoughts and pros & cons of both approaches but I would love to hear from the people reading this blog about their take as well what do they think.


Before jumping right away into the real talk I would like to give a bit of background on how I come up with this blog, I was working with a client in managing his cloud infrastructure where we had 4 environments dev, QA, Pre Production and Production and each environment had close to 20 instances, apart from applications instances there were some admin instances as well such as Icinga for monitoring, logstash for consolidating logs, Graphite Server to view the logs, VPN server to manage access of people.




At this point we got into a discussion that whether the current infrastructure set-u…