Configure Windows with Chef

 

In a previous post we saw how to install and configure our Chef server. Now it’s time to see how to configure our Windows server. Chef cookbooks share the same layout regardless the target operating system.

Cookbooks

In order to achieve this goal we’ll have to install cookbooks, you can find them here.

sudo knife cookbook site install windows

This will install the Windows cookbook, the baseline for all windows server configurations. The next step is to upload it to your Chef server. This is mandatory even if you work from your server !

sudo knife cookbook upload windows

Now you have your cookbook installed and available for your configurations! Let’s have a look at this cookbook.

ll ~/chef-repo/cookbooks/windows
total 104
drwxr-xr-x 8 root root  4096 Feb 19 21:25 ./
drwxrwxr-x 7 fab  fab   4096 Feb 19 21:25 ../
drwxr-xr-x 2 root root  4096 Feb 19 21:25 attributes/
-rw-r--r-- 1 root root 11558 Feb 19 21:25 CHANGELOG.md
drwxr-xr-x 3 root root  4096 Feb 19 21:24 files/
drwxr-xr-x 2 root root  4096 Feb 19 21:25 libraries/
-rw-r--r-- 1 root root 29471 Feb 19 21:25 metadata.json
drwxr-xr-x 2 root root  4096 Feb 19 21:25 providers/
-rw-r--r-- 1 root root 28099 Feb 19 21:25 README.md
drwxr-xr-x 2 root root  4096 Feb 19 21:25 recipes/
drwxr-xr-x 2 root root  4096 Feb 19 21:25 resources/

You see resources, attributes, files, libraries, providers & recipes folders. The metadata.json file (which can be named metadata.db) is interesting, it contains all needed information about this cookbook. I won’t parse all the file, but, just take a look at these lines

 "platforms": {
    "windows": ">= 0.0.0"
  },
  "dependencies": {
    "chef_handler": ">= 0.0.0"
  },

It contains all dependencies needed by this cookbook to work and the possible target. All we need to do the job. We see that chef_handler is needed for windows cookbook to work, we’ll install it later. Now it’s time to see how recipes contained in a cookbook is executed on a target.

Roles

As i said, roles are needed to execute recipe(s).

name "iis"
description "IIS Server"
run_list(
  "recipe[iis]"
)
default_attributes(
  "iis" => {
    "accept_eula" => true
  }
)

Let’s see what are the lines here:

  • name: hmmm… this is the name of this role 🙂
  • description: …
  • run_list: It contains all the recipes that have to be installed for this role
  • default_attributes: here you can set attributes for your recipes, here the accept_eula is needed in order to ou IIS to install for example.

Create the file in ~/chef-repo/roles/iis.rb and now let’s register the role from this file !

sudo knife role from file ~/chef-repo/roles/iis.rb

If you want a list of all your node to see possible targets, use the following command and select the wanted target where the chef-client has been bootstrapped before

knife node list

And now, assign the role to it! There is two ways of doing this. The first is

sudo knife node run_list add tstsrvvnext.pwrshell.net role[iis]

And the second way:

sudo knife node edit <nodename>
{
  "name": "tstsrvvnext.pwrshell.net",
  "chef_environment": "_default",
  "normal": {
    "tags": [

    ]
  },
  "run_list": [
  "role[iis]"
]

}

Just add the role[iis] in the run_list part of this json.

Now you know the minimum to push a role to the target. Let’s see what needed to install the IIS feature to our node.

Install IIS Feature

Now let’s see a full example about how installing the IIS Feature and start the service. We have seen previously that in order the get the windows cookbook working with need chef_handler cookbook too, so let’s start by installing this one

sudo knife cookbook site install chef_handler

Now let’s install iis cookbook, to do this, we have to find the name of this cookbook. In order to search for existing cookbooks, you can use this command

knife cookbook site search *iis*
iis:
  cookbook:             https://supermarket.chef.io/api/v1/cookbooks/iis
  cookbook_description: Installs/Configures Microsoft Internet Information Services
  cookbook_maintainer:  chef
  cookbook_name:        iis
iis_urlrewrite:
  cookbook:             https://supermarket.chef.io/api/v1/cookbooks/iis_urlrewrite
  cookbook_description: Installs and configures the IIS URL Rewrite Module
  cookbook_maintainer:  dunnj
  cookbook_name:        iis_urlrewrite
learn_chef_iis:
  cookbook:             https://supermarket.chef.io/api/v1/cookbooks/learn_chef_iis
  cookbook_description: Installs and configures IIS, the W3SVC, and sets a basic home page.
  cookbook_maintainer:  learn-chef
  cookbook_name:        learn_chef_iis

It seems the cookbook we need is iis

sudo knife cookbook site install iis

Now let’s “upload” them to the Chef Server. Remember that, in the Chef logic, the development and all this stuff is made from workstation 😉

