Migrate databases to and from AWS RDS instances

Amazon Web Services do not provide tools to migrate data to, from and between AWS RDS instances.

There is a free utility that can do the job.

SQL Server Management Studio (SSMS)

Install Microsoft SQL Server Management Studio (SSMS), because the utility uses libraries from it.

  1. Download the installer for free from https://msdn.microsoft.com/en-us/library/mt238290.aspx

SQL Azure Migration Wizard


  1. Download the SQL Azure Migration Wizard from http://sqlazuremw.codeplex.com/
  2. Unzip the downloaded ZIP file into a folder on your hard drive
  3. Create a shortcut in your Start Menu for SQLAzureMW.exe

Migrate a database

  1. Start the SQL Azure Migration Wizard by executing the SQLAzureMW.exe file
  2. Select Database in the Analyze / Migrate section and click Next

Connect to the source database

  1. On the Connect to Server page
    1. Enter the address of the database server
    2. Select SQL Server Authentication
    3. Enter the database owner login name and password
    4. If you keep Master DB selected, the next screen will show the list of databases to select from
    5. To save the username and password select Save Login Information
    6. Click Connect

  2. Select the database to connect to and click Next
  3. Leave Script all database objects selected and click Next
  4. On the Script Wizard Summary page click Next
  5. Click Yes to start the read process
  6. On the Results Summary page select Auto Scroll Display to see the scrolling results
  7. When the read is done click Next

Connect to the target database

  1. Enter the connection properties of the target database server
  2. Select the target database
    1. To migrate the data into a new database click the Create Database button
    2. On mirrored RDS instances we cannot drop and recreate databases. To migrate data into an existing database
      1. Use SQL Management Studio to drop the existing tables to avoid key conflicts
      2. Select the target database on this page
  3. Click Next
  4. Click Yes to start the write process
  5. When the write process is done click Exit


Launch Windows instances locally with Chef Test Kitchen

Most Linux distributions are free, and do not require product keys to launch them.

The steps below are based on the great article at http://kitchen.ci/blog/test-kitchen-windows-test-flight-with-vagrant/

I have summarized the steps below to create a free Virtual Box Windows Server 2012R2 image on your workstation, so Test Kitchen can use Vagrant and Virtual Box to launch Windows instances and test cookbooks locally fast and free.

Install the Vagrant WinRm plugin

vagrant plugin install vagrant-winrm

Get BoxCutter

Create the Windows image with BoxCutter. This process will take 30 minutes or more to fully configure the Windows image. The download step may time out on slower VPN connections. In that case disconnect the VPN connection and try it again without it. In case of any error, just execute the last command again and if it can, the process will continue from the point of error.

cd ~/
mkdir boxcutter
cd boxcutter
git clone https://github.com/boxcutter/windows.git
cd windows

Modify the BoxCutter JSON file

Change the ~/boxcutter/windows/eval-win2012r2-standard.json file to avoid the error message:

virtualbox-iso: Removing floppy drive…
==> virtualbox-iso: Error removing floppy controller: VBoxManage error: VBoxManage: error: The machine ‘eval-win2012r2-standard’ is already locked for a session (or being unlocked)
==> virtualbox-iso: VBoxManage: error: Details: code VBOX_E_INVALID_OBJECT_STATE (0x80bb0007), component MachineWrap, interface IMachine, callee nsISupports
==> virtualbox-iso: VBoxManage: error: Context: “LockMachine(a->session, LockType_Write)” at line 1038 of file VBoxManageStorageController.cpp

  • Change “headless”: “false”, to “headless”: “true”,
  • Add under “headless”: “true”,
"shutdown_timeout": "60m",
"post_shutdown_delay": "120s",


  • Add under every occurrence of “headless”: “{{ user `headless` }}”,
"shutdown_timeout": "{{ user `shutdown_timeout` }}",
"post_shutdown_delay": "{{ user `post_shutdown_delay` }}",

Create the virtual machine

make virtualbox/eval-win2012r2-standard

Add the image to Vagrant

vagrant box add windows-2012r2 ./box/virtualbox/eval-win2012r2-standard-nocm-1.0.4.box

