Contributors20 minutesPreviously, you bootstrapped your node to your Chef server to apply a basic web server configuration. Later, you updated your configuration policy by modifying the contents of the home page to show the node's FQDN.
In this part, you'll make a second modification to your learn_chef_apache2 cookbook that, although it might appear correct, will actually fail on your node. You'll then remedy the failure and verify that chef-client succeeds.
You'll practice the process of updating your cookbook, bumping its version metadata, and applying the update to your node. You'll also gain insight into how to resolve failures when something goes wrong.
1. Assign an owner to the home page
It's a common practice to run your applications and services under a user who has enough access to modify the system, but who is not a root user.
Here you'll modify the learn_chef_apache2 cookbook's default recipe to assign the web_admin user as the owner of the home page, /var/www/html/index.html. While you're at it, you'll 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_apache2/recipes/default.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| #
# Cookbook Name:: learn_chef_apache2
# Recipe:: default
#
# Copyright (c) 2016 The Authors, All Rights Reserved.
apt_update 'Update the apt cache daily' do
frequency 86_400
action :periodic
end
package 'apache2'
service 'apache2' do
supports status: true
action [:enable, :start]
end
template '/var/www/html/index.html' do # ~FC033
source 'index.html.erb'
end |
To assign the web_admin user as the home page owner and set file permissions, you use the template resource'smode, owner and group properties.
Modify your default recipe like this.
Editor: ~/learn-chef/cookbooks/learn_chef_apache2/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
| #
# Cookbook Name:: learn_chef_apache2
# Recipe:: default
#
# Copyright (c) 2016 The Authors, All Rights Reserved.
apt_update 'Update the apt cache daily' do
frequency 86_400
action :periodic
end
package 'apache2'
service 'apache2' do
supports status: true
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 node
Next you'll repeat the steps you performed in the previous part to apply your updated configuration on your node.
- Update the cookbook's version metadata.
- Upload the cookbook to Chef server.
- Run
chef-client on your node.
First, modify metadata.rb by setting the version field to '0.3.0'.
Editor: ~/learn-chef/cookbooks/learn_chef_apache2/metadata.rb
1
2
3
4
5
6
7
8
9
| name 'learn_chef_apache2'
maintainer 'The Authors'
maintainer_email 'you@example.com'
license 'all_rights'
description 'Installs/Configures learn_chef_apache2'
long_description 'Installs/Configures learn_chef_apache2'
version '0.3.0'
issues_url 'https://github.com/learn-chef/learn_chef_apache2/issues' if respond_to?(:issues_url)
source_url 'https://github.com/learn-chef/learn_chef_apache2' if respond_to?(:source_url) |
Next, run this knife cookbook upload command to upload your cookbook to the Chef server.
Terminal: ~/learn-chef
$ | knife cookbook upload learn_chef_apache2Uploading learn_chef_apache2 [0.3.0]Uploaded 1 cookbook.
|
Finally, run knife ssh to trigger chef-client to run on your node. This example shows key-based authentication. Choose the method you used in the previous part.
Terminal: ~/learn-chef
$ | knife ssh 'name:node1-ubuntu' 'sudo chef-client' --ssh-user vagrant --identity-file ~/.ssh/private_key --attribute ipaddress192.168.145.131 Starting Chef Client, version 13.8.5192.168.145.131 resolving cookbooks for run list: ["learn_chef_apache2"]192.168.145.131 Synchronizing Cookbooks:192.168.145.131 - learn_chef_apache2 (0.3.0)192.168.145.131 Installing Cookbook Gems:192.168.145.131 Compiling Cookbooks...192.168.145.131 Converging 4 resources192.168.145.131 Recipe: learn_chef_apache2::default192.168.145.131 * apt_update[Update the apt cache daily] action periodic (up to date)192.168.145.131 * apt_package[apache2] action install (up to date)192.168.145.131 * service[apache2] action enable (up to date)192.168.145.131 * service[apache2] action start (up to date)192.168.145.131 * template[/var/www/html/index.html] action create192.168.145.131 * cannot determine user id for 'web_admin', does the user exist on this system?192.168.145.131 ================================================================================192.168.145.131 Error executing action `create` on resource 'template[/var/www/html/index.html]'192.168.145.131 ================================================================================192.168.145.131 192.168.145.131 Chef::Exceptions::UserIDNotFound192.168.145.131 --------------------------------192.168.145.131 cannot determine user id for 'web_admin', does the user exist on this system?192.168.145.131 192.168.145.131 Resource Declaration:192.168.145.131 ---------------------192.168.145.131 # In /var/chef/cache/cookbooks/learn_chef_apache2/recipes/default.rb192.168.145.131 192.168.145.131 18: template '/var/www/html/index.html' do192.168.145.131 19: source 'index.html.erb'192.168.145.131 20: mode '0644'192.168.145.131 21: owner 'web_admin'192.168.145.131 22: group 'web_admin'192.168.145.131 23: end192.168.145.131 192.168.145.131 Compiled Resource:192.168.145.131 ------------------192.168.145.131 # Declared in /var/chef/cache/cookbooks/learn_chef_apache2/recipes/default.rb:18:in `from_file'192.168.145.131 192.168.145.131 template("/var/www/html/index.html") do192.168.145.131 action [:create]192.168.145.131 default_guard_interpreter :default192.168.145.131 source "index.html.erb"192.168.145.131 declared_type :template192.168.145.131 cookbook_name "learn_chef_apache2"192.168.145.131 recipe_name "default"192.168.145.131 mode "0644"192.168.145.131 owner "web_admin"192.168.145.131 group "web_admin"192.168.145.131 path "/var/www/html/index.html"192.168.145.131 verifications []192.168.145.131 end192.168.145.131 192.168.145.131 System Info:192.168.145.131 ------------192.168.145.131 chef_version=13.8.5192.168.145.131 platform=ubuntu192.168.145.131 platform_version=14.04192.168.145.131 ruby=ruby 2.4.3p205 (2017-12-14 revision 61247) [x86_64-linux]192.168.145.131 program_name=chef-client worker: ppid=12929;start=21:21:42;192.168.145.131 executable=/opt/chef/bin/chef-client192.168.145.131 192.168.145.131 192.168.145.131 Running handlers:192.168.145.131 [2018-05-01T21:21:46+00:00] ERROR: Running exception handlers192.168.145.131 Running handlers complete192.168.145.131 [2018-05-01T21:21:46+00:00] ERROR: Exception handlers complete192.168.145.131 Chef Client failed. 0 resources updated in 04 seconds192.168.145.131 [2018-05-01T21:21:46+00:00] FATAL: Stacktrace dumped to /var/chef/cache/chef-stacktrace.out192.168.145.131 [2018-05-01T21:21:46+00:00] FATAL: Please provide the contents of the stacktrace.out file if you file a bug report192.168.145.131 [2018-05-01T21:21:46+00:00] ERROR: template[/var/www/html/index.html] (learn_chef_apache2::default line 18) had an error: Chef::Exceptions::UserIDNotFound: cannot determine user id for 'web_admin', does the user exist on this system?192.168.145.131 [2018-05-01T21:21:46+00:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)
|
You see that the chef-client run failed! Here's the error.
Terminal: ~/learn-chef
| Chef::Exceptions::UserIDNotFound--------------------------------cannot determine user id for 'web_admin', does the user exist on this system?
|
As you may have already realized, the updated configuration attempts to assign the file owner to a user that does not exist.
3. Resolve the failure
Now you'll perform these steps to resolve the failure. Steps 2—4 should be famililar to you.
- Add the
web_admin group and user to the system. - Update the cookbook's version metadata.
- Upload the cookbook to Chef server.
- Run
chef-client on your node.
First, 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_apache2/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
26
27
28
29
30
31
| #
# Cookbook Name:: learn_chef_apache2
# Recipe:: default
#
# Copyright (c) 2016 The Authors, All Rights Reserved.
apt_update 'Update the apt cache daily' do
frequency 86_400
action :periodic
end
package 'apache2'
service 'apache2' do
supports status: true
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 |
Remember that the order you define your resources matters. Therefore, it's important to define the web_admin group and user before you assign them as the file owner.
Next, increment your cookbook's version metadata. Because you're making a bug fix, increment the last part of the version, making the version '0.3.1'.
Editor: ~/learn-chef/cookbooks/learn_chef_apache2/metadata.rb
1
2
3
4
5
6
7
8
9
| name 'learn_chef_apache2'
maintainer 'The Authors'
maintainer_email 'you@example.com'
license 'all_rights'
description 'Installs/Configures learn_chef_apache2'
long_description 'Installs/Configures learn_chef_apache2'
version '0.3.1'
issues_url 'https://github.com/learn-chef/learn_chef_apache2/issues' if respond_to?(:issues_url)
source_url 'https://github.com/learn-chef/learn_chef_apache2' if respond_to?(:source_url) |
Next, upload your cookbook to the Chef server.
Terminal: ~/learn-chef
$ | knife cookbook upload learn_chef_apache2Uploading learn_chef_apache2 [0.3.1]Uploaded 1 cookbook.
|
Now run chef-client like you did previously. This example uses key-based authentication.
Terminal: ~/learn-chef
$ | knife ssh 'name:node1-ubuntu' 'sudo chef-client' --ssh-user vagrant --identity-file ~/.ssh/private_key --attribute ipaddress192.168.145.131 Starting Chef Client, version 13.8.5192.168.145.131 resolving cookbooks for run list: ["learn_chef_apache2"]192.168.145.131 Synchronizing Cookbooks:192.168.145.131 - learn_chef_apache2 (0.3.1)192.168.145.131 Installing Cookbook Gems:192.168.145.131 Compiling Cookbooks...192.168.145.131 Converging 6 resources192.168.145.131 Recipe: learn_chef_apache2::default192.168.145.131 * apt_update[Update the apt cache daily] action periodic (up to date)192.168.145.131 * apt_package[apache2] action install (up to date)192.168.145.131 * service[apache2] action enable (up to date)192.168.145.131 * service[apache2] action start (up to date)192.168.145.131 * group[web_admin] action create192.168.145.131 - create group web_admin192.168.145.131 * linux_user[web_admin] action create192.168.145.131 - create user web_admin192.168.145.131 * template[/var/www/html/index.html] action create192.168.145.131 - change owner from 'root' to 'web_admin'192.168.145.131 - change group from 'root' to 'web_admin'192.168.145.131 192.168.145.131 Running handlers:192.168.145.131 Running handlers complete192.168.145.131 Chef Client finished, 3/7 resources updated in 05 seconds
|
You see that the chef-client run succeeds. You also see that the file ownership changed from the root user to the web_admin user.
Verify the configuration by running curl or by refreshing your web browser.
Terminal: ~/learn-chef
$ | curl 192.168.145.131<html> <body> <h1>hello from node1-ubuntu</h1> </body></html>
|
Great work! In practice, you'll want to run your cookbook on a test instance before you upload your work to the Chef server. That way, you'll catch errors like the one you saw here earlier in the process. You learn more about local development in a future module.
Even when you develop your code locally, errors do occur in production. In this part, you were able to quickly fix the error and validate the configuration.