sudo knife cookbook upload iis windows chef_handler

Ok, now our cookbooks are available by Chef Server. Let’s create the role and assign it to the node previously bootstrapped. We created an iis.rb file in this article so let’s reuse it and assign it.

sudo knife node run_list add tstsrvvnext.pwrshell.net role[iis]

Note that if the role is already added to the node, it’ll just update the node configuration. It won’t create a conflict of throw an error.

Let’s push the role to our target!

sudo knife winrm name:tstsrvvnext.pwrshell.net 'chef-client' -x Administrateur -P '<password>' --winrm-authentication-protocol basic

I won’t display the whole log, but actions are executed in this order:

  1. Connect to Chef-Client
  2. Loading cookbooks in client cache
  3. Executions of recipes in the run_list order
  4. That’s all!
tstsrvvnext.pwrshell.net [2015-02-20T08:50:29+00:00] INFO: Chef Run complete in 142.03902 seconds
tstsrvvnext.pwrshell.net [2015-02-20T08:50:29+00:00] INFO: Running report handlers
tstsrvvnext.pwrshell.net [2015-02-20T08:50:29+00:00] INFO: Report handlers complete

This is pretty easy isn’t it 🙂

By the way, if your script encounter errors, you can find a debug trace file in C:\chef\cache !

Execute Desired State Configuration

Now the funniest part begins 😀

Chef can execute DSC resources or scripts. Today we will focus on resource. First, let’s install and upload the dsc cookbook, remember all this stuff is beta ware and shouldn’t be used in production!

sudo knife cookbook site install dsc
sudo knife cookbook upload dsc

This cookbook is delivered by few demo files. For this demo i’ll use demo_dsc.rb

cd ~/chef-repo/cookbooks/
git clone https://github.com/opscode-cookbooks/dsc.git
Cloning into 'dsc'...
remote: Counting objects: 213, done.
remote: Compressing objects: 100% (98/98), done.
remote: Total 213 (delta 132), reused 174 (delta 110)
Receiving objects: 100% (213/213), 57.38 KiB, done.
Resolving deltas: 100% (132/132), done.

hehe another way of downloading cookbook for Chef 😉

sudo knife cookbook upload dsc
Uploading dsc            [0.1.0]
Uploaded 1 cookbook.

Now let’s create our role, we’ll use the recipe present in the cookbook dsc_demo.

{
  "name": "test_dsc",
  "description": "Testing DSC resource",
  "json_class": "Chef::Role",
  "default_attributes": {
  },
  "override_attributes": {
  },
  "chef_type": "role",
  "run_list": [
    "recipe[dsc::dsc_demo]"
  ],
  "env_run_lists": {
  }
}

Write the file in ~/chef-repo/roles/test_dsc.json

sudo knife node run_list add tstsrvvnext2.pwrshell.net role[test_dsc]
tstsrvvnext2.pwrshell.net:
  run_list: role[test_dsc]

And finally execute the stuff !

