kitchen.yml
Use Test Kitchen to automatically test cookbook data across any combination of platforms and test suites:
- Defined in a
kitchen.ymlfile - Uses a driver plugin architecture
- Supports cookbook testing across many cloud providers and virtualization technologies
- Supports all common testing frameworks that are used by the Ruby community
- Uses a comprehensive set of base images provided by Bento
kitchen.yml file to define what’s required to run Test Kitchen,
including drivers, provisioners, platforms, and test suites.Note
Syntax
The basic structure of a kitchen.yml file is as follows:
driver:
name: driver_name
provisioner:
name: provisioner_name
verifier:
name: verifier_name
transport:
name: transport_name
platforms:
- name: platform-version
driver:
name: driver_name
- name: platform-version
suites:
- name: suite_name
run_list:
- recipe[cookbook_name::recipe_name]
attributes: { foo: "bar" }
excludes:
- platform-version
- name: suite_name
driver:
name: driver_name
run_list:
- recipe[cookbook_name::recipe_name]
attributes: { foo: "bar" }
includes:
- platform-version
where:
driver_nameis the name of a driver that will be used to create platform instances used during cookbook testing. This is the default driver used for all platforms and suites unless a platform or suite specifies adriverto override the default driver for that platform or suite; a driver specified for a suite will override a driver set for a platformprovisioner_namespecifies how Chef Infra Client will be simulated during testing.chef_zeroandchef_soloare the most common provisioners used for testing cookbooksverifier_namespecifies which application to use when running tests, such asinspectransport_namespecifies which transport to use when executing commands remotely on the test instance.winrmis the default transport on Windows. Thesshtransport is the default on all other operating systems.platform-versionis the name of a platform on which Test Kitchen will perform cookbook testing, for example,ubuntu-20.04orcentos-7; depending on the platform, additional driver details—for example, instance names and URLs used with cloud platforms like OpenStack or Amazon EC2—may be requiredplatformsmay define Chef Infra Server attributes that are common to the collection of test suitessuitesis a collection of test suites, with eachsuite_namegrouping defining an aspect of a cookbook to be tested. Eachsuite_namemust specify a run-list, for example:run_list: - recipe[cookbook_name::default] - recipe[cookbook_name::recipe_name]Each
suite_namegrouping may specifyattributesas a Hash:{ foo: "bar" }A
suite_namegrouping may useexcludesandincludesto exclude/include one (or more) platforms. For example:excludes: - platform-version - platform-version # for additional platforms
For example, a simple kitchen.yml file:
driver:
name: vagrant
provisioner:
name: chef_zero
platforms:
- name: ubuntu-20.04
- name: centos-8
- name: debian-10
suites:
- name: default
run_list:
- recipe[apache::httpd]
excludes:
- debian-10
This file uses HashiCorp Vagrant as the driver, which requires no additional configuration because it’s the default driver used by Test Kitchen, chef-zero as the provisioner, and a single (default) test suite that runs on Ubuntu 20.04, and CentOS 7.
Provisioner Settings
Test Kitchen can configure the chef-zero provisioner with the following Chef-specific settings:
attributes- Chef attributes for use in the suite
chef_client_path- Chef Infra Client provisioner only.
chef_metadata_url- This will be deprecated in a future version.
chef_omnibus_install_options- Use to specify the package to be installed. Possible values:
-P chef(for Chef Infra Client) and-P chef-workstation(for Chef Infra Client that’s packaged as part of Chef Workstation). Use-nto specify the nightly build. For example:-P chef-workstationor-n -P chef-workstation. This will be deprecated in a future version. See theproduct_name,product_version, andchannelsettings instead. chef_omnibus_root- Default value:
/etc/optfor UNIX and Linux,$env:systemdrive\\opscode\\chefon Windows. chef_omnibus_url- The URL of an
install.shscript that will install Chef Infra Client on the machine under test. Default value:https://omnitruck.chef.io/install.sh. This will be deprecated in a future version. chef_solo_path- chef-solo provisioner only.
chef_zero_host- Chef Infra Client provisioner only.
chef_zero_port- Chef Infra Client provisioner only. The port on which chef-zero is to listen.
client_rb- Chef Infra Client provisioner only. A list of
client.rbfile settings. For example:client_rb: log_level: :warn clients_path- The relative path to the directory in which client data is located. This data must be defined as JSON.
cookbook_files_glob- A file glob (pattern) that matches files considered to be part of the cookbook. (Typically, this value doesn’t need to be modified from the default.)
data_path- Use to specify the path from which non-cookbook files are copied to a Kitchen instance.
data_bags_path- The relative path to a directory in which data bags and data bag items are defined. This data must be structured as if it were in the chef-repo.
deprecations_as_errors- Set to
trueto treat deprecation warning messages as error messages. driver- Use to specify a driver for a platform. This will override the default driver.
enforce_idempotency- Use with
multiple_converge> 1. Set totrueto force test-kitchen to fail if last converge has any updated resources. encrypted_data_bag_secret_key_path- The path to an RSA key file that’s used to decrypt encrypted data bag items.
environments_path- The relative path to the directory in which environment data is located. This data must be defined as JSON.
http_proxy- The proxy server for HTTP connections.
https_proxy- The proxy server for HTTPS connections.
no_proxy- The comma-separated exception list of host patterns to exclude from using in proxy connections.
install_msi_url- An alternate URL of a Windows MSI package that will install Chef Infra Client on the machine under test. This will be deprecated in a future version. Use the
download_urlsetting instead. json_attributes- Chef Infra Client provisioner only.
log_file
:
multiple_converge- Number of times to converge the node. Defaults to 1.
nodes_path- The relative path to the directory in which node data is located. This data must be defined as JSON.
require_chef_omnibus- Use to install the latest version of Chef Infra Client on a node. Set to
trueto install the latest version,falseto not install Chef Infra Client (assumes the box already has it installed), or a version specifier like15.3.12to install a particular version, or simply15to install the latest 15.x package. When set totrueor a version number, thechef_omnibus_urlmay be used to specify the URL of theinstall.shthat installs the specified version of Chef Infra Client. Default value:true. This will be deprecated in a future version. See theproduct_versionandinstall_strategysettings. roles_path- The relative path to the directory in which role data is located. This data must be defined as JSON.
root_path- The directory in which Kitchen will stage all content on the target node. This directory should be large enough to store all the content and must be writable. (Typically, this value doesn’t need to be modified from the default value.) Default value:
/tmp/kitchen. ruby_bindir- Chef Infra Client provisioner only.
run_list
:
solo_rb- chef-solo provisioner only.
retry_on_exit_code- Takes an array of exit codes to indicate that kitchen should retry the converge command. Default value:
[35, 213]. max_retries- Number of times to retry the converge before passing along the failed status. Defaults value: 1.
wait_for_retry- Number of seconds to wait between converge attempts. Default value: 30.
These settings may be added to the provisioner section of the
kitchen.yml file when the provisioner is chef-zero or chef-solo.
New provisioner settings
product_namecheforchef-workstation. This setting must be specified to use the new settings. Using this setting overrides Test Kitchen’s default behavior based on therequire_chef_omnibussetting.Replaces:
chef_omnibus_install_optionsproduct_version- Product version number. Supports partial version numbers.
Default value:
latestReplaces:
require_chef_omnibus channel- Artifact repository name.
stable,currentorunstable.Default value:
stableReplaces:
chef_omnibus_install_options install_strategy- Product install strategy.
once(Don’t install if any product installation detected),alwaysorskip.Default value:
onceReplaces:
require_chef_omnibus download_url- Direct package URL. Supports all platforms.
Replaces:
install_msi_url checksum- Optional setting when using
download_url. Validates SHA256 checksum after download. platform- Override platform.
Default value: auto detected
platform_version- Override platform platform.
Default value: auto detected
architecture- Override platform architecture.
Default value: auto detected
always_update_cookbooks- Updates the
policyfile.lock.jsonwhen changes are made to the cookbook. Supportstrueorfalse.Default value: auto detected
Transport Settings
Kitchen can configure a transport with the following settings for either
ssh or winrm transports:
connection_retries- Maximum number of times to retry after a failed attempt to open a connection. The default is 5.
connection_retry_sleep- Number of seconds to wait until attempting to make another connection after a failure.
max_wait_until_ready- Maximum number of attempts to determine if the test instance is ready to accept commands. This defaults to 600.
password- The password used for authenticating to the test instance.
port- The port used to connect to the test instance. This defaults to
22for thesshtransport and5985or5986forwinrmusinghttporhttpsrespectively. username- The username used for authenticating to the test instance. This defaults to
administratorfor thewinrmtransport androotfor thesshtransport. Some drivers may change this default.
These settings may be added to the transport section of the
kitchen.yml file when the transport is SSH:
compression- Whether or not to use compression. The default is
false. compression_level- The default is 6 if
compressionistrue. connection_timeout- Defaults to 15.
keepalive- Defaults to
true. keepalive_interval- Defaults to 60.
max_ssh_sessions- Maximum number of parallel ssh sessions.
ssh_key- Path to an ssh key identity file.
These settings may be added to the transport section of the
kitchen.yml file when the transport is WinRM:
elevated- When
true, all commands are executed with a scheduled task. This may eliminate access denied errors related to double hop authentication, interacting with Windows updates and installing some MSIs such as sql server and .net runtimes. Defaults tofalse. elevated_password- The password used by the identity running the scheduled task. This may be
nullin the case of service accounts. Defaults topassword. elevated_username- The identity that the task runs under. This may also be set to service accounts such as
System. This defaults tousername. rdp_port- Port used making
rdpconnections forkitchen logincommands. Defaults to 3389. winrm_transport- The transport type used by WinRM. The default is
negotiate.sslandplaintextare also acceptable values.
Work with proxies
The environment variables http_proxy, https_proxy, and ftp_proxy
are honored by Test Kitchen for proxies. The client.rb file is read to
look for proxy configuration settings. If http_proxy, https_proxy,
and ftp_proxy are specified in the client.rb file, Chef Infra Client
will configure the ENV variable based on these (and related) settings.
For example:
http_proxy 'http://proxy.example.org:8080'
http_proxy_user 'myself'
http_proxy_pass 'Password1'
will be set to:
ENV['http_proxy'] = 'http://myself:Password1@proxy.example.org:8080'
Test Kitchen also supports http_proxy and https_proxy in the
kitchen.yml file. You can set them manually or have them read from
your local environment variables:
driver:
name: vagrant
provisioner:
name: chef_zero
# Set proxy settings manually, or
http_proxy: 'http://user:password@server:port'
https_proxy: 'http://user:password@server:port'
# Read from local environment variables
http_proxy: <%= ENV['http_proxy'] %>
https_proxy: <%= ENV['https_proxy'] %>
This won’t set the proxy environment variables for applications other than Chef. The Vagrant plugin, vagrant-proxyconf, can be used to set the proxy environment variables for applications inside the VM.
Chef Infra Client settings
A kitchen.yml file may define Chef Infra Client-specific settings, such
as whether to require the Chef installer or the URL from which Chef
Infra Client is downloaded, or to override settings in the client.rb
file:
provisioner:
name: chef_zero *or* chef_solo
require_chef_omnibus: true
chef_omnibus_url: https://www.chef.io/chef/install.sh
...
suites:
- name: config
run_list:
...
attributes:
chef_client:
load_gems:
chef-handler-updated-resources:
require_name: "chef/handler/updated_resources"
config:
log_level: ":debug"
ssl_verify_mode: ":verify_peer"
start_handlers: [{class: "SimpleReport::UpdatedResources", arguments: []}]
report_handlers: [{class: "SimpleReport::UpdatedResources", arguments: []}]
exception_handlers: [{class: "SimpleReport::UpdatedResources", arguments: []}]
ohai:
disabled_plugins: ["passwd"]
where:
require_chef_omnibusis used to ensure that the Chef installer will be used to install Chef Infra Client to all platform instances;require_chef_omnibusmay also be set tolatest, which means the newest version of Chef Infra Client for that platform will be used for cookbook testingchef_omnibus_urlis used to specify the URL from which Chef Infra Client is downloaded- the
attributesfor theconfigtest suite contain specific client.rb settings for use with this test suite
Driver Settings
Driver-specific configuration settings may be required. Use a block similar to:
driver:
name: driver_name
optional_settings: values
Specific optional_settings: values may be specified.
Bento
Bento is a Chef Software project that produces base testing VirtualBox, Parallels, and VMware boxes for multiple operating systems for use with Test Kitchen. By default, Test Kitchen uses the base images provided by Bento although custom images may also be built using HashiCorp Packer.Drivers
Test Kitchen uses a driver plugin architecture to enable Test Kitchen to test instances on cloud providers such as Amazon EC2, Google Compute Engine, and Microsoft Azure. You can also test on multiple local hypervisors, such as VMware, Hyper-V, or VirtualBox.
Note
Most drivers have driver-specific configuration settings that must be
added to the kitchen.yml file before Test Kitchen will be able to use
that platform during cookbook testing. For information about these
driver-specific settings, please refer to the driver-specific
documentation.
Some popular drivers:
- kitchen-azurerm: A driver for Microsoft Azure.
- kitchen-cloudstack: A driver for CloudStack.
- kitchen-digitalocean: A driver for DigitalOcean. This driver ships in Chef Workstation.
- kitchen-dokken: A driver for Docker. This driver ships in Chef Workstation.
- kitchen-dsc: A driver for Windows PowerShell Desired State Configuration (DSC).
- kitchen-ec2: A driver for Amazon EC2. This driver ships in Chef Workstation.
- kitchen-google: A driver for Google Compute Engine. This driver ships in Chef Workstation
- kitchen-hyperv: A driver for Microsoft Hyper-V Server. This driver ships in Chef Workstation.
- kitchen-openstack: A driver for OpenStack. This driver ships in Chef Workstation.
- kitchen-rackspace: A driver for Rackspace.
- kitchen-vagrant: A driver for HashiCorp Vagrant. This driver ships in Chef Workstation.
kitchen-vagrant
Thekitchen-vagrant driver for Kitchen generates a single Vagrantfile
for each instance of Kitchen in a sandboxed directory. The
kitchen-vagrant driver supports VirtualBox and VMware Fusion, requires
Vagrant 1.1.0 (or higher), and is the default driver for Test Kitchen.The following attributes are used to configure kitchen-vagrant for
Chef:
boxThe box on which Vagrant will run.
Default value: computed from the platform name of the instance.
Required
box_check_updateWhether to check for box updates.
Default value:
false.box_urlThe URL at which the configured box is located.
Default value: computed from the platform name of the instance, but only when the Vagrant provider is VirtualBox- or VMware-based.
communicatorUse to override the
config.vm.communicatorsetting in Vagrant. For example, when a base box is a Windows operating system that doesn’t have SSH installed and enabled, Vagrant won’t be able to boot without a custom Vagrant file.Default value:
nil(assumes SSH is available).customizeA hash of key-value pairs that define customizations that should be made to the Vagrant virtual machine.
Example:
customize: memory: 1024 cpuexecutioncap: 50.guestThe
config.vm.guestsetting in the default Vagrantfile.guiThe graphical user interface for the defined platform. This is passed to the
config.vm.providersetting in Vagrant, but only when the Vagrant provider is VirtualBox- or VMware-based.networkAn array of network customizations to be applied to the virtual machine.
Example:
network: - ["forwarded_port", {guest: 80, host: 8080}] - ["private_network", {ip: "192.168.33.33"}].Default value:
[].pre_create_commandA command to run immediately before
vagrant up --no-provisioner.providerThe Vagrant provider. This value must match a provider name in Vagrant.
provisionWhether to provision Vagrant when the instance is created. This is useful if the operating system needs customization during provisioning.
Default value:
false.ssh_keyThe private key file used for SSH authentication.
synced_foldersThe collection of synchronized folders on each Vagrant instance. Source paths are relative to the Kitchen root path.
Example:
synced_folders: - ["data/%{instance_name}", "/opt/instance_data"] - ["/host_path", "/vm_path", "create: true, type: :nfs"].Default value:
[].vagrantfile_erbThe alternate Vagrant Embedded Ruby (ERB) template to be used by this driver.
vagrantfilesAn array of paths to one (or more) Vagrant files to be merged with the default Vagrant file. The paths may be absolute or relative to the
kitchen.ymlfile.vm_hostnameThe internal hostname for the instance. This isn’t required when connecting to a Vagrant virtual machine. Set this to
falseto prevent this value from being rendered in the default Vagrantfile.Default value: computed from the platform name of the instance.
The kitchen-vagrant driver can predict the box name for Vagrant and
the download URL that have been published by Chef. For example:
platforms:
- name: ubuntu-18.04
- name: ubuntu-20.04
- name: centos-7
- name: centos-8
- name: debian-10
which will generate a configuration file similar to:
platforms:
- name: ubuntu-18.04
driver:
box: bento/ubuntu-18.04
- name: ubuntu-20.04
driver:
box: bento/ubuntu-20.04
# ...
Examples
The following examples show actual kitchen.yml files used in
Chef-maintained cookbooks.
Chef, Chef Workstation
The following example shows the provisioner settings needed to install Chef Workstation, and then use the version of Chef that’s embedded in Chef Workstation to converge the node.
To install the latest version of Chef Workstation:
provisioner:
...
chef_omnibus_install_options: -P chef-workstation
chef_omnibus_root: /opt/chef-workstation
and to install a specific version of Chef Workstation:
provisioner:
...
chef_omnibus_install_options: -P chef-workstation
chef_omnibus_root: /opt/chef-workstation
require_chef_omnibus: 0.9
Windows platform
The following example shows platform settings for the Windows platform:
platforms:
- name: eval-win2012r2-standard
os_type: windows
transport:
name: winrm
elevated: true
If name begins with win then the os_type defaults to windows.
The winrm transport is the default on Windows operating systems. Here
elevated is true which runs windows commands with a scheduled task to
imitate a local user.
Chef Infra Client cookbook
The following kitchen.yml file is part of the chef-client cookbook and
ensures Chef Infra Client is configured correctly.
driver:
name: vagrant
provisioner:
name: chef_zero
platforms:
- name: centos-8
- name: fedora-latest
- name: ubuntu-1804
- name: ubuntu-2004
suites:
- name: service_init
run_list:
- recipe[minitest-handler]
- recipe[chef-client::config]
- recipe[chef-client_test::service_init]
- recipe[chef-client::init_service]
attributes: {}
- name: service_runit
run_list:
- recipe[minitest-handler]
- recipe[runit]
- recipe[chef-client_test::service_runit]
- recipe[chef-client::runit_service]
attributes: {}
- name: service_upstart
run_list:
- recipe[minitest-handler]
- recipe[chef-client_test::service_upstart]
- recipe[chef-client::upstart_service]
excludes: ["centos-5.9"]
attributes: {}
- name: cron
run_list:
- recipe[minitest-handler]
- recipe[chef-client::cron]
attributes: {}
- name: delete_validation
run_list:
- recipe[chef-client::delete_validation]
attributes: {}
chef-splunk Cookbook
The following kitchen.yml file is part of the chef-splunk cookbook and
is used to help ensure the installation of the Splunk client and server
is done correctly.
driver:
name: vagrant
customize:
memory: 1024
provisioner:
name: chef_zero
platforms:
- name: ubuntu-18.04
- name: ubuntu-20.04
- name: centos-7
- name: centos-8
suites:
- name: client
run_list:
- recipe[chef-splunk::default]
- recipe[test::default]
attributes:
dev_mode: true
splunk:
accept_license: true
- name: server
run_list:
- recipe[chef-splunk::default]
attributes:
dev_mode: true
splunk:
is_server: true
accept_license: true
ssl_options:
enable_ssl: true
yum Cookbook
The following kitchen.yml file is part of the yum cookbook:
driver:
name: vagrant
provisioner:
name: chef_zero
platforms:
- name: centos-7
- name: centos-8
- name: fedora-latest
suites:
- name: default
run_list:
- recipe[yum::default]
- recipe[yum_test::test_repo]
Platform Attributes
The following kitchen.yml file sets up a simple tiered configuration of
Chef Infra Server, including two front-end servers, a single
back-end server, and two add-ons (Chef Push Jobs and Chef management
console). The platforms block uses an attributes section to define
Chef Infra Server attributes that are used by all three test suites:
driver:
name: vagrant
provisioner:
name: chef_zero
platforms:
- name: ubuntu-18.04
attributes:
chef-server:
api_fqdn: backend.chef-server.com
backend:
fqdn: backend.chef-server.com
ipaddress: 123.456.789.0
frontends:
frontend1.chef-server.com: 123.456.789.0
frontend2.chef-server.com: 123.456.789.0
urls:
private_chef: http://123.456.789.0/path/to/private-chef_11.1.4-1_amd64.deb
manage: http://123.456.789.0/path/to/opscode-manage_1.3.1-1_amd64.deb
push_jobs: http://123.456.789.0/path/to/opscode-push-jobs-server_1.1.1-1_amd64.deb
suites:
- name: frontend1
driver:
vm_hostname: frontend1.chef-server.com
network:
- ["private_network", {ip: "123.456.789.0"}]
customize:
memory: 2048
cpus: 2
run_list:
- recipe[chef-server::configfile]
- recipe[chef-server::ntp]
- recipe[chef-server::server]
- recipe[chef-server::frontend]
- name: frontend2
driver:
vm_hostname: frontend2.chef-server.com
network:
- ["private_network", {ip: "123.456.789.0"}]
customize:
memory: 2048
cpus: 2
run_list:
- recipe[chef-server::configfile]
- recipe[chef-server::ntp]
- recipe[chef-server::server]
- recipe[chef-server::frontend]
- name: backend
driver:
vm_hostname: backend.chef-server.com
network:
- ["private_network", {ip: "123.456.789.0"}]
customize:
memory: 8192
cpus: 4
run_list:
- recipe[chef-server::configfile]
- recipe[chef-server::ntp]
- recipe[chef-server::server]
- recipe[chef-server::backend]
Kitchen Converge On System Reboot
Test-Kitchen can handle reboots (when initiated from Chef Infra Client)
by setting retry_on_exit_code, max_retries and wait_for_retry
attributes on the provisioner in kitchen.yml file as follows :
provisioner:
name: chef_zero
retry_on_exit_code:
- 35 # 35 is the exit code signaling that the node is rebooting
- 1
max_retries: 1
client_rb:
exit_status: :enabled # Opt-in to the standardized exit codes
client_fork: false # Forked instances don't return the real exit code
One note on Linux nodes: The shutdown command blocks (as opposed to the Windows variant which registers the reboot and returns right away), so once the timeout period passes, Chef Infra Client and the node are in a race to see who can exit/shutdown first—so, you may or may not get the exit code out of Linux instances. In that case, you can add 1 to the retry_on_exit_code array and that should catch both cases.
Please refer YAML
documentation
to set retry_on_exit_code attribute.