Test the virtual machine

Your .kitchen.yml file should look like this

  name: vagrant

  name: chef_zero

  - name: windows-2012r2

  - name: MY_SUITE_NAME


You may need to execute the kitchen converge commands as sudo to be able to launch the Windows instance.

Serialize SSH and RSA private keys to store them in a Chef Data Bag

To send RSA private keys to instances, store them in encrypted data bags. The data bag item is a JSON file that contains keys and values.

To place the multi-line RSA key into the value part of the JSON file, we need to replace the new line characters with “\n”

On Macintosh

we will use Atom to do the replacement:

  1. Open the RSA key file in Atom,
  2. Press Command F to open the Find and Replace window,
  3. On the right side click the Use Regex button,
  4. In the search field enter
  5. In the replace with field enter
  6. Press the Replace All button

On Windows

we can use Notepad++ to do the replacement:

  • Open the RSA key file in Notepad++,
  • In the Search menu select Replace…,
  • Select Extended mode in the Search Mode section,
  • Enter \r\n to the Find what text box
  • Enter * (star) to the Replace with text box 
  • Press the Replace All button


  • Select Normal in the Search Mode section,
  • Enter *  (star) to the Find what text box
  • Enter \n to the Replace with text box
  • Press the Replace All button


You can place the single line key into any encrypted Data Bag file. See Data Bags on Data Bag encryption.

HTTP Request Returned 409 Conflict: Client already exists

The Chef server maintains the list of registered nodes and clients in its database.  When you launch a new instance with Chef you may encounter the following error message:

*** Input CHEF_CLIENT_NODE_NAME is undefined, using: IP-0AFE6965
*** Starting chef-client
*** Finished chef-client
Printing Log
[...] INFO: Client key C:\chef\client.pem is not present - registering
[...] INFO: HTTP Request Returned 409 Conflict: Client already exists
[...] INFO: HTTP Request Returned 403 Forbidden: error
[...] ERROR: Running exception handlers
[...] ERROR: Exception handlers complete
[...] FATAL: Stacktrace dumped to C:/chef/cache/chef-stacktrace.out
[...] FATAL: Please provide the contents of the stacktrace.out file if you file a bug report
[...] FATAL: Net::HTTPServerException: 403 "Forbidden"


In this case the CHEF_CLIENT_NODE_NAME already exists in the client database.You can search for it from a Bash window.


Add a line to the Chef configuration to remove the existing node with the same node name

If you use Terraform to launch server instances and configure Chef, add this line to the Chef provisioner:

recreate_client = true

To delete nodes from the Chef server:

Use the knife command to search for the existing node from a Bash window.

To find the node in the Chef server database

knife search node '*:IP-0AFE6965'

To find the client in the Chef server database

knife search client '*:IP-0AFE6965'

If any of them found, those are leftovers from a previous launch. AWS reuse the IDs, so you have to remove the nodes from the Chef server database when you terminate the instances. To delete the unnecessary entries use the following commands:

knife node delete 'IP-0AFE6965'
knife client delete 'IP-0AFE6965'

To remove the terminated instances from the Chef server database you can also use the Chef web interface.

  • On the Nodes tab enter the IP address of the instance into the search box and hit Enter
  • In the Actions column click the down arrow next to the instance and select Delete

DevOps Engineering part 7. – Launching production instances in the cloud

In the previous parts of this tutorial we have launched instances (servers) in the cloud, but those were created by Test Kitchen, running on our workstation. Those instances are as good as they can be, but the cookbook did not reside on the Chef server.

To launch pre-production and production instances in the cloud, first we need to upload the cookbook to the Chef server. In Beginner’s Guide to DevOps Engineering part 4. Connect to the Chef server we have already connected our workstation to the Chef server.

Upload the cookbook to the Chef server

To make your cookbook available for all the servers of the organization we will upload the cookbook to the Chef server.

  • In the folder of the cookbook open a Bash window
  • Execute the command to upload the cookbook to the Chef server
    knife cookbook upload COOKBOOK_NAME --freeze

    Don’t forget to add the –freeze option to the end to protect the version of the cookbook from accidental changes.

