Contributors20 minutes | Test Kitchen can help you detect and remedy failures before your change reaches production. |
In the Manage a node with Chef server module, you applied a configuration change that failed on your node. Imagine your node represents a piece of your production infrastructure. A failure in production can cause both an interruption to your team as well as reduced access to services for your users.
In this part, you'll repeat the exercise where you apply a change that, although it might appear correct, will actually fail on your test instance. You'll then remedy the failure and verify that chef-client succeeds.
In doing so, you'll see how, with Test Kitchen, you can detect and remedy failures before your change reaches production.
1. Assign an owner to the home page
Let's make the same change to the web server cookbook that we did previously. Here, we want to assign the web_admin user as the owner of the home page, /var/www/html/index.html. We also want to configure the home page so that the web_admin user has read and write access, and everyone else has read-only access.
Recall that your default recipe looks like this.
Editor: ~/learn-chef/cookbooks/learn_chef_httpd/recipes/default.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| #
# Cookbook Name:: learn_chef_httpd
# Recipe:: default
#
# Copyright (c) 2016 The Authors, All Rights Reserved.
package 'httpd'
service 'httpd' do
action [:enable, :start]
end
template '/var/www/html/index.html' do # ~FC033
source 'index.html.erb'
end |
Modify your default recipe to look like this. Note the use of the template resource's mode, owner, and group properties.
Editor: ~/learn-chef/cookbooks/learn_chef_httpd/recipes/default.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| #
# Cookbook Name:: learn_chef_httpd
# Recipe:: default
#
# Copyright (c) 2016 The Authors, All Rights Reserved.
package 'httpd'
service 'httpd' do
action [:enable, :start]
end
template '/var/www/html/index.html' do
source 'index.html.erb'
mode '0644'
owner 'web_admin'
group 'web_admin'
end |
2. Apply the changes to your test instance
Now see what happens when you run kitchen converge. Because you destroyed your test instance in the previous part, Test Kitchen creates a new instance for you.
Terminal: ~/learn-chef/cookbooks/learn_chef_httpd
$ | kitchen converge-----> Starting Kitchen (v1.20.0)-----> Creating <default-centos-7>... Creating GCE instance <tk-default-centos-7-debbd2> in project cheftraining-petchel, zone us-east1-c... Zone operation operation-1524857089968-56ad9752e4781-28839243-9567c288 created. Waiting for it to complete... Current status: PENDING Current status: RUNNING Current status: DONE Server <tk-default-centos-7-debbd2> created. Waiting for server <tk-default-centos-7-debbd2> to be ready... Waiting for SSH service on 35.196.96.104:22, retrying in 3 seconds [SSH] Established GCE instance <tk-default-centos-7-debbd2> created and ready. Finished creating <default-centos-7> (0m27.65s).-----> Converging <default-centos-7>... Preparing files for transfer Preparing dna.json Resolving cookbook dependencies with Berkshelf 6.3.1... Removing non-cookbook files before transfer Preparing validation.pem Preparing client.rb-----> Installing Chef Omnibus (install only if missing) Downloading https://omnitruck.chef.io/install.sh to file /tmp/install.sh Trying curl... Download complete. el 7 x86_64 Getting information for chef stable for el... downloading https://omnitruck.chef.io/stable/chef/metadata?v=&p=el&pv=7&m=x86_64 to file /tmp/install.sh.1249/metadata.txt trying curl... sha1 dedf02c8ac06a6e6927b5fef64c0ff50e4cba154 sha256 14ca797942b9a5b4e9c7b0abdb4dada1c2a2c783e5f264b422f36a8993439d78 url https://packages.chef.io/files/stable/chef/14.0.202/el/7/chef-14.0.202-1.el7.x86_64.rpm version 14.0.202 downloaded metadata file looks valid... downloading https://packages.chef.io/files/stable/chef/14.0.202/el/7/chef-14.0.202-1.el7.x86_64.rpm to file /tmp/install.sh.1249/chef-14.0.202-1.el7.x86_64.rpm trying curl... Comparing checksum with sha256sum... WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING You are installing an omnibus package without a version pin. If you are installing on production servers via an automated process this is DANGEROUS and you will be upgraded without warning on new releases, even to new major releases. Letting the version float is only appropriate in desktop, test, development or CI/CD environments. WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING Installing chef installing with rpm... warning: /tmp/install.sh.1249/chef-14.0.202-1.el7.x86_64.rpm: Header V4 DSA/SHA1 Signature, key ID 83ef826a: NOKEY Updating / installing... Thank you for installing Chef! Transferring files to <default-centos-7> Starting Chef Client, version 14.0.202 Creating a new client identity for default-centos-7 using the validator key. resolving cookbooks for run list: ["learn_chef_httpd::default"] Synchronizing Cookbooks: - learn_chef_httpd (0.1.0) Installing Cookbook Gems: Compiling Cookbooks... Converging 3 resources Recipe: learn_chef_httpd::default * yum_package[httpd] action install - install version 0:2.4.6-67.el7.centos.6.x86_64 of package httpd * service[httpd] action enable - enable service service[httpd] * service[httpd] action start - start service service[httpd] * template[/var/www/html/index.html] action create * cannot determine user id for 'web_admin', does the user exist on this system? ================================================================================ Error executing action `create` on resource 'template[/var/www/html/index.html]' ================================================================================ Chef::Exceptions::UserIDNotFound -------------------------------- cannot determine user id for 'web_admin', does the user exist on this system? Resource Declaration: --------------------- 12: template '/var/www/html/index.html' do 13: source 'index.html.erb' 14: mode '0644' 15: owner 'web_admin' 16: group 'web_admin' 17: end Compiled Resource: ------------------ template("/var/www/html/index.html") do action [:create] default_guard_interpreter :default source "index.html.erb" declared_type :template cookbook_name "learn_chef_httpd" recipe_name "default" mode "0644" owner "web_admin" group "web_admin" path "/var/www/html/index.html" verifications [] variables {} end System Info: ------------ chef_version=14.0.202 platform=centos platform_version=7.4.1708 ruby=ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux] program_name=/opt/chef/bin/chef-client executable=/opt/chef/bin/chef-client Running handlers: [2018-04-27T19:25:48+00:00] ERROR: Running exception handlers Running handlers complete [2018-04-27T19:25:48+00:00] ERROR: Exception handlers complete Chef Client failed. 3 resources updated in 15 seconds [2018-04-27T19:25:48+00:00] FATAL: Stacktrace dumped to /tmp/kitchen/cache/chef-stacktrace.out [2018-04-27T19:25:48+00:00] FATAL: Please provide the contents of the stacktrace.out file if you file a bug report [2018-04-27T19:25:48+00:00] FATAL: Chef::Exceptions::UserIDNotFound: template[/var/www/html/index.html] (learn_chef_httpd::default line 12) had an error: Chef::Exceptions::UserIDNotFound: cannot determine user id for 'web_admin', does the user exist on this system?>>>>>> ------Exception------->>>>>> Class: Kitchen::ActionFailed>>>>>> Message: 1 actions failed.>>>>>> Converge failed on instance <default-centos-7>. Please see .kitchen/logs/default-centos-7.log for more details>>>>>> ---------------------->>>>>> Please see .kitchen/logs/kitchen.log for more details>>>>>> Also try running `kitchen diagnose --all` for configuration
|
Here you see the same failure that you saw previously when you ran this code on your node.
Terminal: ~
| Chef::Exceptions::UserIDNotFound--------------------------------cannot determine user id for 'web_admin', does the user exist on this system?
|
You also see that Test Kitchen returns with a non-zero exit code.
Terminal: ~/learn-chef/cookbooks/learn_chef_httpd
3. Resolve the failure
Now you'll resolve the failure just as you did previously.
Modify your default recipe by using the group and user resources to define the web_admin group and user.
Editor: ~/learn-chef/cookbooks/learn_chef_httpd/recipes/default.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| #
# Cookbook Name:: learn_chef_httpd
# Recipe:: default
#
# Copyright (c) 2016 The Authors, All Rights Reserved.
package 'httpd'
service 'httpd' do
action [:enable, :start]
end
group 'web_admin'
user 'web_admin' do
group 'web_admin'
system true
shell '/bin/bash'
end
template '/var/www/html/index.html' do
source 'index.html.erb'
mode '0644'
owner 'web_admin'
group 'web_admin'
end |
Now run kitchen converge to apply the configuration.
Terminal: ~/learn-chef/cookbooks/learn_chef_httpd
$ | kitchen converge-----> Starting Kitchen (v1.20.0)-----> Converging <default-centos-7>... Preparing files for transfer Preparing dna.json Resolving cookbook dependencies with Berkshelf 6.3.1... Removing non-cookbook files before transfer Preparing validation.pem Preparing client.rb-----> Chef Omnibus installation detected (install only if missing) Transferring files to <default-centos-7> Starting Chef Client, version 14.0.202 resolving cookbooks for run list: ["learn_chef_httpd::default"] Synchronizing Cookbooks: - learn_chef_httpd (0.1.0) Installing Cookbook Gems: Compiling Cookbooks... Converging 5 resources Recipe: learn_chef_httpd::default * yum_package[httpd] action install (up to date) * service[httpd] action enable (up to date) * service[httpd] action start (up to date) * group[web_admin] action create - create group web_admin * linux_user[web_admin] action create - create user web_admin * template[/var/www/html/index.html] action create - create new file /var/www/html/index.html - update content in file /var/www/html/index.html from none to ef4ffd --- /var/www/html/index.html 2018-04-27 19:26:02.753819123 +0000 +++ /var/www/html/.chef-index20180427-1880-15hczgi.html 2018-04-27 19:26:02.752819123 +0000 @@ -1 +1,6 @@ +<html> + <body> + <h1>hello world</h1> + </body> +</html> - change mode from '' to '0644' - change owner from '' to 'web_admin' - change group from '' to 'web_admin' - restore selinux security context Running handlers: Running handlers complete Chef Client finished, 3/6 resources updated in 02 seconds Downloading files from <default-centos-7> Finished converging <default-centos-7> (0m7.58s).-----> Kitchen is finished. (0m10.50s)
|
As before, run kitchen exec to verify the contents of your web server's home page.
Terminal: ~/learn-chef/cookbooks/learn_chef_httpd
$ | kitchen exec -c 'curl localhost'-----> Execute command on default-centos-7. <html> <body> <h1>hello world</h1> </body> </html>
|
Also verify that the web_admin user is the owner of the home page and that the home page has the expected file permissions.
Terminal: ~/learn-chef/cookbooks/learn_chef_httpd
$ | kitchen exec -c 'stat /var/www/html/index.html'-----> Execute command on default-centos-7. File: '/var/www/html/index.html' Size: 59 Blocks: 8 IO Block: 4096 regular file Device: 801h/2049d Inode: 26013129 Links: 1 Access: (0644/-rw-r--r--) Uid: ( 997/web_admin) Gid: ( 1004/web_admin) Context: unconfined_u:object_r:httpd_sys_content_t:s0 Access: 2018-04-27 19:26:06.384818690 +0000 Modify: 2018-04-27 19:26:02.752819123 +0000 Change: 2018-04-27 19:26:02.756819123 +0000 Birth: -
|
Success! With local development, you can make changes, experiment, and verify that your configuration does what you expect using local test instances. You now have increased confidence that your change will work in production.
| Unlike in the Manage a node with Chef server module, you did not modify your cookbook's version in the metadata.rb file. You only need to increment the version number when you upload your cookbook to the Chef server. |
Feel free to experiment further with your test instance. When you're done, be sure to run kitchen destroy to delete your instance.
Conclusion
In this module, you used Test Kitchen to configure a basic web server on a CentOS virtual machine, all from your workstation. You also saw how with local development, you can detect and resolve failures before your change appears in production.
Local development gives you the time and flexibility to experiment, iterate, and fix problems early in the development cycle. You only upload your cookbooks to the Chef server and apply them to your bootstrapped nodes after you've confirmed from your workstation that your configuration code works as you expect.
Learn more about Test Kitchen at kitchen.ci.
In the Create a web app cookbook module, you'll use the skills you've just learned to build a basic but complete web application that uses a web server, a database, and scripting. You'll learn how to leverage cookbooks that are written by the Chef community and resolve cookbook dependencies to create cookbooks that are more reusable.