sudo knife winrm name:tstsrvvnext2.pwrshell.net 'chef-client' -x Administrateur -P '<password>' --winrm-authentication-protocol basic
tstsrvvnext2.pwrshell.net [2015-02-20T09:28:02+00:00] INFO: *** Chef 12.0.3 ***
tstsrvvnext2.pwrshell.net [2015-02-20T09:28:02+00:00] INFO: Chef-client pid: 3692
tstsrvvnext2.pwrshell.net [2015-02-20T09:28:19+00:00] INFO: Run List is [role[test_dsc]]
tstsrvvnext2.pwrshell.net [2015-02-20T09:28:19+00:00] INFO: Run List expands to [dsc::dsc_demo]
tstsrvvnext2.pwrshell.net [2015-02-20T09:28:19+00:00] INFO: Starting Chef Run for tstsrvvnext2.pwrshell.net
tstsrvvnext2.pwrshell.net [2015-02-20T09:28:19+00:00] INFO: Running start handlers
tstsrvvnext2.pwrshell.net [2015-02-20T09:28:19+00:00] INFO: Start handlers complete.
tstsrvvnext2.pwrshell.net [2015-02-20T09:28:19+00:00] INFO: HTTP Request Returned 404 Object Not Found:
tstsrvvnext2.pwrshell.net [2015-02-20T09:28:19+00:00] INFO: Loading cookbooks [dsc@0.1.0]
tstsrvvnext2.pwrshell.net [2015-02-20T09:28:20+00:00] INFO: Storing updated cookbooks/dsc/recipes/getdscresourcekit.rb in the cache.
tstsrvvnext2.pwrshell.net [2015-02-20T09:28:20+00:00] INFO: Storing updated cookbooks/dsc/recipes/iis.rb in the cache.
tstsrvvnext2.pwrshell.net [2015-02-20T09:28:20+00:00] INFO: Storing updated cookbooks/dsc/recipes/noiis.rb in the cache.
tstsrvvnext2.pwrshell.net [2015-02-20T09:28:20+00:00] INFO: Storing updated cookbooks/dsc/recipes/windows_update_log.rb in the cache.
tstsrvvnext2.pwrshell.net [2015-02-20T09:28:20+00:00] INFO: Storing updated cookbooks/dsc/recipes/telnet.rb in the cache.
tstsrvvnext2.pwrshell.net [2015-02-20T09:28:20+00:00] INFO: Storing updated cookbooks/dsc/libraries/powershell_cmdlet.rb in the cache.
tstsrvvnext2.pwrshell.net [2015-02-20T09:28:20+00:00] INFO: Storing updated cookbooks/dsc/recipes/website.rb in the cache.
tstsrvvnext2.pwrshell.net [2015-02-20T09:28:20+00:00] INFO: Storing updated cookbooks/dsc/recipes/default.rb in the cache.
tstsrvvnext2.pwrshell.net [2015-02-20T09:28:20+00:00] INFO: Storing updated cookbooks/dsc/recipes/dsc_demo.rb in the cache.
tstsrvvnext2.pwrshell.net [2015-02-20T09:28:20+00:00] INFO: Storing updated cookbooks/dsc/recipes/uninstall.rb in the cache.
tstsrvvnext2.pwrshell.net [2015-02-20T09:28:21+00:00] INFO: Storing updated cookbooks/dsc/libraries/powershell_cmdlet_exception.rb in the cache.
tstsrvvnext2.pwrshell.net [2015-02-20T09:28:21+00:00] INFO: Storing updated cookbooks/dsc/libraries/powershell_cmdlet_result.rb in the cache.
tstsrvvnext2.pwrshell.net [2015-02-20T09:28:21+00:00] INFO: Storing updated cookbooks/dsc/libraries/dsc_resource_store.rb in the cache.
tstsrvvnext2.pwrshell.net [2015-02-20T09:28:21+00:00] INFO: Storing updated cookbooks/dsc/libraries/dsc_resource.rb in the cache.
tstsrvvnext2.pwrshell.net [2015-02-20T09:28:21+00:00] INFO: Storing updated cookbooks/dsc/libraries/dsc_provider.rb in the cache.
tstsrvvnext2.pwrshell.net [2015-02-20T09:28:21+00:00] INFO: Storing updated cookbooks/dsc/Berksfile in the cache.
tstsrvvnext2.pwrshell.net [2015-02-20T09:28:21+00:00] INFO: Storing updated cookbooks/dsc/CHANGELOG.md in the cache.
tstsrvvnext2.pwrshell.net [2015-02-20T09:28:21+00:00] INFO: Storing updated cookbooks/dsc/metadata.rb in the cache.
tstsrvvnext2.pwrshell.net [2015-02-20T09:28:21+00:00] INFO: Storing updated cookbooks/dsc/LICENSE in the cache.
tstsrvvnext2.pwrshell.net [2015-02-20T09:28:21+00:00] INFO: Storing updated cookbooks/dsc/README.md in the cache.
tstsrvvnext2.pwrshell.net [2015-02-20T09:28:21+00:00] INFO: Processing dsc_resource[demogroupremove] action set (dsc::dsc_demo line 19)
tstsrvvnext2.pwrshell.net [2015-02-20T09:28:21+00:00] INFO: Getting PowerShell DSC resource 'group'
tstsrvvnext2.pwrshell.net [2015-02-20T09:28:41+00:00] INFO: DSC Resource type 'group' Configuration completed successfully
tstsrvvnext2.pwrshell.net [2015-02-20T09:28:41+00:00] INFO: Processing dsc_resource[demogroupadd] action set (dsc::dsc_demo line 25)
tstsrvvnext2.pwrshell.net [2015-02-20T09:28:54+00:00] INFO: DSC Resource type 'group' Configuration completed successfully
tstsrvvnext2.pwrshell.net [2015-02-20T09:28:54+00:00] INFO: Processing dsc_resource[demogroupadd2] action set (dsc::dsc_demo line 31)
tstsrvvnext2.pwrshell.net [2015-02-20T09:29:00+00:00] INFO: Chef Run complete in 40.969294 seconds
tstsrvvnext2.pwrshell.net [2015-02-20T09:29:00+00:00] INFO: Running report handlers
tstsrvvnext2.pwrshell.net [2015-02-20T09:29:00+00:00] INFO: Report handlers complete

Ok our recipe has been executed like you see!

dsc_chef1

I hope you’ll find interest in Chef and Desired State Configuration for your clients or your infrastructure, if you have question feel free to ask with comments or on Twitter.

Next time we’ll talk about automating Azure with Chef!

See ya 🙂