Launch the server in the Cloud

There are many ways to launch servers in a scripted way, we are going to review a few options. One is to use RightScale, a Cloud Management Platform, that can manage servers in multiple cloud environments.


Create a new Deployment

  • Using your web browser log into the RightScale Cloud Management user interface,
  • In the Manage menu select Deployment and click the New button,
  • Enter the name of the new deployment,
  • To add the new deployment to your bookmarks,
    • On the left side in the Bookmarks section click the Add link,
    • If necessary shorten the name of the bookmark and click OK,
    • To reorder the bookmarks
      • Click the Edit link and drag the bookmark to the desired position,
      • Click the Done link to save your changes.

Create the CAT file

CAT files are Ruby like scripts that describe the configuration of the instance. It contain the name of the deployment the server should be placed it, the cloud attributes to assign security groups, regions, availability zones, set the drive size, specify security keys. The easiest way to configure a server is to copy an existing RightScale Self Service CAT file and update it with the new values.

If this is the first CAT file in your organization, get help from RightScale support and get a sample file from them.

If your organization already has a library of CAT files

  • Make a copy of an existing CAT file
  • Update the values to customize it for your server
    • Application name
    • Chef runlist
    • Security group
    • Deployment name
    • Load balancer name
    • Instance type


Upload the CAT file to RightScale

  • Open the RightScale Self Service user interface,
  • Select Designer on the left,
  • Click the Upload CAT button and select the CAT file,
  • Click the Upload button in the lower right corner,
  • In the green popup in the upper right corner click the Publish to catalog link,
  • In the lower right corner click the Yes, Publish button.

Launch the server in RightScale Self Service

  • In the RightScale Self Service interface select Catalog on the left side,
  • Select the catalog item you want to launch,
  • Enter a name for the instance to be able to identify it later and select the instance in the dropdown list,
  • Click the Launch CloudApp button.

To monitor the server launch

  • In your web browser open the RightScale user interface,
  • In the design menu select Deployments,
  • Select the deployment of the instance,
  • Click the instance to see in formation on it.


to the Tutorials page


DevOps Engineering part 5. – Create an enterprise cookbook

In this exercise we will create a Chef cookbook for a corporation. It will be robust and include all the necessary elements to be used in a large enterprise. If your company already has established standards, as you progress with this tutorial, copy the appropriate file from an existing cookbook. If this is the first cookbook in your organization, or you don’t want to follow the current standards, copy the sample files from this page.

Create the cookbook

  • Navigate to the C:\Chef\…\cookbooks folder and open a Bash window
  • Create an empty cookbook
    chef generate cookbook COOKBOOK_NAME

    Chef creates a new sub-folder with the name of the cookbook.

  • Rename the new folder to cookbook-COOKBOOK_NAME to distinguish it in version control from other repository types.

Update the .gitignore file

  • Chef DK has generated a .gitignore file that contains most of the important entries, but we need to add a few important lines:
    # Certificates
    # Unencrypted Data Bags
    # Macintosh folder custom attribute file
    # If working in a team, personalized Test Kitchen config file 

Update the metadata.rb file

Add your name, email address, and the version of the cookbook to the top of the metadata.rb file

maintainer 'YOUR_NAME'
maintainer_email 'YOUR_EMAIL_ADDRESS'
license 'All rights reserved'
description 'Installs/Configures THE_NAME_OF_THE_COOKBOOK'
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
version '1.0.0'

The expression in the long_description line refers to the README.md file that GitHub can create when you set up a new repository. Place the cookbook related information into that file, so others who want to use your cookbook can easily find it.

Update the Berksfile

Add the list of cookbooks this cookbook depends on to the Berksfile file. To download all necessary cookbooks execute

berks install

Update the .kitchen.yml file to be able to test your cookbook.

If you want to test your cookbook in the Cloud, copy the following sections from an existing .kitchen.yml file of your organization. To learn Chef and launch instances with Vagrant on your workstation, the automatically created .kitchen.yml file is perfect.

  • driver
  • provisioner
  • platforms
  • a suite as an example

If your organization use tags to track instances in the Cloud,  update the tags section to reflect the values of the cookbook.

To add multiple recipes to the Chef run list use this syntax:


Encrypted Data Bags

If you want to use encrypted data bags, ask your Chef administrator to send you the key file to encrypt and decrypt data bags. Create the data_bags_unencrypted folder for the data bag secret key on the same level where the cookbook and environment folders are.

This is a chicken and egg paradox. We don’t want to commit secrets into version control, so we need to encrypt them. But how can we place the secret encryption key on the server to decrypt the secrets? We will use Packer to create our own server images that will contain the secret key, so when Chef starts to run on the server, the key is going to be there.

Default recipe

We will place code in the default.rb file that is common to all recipes in the cookbook. All custom recipes will call the default recipe as the first step.

Update the header comments of the default.rb recipe with your name and company information

# Cookbook Name:: COOKBOOK_NAME
# Recipe:: default
# Copyright (c) 2015-2016 COMPANY_NAME, All Rights Reserved.

Attribute file

Create the default attribute file with

chef generate attribute default

Add the necessary attributes to the attribute file to store the AWS tag and other cookbook specific values.

Custom recipe

Use the Chef generate command to create the new recipes. It creates all test files in the corect location.

  • Create a new recipe and the test files with
    chef generate recipe MY_RECIPE_NAME
  • Add the following line under the header to call the default recipe, even if it is currently empty
    include_recipe 'COOKBOOK_NAME::default'

Add the cookbook to GitHub

Create the local repository

  • In the Bash window execute the following commands
git init
git add .
git commit -m "Initial commit"

Add the repository to GitHub

In your web browser log into your GitHub account and create a new repository

  • Click the New Repository button
  • Name the repository the same as the name of the folder of the cookbook (cookbook-…)
  • Execute the lines in the section …or push an existing repository….  If you work on a Windows workstation make sure HTTPS is selected
    git remote add origin https://github.com/....git
    git push -u origin master
  • In the Collaborators & teams section of Settings select the group who will have access to the new repository

Test the cookbook

In the Bash window launch the instance with Test Kitchen

List the available instances

kitchen list

Launch the instance


If there are multiple suites or platforms in the .kitchen.yml file you need to type the unique part of the name of the instance to identify it.

Start a Remote Desktop connection to a Windows instance


If you work on a Macintosh workstation and testing a Windows server, the best way to remote into the server is

  1. Install Microsoft Remote Desktop for free from the Apple App Store (See the Remote Desktop Client section in Install the DevOps development tools on Macintosh,
  2. Execute the kitchen login STRING_UNIQUE_TO_THE_INSTANCE command in the terminal window,
  3. The Microsoft Remote Desktop window will pop up with the User account name and the IP address. If you click “Connect”, the remote connection opens with the default settings, that are may not optimal for your display. The “login” command already created a new entry in the Microsoft Remote Desktop app with the IP address of the instance. To use custom settings, click Cancel,
  4. Open the Microsoft Remote Desktop app, right click the last entry that contains the IP address, select Edit, and copy the IP address to the clipboard,
  5. Create a new connection with custom display settings and paste the IP address there. You can keep this generic connection to access the Test Kitchen instances, just update the IP address.
  6. Delete the automatically created connection

SSH into a Linux instance



  • USER_NAME is the value of username: in the .kitchen.yml file.
  • IP_ADDRESS is the IP of the instance. Get it from the “Waiting for SSH service on…” line of the Test Kitchen bash or command window, or from the .yml file in the .kitchen/logs folder of the cookbook.
  • PATH_TO_THE_SSH_KEY_FILE is the value of ssh_key: in the .kitchen.yml file.

Terminate the instance


Upload the cookbook to the Chef server

See Connect to the Chef server in Beginner’s Guide to DevOps Engineering part 4.


Infrastructure as code in Beginner’s Guide to DevOps Engineering part 6.


to the Tutorials page

DevOps Engineering part 4. – Connect to the Chef server

Find a Chef Server

To work in a corporate environment, your organization needs access to a Chef server.

To learn Chef and test your cookbooks for free, you can create an account on the “hosted” Chef server, maintained by the Chef company. The plan allows five nodes at a time, so you can even launch a small server farm for yourself. Another option is to launch your own Chef server (on-premises) and manage up to 25 nodes on it for free. That could be enough for a small organization to get started with automation. Please see the Chef web portal for more information at https://www.chef.io/

To use the “hosted” Chef server

To launch your own Chef server

Accessing the Chef Server

To access the Chef server you need a user account to log into the web interface and a key to access the server with command line tools, like knife.

Until you set up your workstation to access the Chef server, you will  get the following error message:

WARNING: No knife configuration file found
WARN: Failed to read the private key C:\chef\client.pem: #<Errno::ENOENT: No such file or directory @ rb_sysopen - C:\chef\client.pem>
ERROR: Your private key could not be loaded from C:\chef\client.pem
Check your configuration file and ensure that your private key is readable

Create a user account on the Chef server

Register your username

  • Open the Chef server page in your web browser,
  • Click the Click here to get started! link to create a new account,
  • Enter your name, email address and username you want to use and click the Get Started button. The Chef server will send you an invitation email.

Verify your email address

  • Open the email Chef Notifications sent you and click the long link to verify your email address,
  • On the Email Verification page enter the password you want to use on the Chef server and click the Create User button,

Ask your Chef server administrator to invite you to an organization on the Chef server

The administrator

  • Using a web browser log into the Chef server user interface,
  • In the upper right corner select the organization to invite the user to,
  • On the Administration tab select Users on the left side,
  • Under Users click Invite,
  • Enter the username of the new registered user and click the Invite button

Accept the invite to the organization

  • Using a web browser log into the Chef server user interface,
  • On the Welcome to Chef, page click the Accept Invite button.
  • If you are already logged into the Chef server user interface, the upper right corner will show you the number of invitations you have received. Click the red number, then the message to accept the invitation,
  • Select the checkbox next to the organization you want to be part of and click the Accept button.
  • Click Close to dismiss the message window.

Download your key to access the Chef server

  • Using a web browser log into the Chef server user interface,
  • In the upper right corner click your name and select My Profile,
  • In the lower right click the Reset Key link,
  • Click the Download button to download your private .pem key file.

Save your key, you cannot download it again. When you generate a new key, the prior key will be deleted on the server.

Configure knife

The knife command is used to interact with the Chef server. Before you can connect to the Chef server we need to configure knife

  • Open a Bash window in your home directory: ~ on Mac, C:\Users\YOUR_USER_NAME on Windows
  • Execute
    knife configure
  • Get the Chef server address from your administrator and answer the questions:
    Please enter the chef server URL: https://CHEF_SERVER_URL/organizations/ORGANIZATION_NAME
    Please enter an existing username or clientname for the API: YOUR_USER_NAME
    Overwrite /Users/YOUR_USER_NAME/.chef/credentials?? (Y/N) Y
  • Get the chef_shell.rb and knife.rb from your administrator and place them at ~/.chef on Mac and C:\Users\YOUR_USER_NAME\.chef on Windows,
  • Replace the username placeholders with your username.

Save the key files on your workstation

  • Move the .pem Chef server private key file, you have downloaded during the Chef user registration, to the C:/Chef/.chef directory.
  • Get the VALIDATOR_FILE_NAME.pem file from your Chef server administrator and save it in the C:/Chef/.chef directory.

Test the Chef server connectivity

  • Open a Bash window in the folder of the cookbook at C:\Chef\cookbooks\test
  • Execute
knife cookbook list

to see the list of the available cookbooks on the Chef server.

Upload the cookbook to the Chef server

knife cookbook upload COOKBOOK_NAME --freeze

The –freeze option is the most important. It locks the cookbook on the Chef server so we are forced to increment the version before we upload a new version of the cookbook.


Create an enterprise cookbook in Beginner’s Guide to DevOps Engineering part 5.


to the Tutorials page

Remove Policyfile.rb from your Chef cookbook

When you test your cookbook in Chef Test Kitchen and get the following error, delete the “Policyfile.rb” from your Chef cookbook directory.

$$$$$$ You must set your run_list in your policyfile instead of kitchen config. The run_list your config will be ignored.
$$$$$$ Ignored run_list: ["recipe[...::...]"]
       Preparing dna.json
       Exporting cookbook dependencies from Policyfile /tmp/...
       Error: Invalid lockfile data
       Reason: (ChefDK::DependencyConflict) Cookbook ... (...) has dependency constraints that cannot be met by the existing cookbook set:
       Cookbook ... isn't included in the existing cookbook set.

Chef Data Bags

Create an encrypted Chef data bag

There are secrets in most of the Chef cookbooks that we want to protect. We don’t want to give out user names, passwords and AWS keys.  In Chef the best place to hide these secrets is the Encrypted Data Bag.

A Data Bag is a JSON file that we can encrypt, so we can store it in version control with the rest of the cookbook.

To make  continuous integration and delivery (CI/CD) easier, store the Encrypted Data Bags in the cookbook folder structure and commit them together with the rest of the cookbook into version control (Git)

To make sure the unencrypted secret is not committed into version control, add the following line to the  .gitignore file

# Ignore the unencrypted Data Bags

The structure of Chef folder should look like this. Store the unencrypted Data Bags with the original values in the data_bags_unencrypted folder

Create a folder for the unencrypted Data Bag and create a file for the Data Bag Item. The name of the file and the value of the id element should be the same.

Enter the Data Bag Item values and save the file.

 "id": "access_key",
 "AccessKey": "XXXXX",
 "SecretKey": "YYYYY"

Automate the data bag encryption

Create the folder structure

  1. Create a folder for data bag related files on the same level as the cookbooks folder. Name it data_bags

  2. Get the data bag encryption secret file from your Chef server administrator and place it in the data_bags_unencrypted  folder.
  3. Create a folder for Chef related scripts on the same level as the cookbooks folder. Name it devops-chef-scripts

Create the automation script

Create the following script and name it encrypt_databag.sh. This script

  1. Encrypts the Data Bag,
  2. Uploads the encrypted data bag to the Chef server,
  3. Saves the encrypted data bag in the data_bags folder on your workstation.

Replace >>>MY_ENCRYPTED_DATABAG_SECRET<<< with the name of the encrypted data bag secret file.

if [ -z $1 ] || [ -z $2 ]
	echo "Please supply the arguments: DATABAG_NAME ITEM_NAME"
	echo "../devops-chef-scripts/encrypt_databag.sh [DATA_BAG_NAME/NAME OF THE FOLDER] [ITEM_NAME/ID]"

  echo -- knife data bag create $1
  knife data bag create $1

  # Encrypt the databag and upload it to the Chef server
  echo -- knife data bag from file $1 $1/$2.json --secret-file ../data_bags_unencrypted/>>>MY_ENCRYPTED_DATABAG_SECRET<<<
  knife data bag from file $1 $1/$2.json --secret-file ../data_bags_unencrypted/>>>MY_ENCRYPTED_DATABAG_SECRET<<<

  # Create a directory for the encrypted databag on the workstation
  echo -- mkdir -p ../data_bags/$1
  mkdir -p ../data_bags/$1

  # Download the encrypted data bag
  echo -- knife data bag show $1 $2 -F json 'to' ../data_bags/$1/$2.json
  knife data bag show $1 $2 -F json > ../data_bags/$1/$2.json

  echo "Encrypted data bag has been created at ../data_bags/"$1"/"$2".json"


echo -n "Press a key to exit"	#'-n' means do not add \n to end of string
read              		# No arg means dump next line of input

Add execution right to the file

chmod +x ./encrypt_databag.sh

Encrypt the data bag

Open a Bash window in the data_bags_unencrypted folder

Execute the following command, where

DATA_BAG_NAME is the name of the data bag folder
ITEM_NAME is the value of the id element and the item file name without the ‘.json’ extension,

../devops-chef-scripts/encrypt_databag.sh DATA_BAG_NAME ITEM_NAME

The script will create a folder for the Data Bag in the “data_bags” folder and save the encrypted Data Bag file in it.

The following warning is normal. We did not want to unencrypt the data bag, just download the encrypted version.

WARNING: Encrypted data bag detected, but no secret provided for decoding. Displaying encrypted data.


If you get the error message

ERROR: The object you are looking for could not be found
Response: Cannot load data bag item … for data bag …

make sure you set the name of the data bag item file without the .json extension and the value of the id element the same.


DevOps Engineering part 2. – Create and test your first cookbook in 5 minutes

In the first part of the series, Beginner’s Guide to DevOps Engineering Part 1. we have already installed the DevOps development tools.

Create and test your first cookbook in 5 minutes

 Set up the Chef working folder

  1. Create a folder for the Chef development
    1. on Mac ~/Chef
    2. on Windows C:\Chef
  2. In the Chef folder create a sub-folder cookbooks
  3. Right-click the cookbooks folder
    1. on Mac select Services, iTerm2 in Finder
    2. on Windows  select Git Bash Here

Create your first cookbook

    • Enter the following command into the Bash window to create a new cookbook
      chef generate cookbook test

Specify the program you want to use to open .rb files

on Mac

  1. In Finder navigate to ~/Chef/test/recipes
  2. Right-click the default.rb file and select Open With, Atom

on Windows

  • In File Explorer navigate to the C:\Chef\test\recipes older
  • Right-click the default.rb file
    • Select Open with
    • Select the Always use… checkbox  and click the More apps link
  • Select Notepad++ and click the OK button


Let’s create a file with Hello world in it.

      • Enter the following to create your first recipe
        • on Mac
          file '/Users/YOUR_USERNAME/Desktop/helloworld.txt' do
           content 'Hello world'
        • on Windows (make sure you use double backslashes!!!)
          file 'C:\\Users\\YOUR_USERNAME\\Desktop\\helloworld.txt' do
           content 'Hello world'
      • Save the file
      • In the bash Window navigate to the test cookbook directory
        cd test
      • Execute your first recipe with the following in the Bash window
        chef-client --local-mode recipes/default.rb
      • Navigate to the Desktop and open the helloworld.txt file to see the result of your script.

Test your cookbook on a virtual machine

We will use Test Kitchen and Vagrant to launch virtual machines. Currently, only Linux images are available for Vagrant, so we will modify our recipe to select between Linux and Windows and act accordingly.

Open the default.rb recipe and update it to look like this

case node['os']
when 'linux'
  file "/tmp/helloworld.txt" do
    content 'This file was created by Chef!'
when 'windows'
  file "C:\\Chef\\helloworld.txt" do
    content 'This file was created by Chef!'

Enter the following commands into the Bash window

      • Display the available test configurations ( suites )
        kitchen list
      • Launch a virtual Linux machine and test your recipe
        kitchen converge ubuntu

        The first time you launch a virtual machine with an operating system you have never used on your workstation, Vagrant has to download the machine image from the Internet. It can take 5-10 minutes. When the virtual machine is created and launched, Test Kitchen will copy your cookbook to it and execute it there.
      • Test kitchen will display the —–> Kitchen is finished message when the cookbook has successfully executed.
      • Log into the virtual machine
        kichen login ubuntu
      • The root prompt appears in the Bash windows. Let’s check if the file has been created or not.
      • To destroy the virtual machine
        kitchen destroy ubuntu

Windows in Vagrant

To test your cookbook on a Windows virtual machine locally, create one for Vagrant. See Launch Windows instances locally with Chef Test Kitchen for the details.

Learn the basics, so you can ask questions

Chef has a steep learning curve. Chef is not just scripting or programming, but you have to understand how Chef works to be able to use it to configure servers. There are many ways to do the same thing and there is not much documentation to recommend the best way. If you search Google, the problems usually have multiple solutions, and many times the “best” answer is selected based on personal preference. To get started, you should familiarize yourself with the tools, because you will use most of them during the development process.

In this guide I will use a Windows computer as a workstation, but all tools work on Mac and Linux computers.


Learn Vagrant to understand how Test Kitchen manages the test servers on your local machine or at AWS. You will not use vagrant directly, but Test Kitchen uses it to launch servers.


Test Kitchen




Working with AWS in Beginner’s Guide to DevOps Engineering part 3.


to the Tutorials page