Thursday 20 October 2016

Configure a package and service

1. Ensure the apt cache is up to date

In this part you'll configure Apache. Because we want to install the latest version of Apache, it's important to ensure that your system's package index contains the latest list of what packages are available.
You could run the apt-get update command manually when you bring up your instance. But over time, you would need to remember to periodically update the apt cache to get the latest updates. Chef provides the apt_update resource to automate the process.
From your ~/chef-repo directory, add this code to a file named webserver.rb.

Editor: ~/chef-repo/webserver.rb

1
2
3
4
apt_update 'Update the apt cache daily' do
  frequency 86_400
  action :periodic
end
In a production environment, you might run Chef periodically to ensure your systems are kept up to date. As an example, you might run Chef multiple times in a day. However, you likely don't need to update the apt cache every time you run Chef. The frequency property specifies how often to update the apt cache (in seconds.) Here, we specify 86,400 seconds to update the cache once every 24 hours. (The _ notation is a Ruby convention that helps make numeric values more readable.)
The :periodic action means that the update occurs periodically. Another option would be to use the :update action to update the apt cache each time Chef runs.

2. Install the Apache package

Now let's install the Apache package, apache2. Modify webserver.rb to look like this.

Editor: ~/chef-repo/webserver.rb

1
2
3
4
5
6
apt_update 'Update the apt cache daily' do
  frequency 86_400
  action :periodic
end

package 'apache2'
We don't need to specify an action because :install is the default.
Now run chef-client to apply the recipe.

Terminal: ~/chef-repo

                  
skytap@host-1:~$ sudo chef-client --local-mode webserver.rb
[2016-10-19T19:05:07+00:00] WARN: No config file found or specified on command line, using command line options.[2016-10-19T19:05:07+00:00] WARN: No cookbooks directory found at or above current directory.  Assuming /root/chef-repo.Starting Chef Client, version 12.14.89resolving cookbooks for run list: []Synchronizing Cookbooks:Installing Cookbook Gems:Compiling Cookbooks...[2016-10-19T19:05:09+00:00] WARN: Node ubuntu-1404 has an empty run list.Converging 2 resourcesRecipe: @recipe_files::/root/chef-repo/webserver.rb  * apt_update[Update the apt cache daily] action periodic (up to date)  * apt_package[apache2] action install    - install version 2.4.7-1ubuntu4.13 of package apache2 Running handlers:Running handlers completeChef Client finished, 1/2 resources updated in 01 minutes 06 seconds
  sudo is required because this command installs a package and therefore must be run with root privileges.
Run the recipe a second time.

Terminal: ~/chef-repo

                 
skytap@host-1:~$ sudo chef-client --local-mode webserver.rb
[2016-10-19T19:06:17+00:00] WARN: No config file found or specified on command line, using command line options.[2016-10-19T19:06:17+00:00] WARN: No cookbooks directory found at or above current directory.  Assuming /root/chef-repo.Starting Chef Client, version 12.14.89resolving cookbooks for run list: []Synchronizing Cookbooks:Installing Cookbook Gems:Compiling Cookbooks...[2016-10-19T19:06:20+00:00] WARN: Node ubuntu-1404 has an empty run list.Converging 2 resourcesRecipe: @recipe_files::/root/chef-repo/webserver.rb  * apt_update[Update the apt cache daily] action periodic (up to date)  * apt_package[apache2] action install (up to date) Running handlers:Running handlers completeChef Client finished, 0/2 resources updated in 02 seconds
You see that Chef does not apply any changes because there's nothing to do – it's not yet time to update the apt cache and the Apache package is already installed.

3. Start and enable the Apache service

Now let's first enable the Apache service when the server boots and then start the service. Modify webserver.rb to look like this.

Editor: ~/chef-repo/webserver.rb

1
2
3
4
5
6
7
8
9
10
11
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
This code declares multiple actions.
  Ubuntu 14.04 provides two init systems. The supports :status => true part tells Chef that the apache2 init script supports the status message. This information helps Chef use the appropriate strategy to determine if the apache2 service is running. If you're interested, read this blog post for more information.
Now apply it.

Terminal: ~/chef-repo

                   
skytap@host-1:~$ sudo chef-client --local-mode webserver.rb
[2016-10-19T19:06:22+00:00] WARN: No config file found or specified on command line, using command line options.[2016-10-19T19:06:22+00:00] WARN: No cookbooks directory found at or above current directory.  Assuming /root/chef-repo.Starting Chef Client, version 12.14.89resolving cookbooks for run list: []Synchronizing Cookbooks:Installing Cookbook Gems:Compiling Cookbooks...[2016-10-19T19:06:24+00:00] WARN: Node ubuntu-1404 has an empty run list.Converging 3 resourcesRecipe: @recipe_files::/root/chef-repo/webserver.rb  * apt_update[Update the apt cache daily] action periodic (up to date)  * apt_package[apache2] action install (up to date)  * service[apache2] action enable (up to date)  * service[apache2] action start (up to date) Running handlers:Running handlers completeChef Client finished, 0/4 resources updated in 02 seconds
The package is already installed, so there's nothing to do. Similarly, the service is already started and enabled. On some Linux distros, Apache is not started or enabled as it is installed. With Chef, this is easy to verify.

4. Add a home page

Let's spruce things up and add a custom home page.
You already know how to configure a file resource; append one that configures the default home page,/var/www/html/index.html, to the end of webserver.rb. The entire recipe now looks like this.

Editor: ~/chef-repo/webserver.rb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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

file '/var/www/html/index.html' do
  content '
  
    

hello world

'
end
  Versions of Ubuntu prior to 14.04 use /var/www/index.html as the default home page, so adjust your recipe accordingly if your version of Ubuntu is prior to 14.04.
Now apply it.

Terminal: ~/chef-repo

                                      
skytap@host-1:~$ sudo chef-client --local-mode webserver.rb
[2016-10-19T19:06:27+00:00] WARN: No config file found or specified on command line, using command line options.[2016-10-19T19:06:27+00:00] WARN: No cookbooks directory found at or above current directory.  Assuming /root/chef-repo.Starting Chef Client, version 12.14.89resolving cookbooks for run list: []Synchronizing Cookbooks:Installing Cookbook Gems:Compiling Cookbooks...[2016-10-19T19:06:29+00:00] WARN: Node ubuntu-1404 has an empty run list.Converging 4 resourcesRecipe: @recipe_files::/root/chef-repo/webserver.rb  * apt_update[Update the apt cache daily] action periodic (up to date)  * apt_package[apache2] action install (up to date)  * service[apache2] action enable (up to date)  * service[apache2] action start (up to date)  * file[/var/www/html/index.html] action create    - update content in file /var/www/html/index.html from 538f31 to 2914aa    --- /var/www/html/index.html    2016-10-19 19:06:08.969156760 +0000    +++ /var/www/html/.chef-index20161019-5424-ry33te.html  2016-10-19 19:06:29.777156760 +0000    @@ -1,379 +1,6 @@    -    -    -    -  <!--    -    Modified from the Debian original for Ubuntu    -    Last updated: 2014-03-19    -    See: https://launchpad.net/bugs/1288690[...]    -    
- +

hello world

- Running handlers:Running handlers completeChef Client finished, 1/5 resources updated in 02 seconds

5. Confirm your web site is running

Run the curl command to confirm that your web page is available.

Terminal: ~/chef-repo

      
skytap@host-1:~$ curl localhost
      

hello world

Normally, you could also access your web server from a browser on another machine. However, the free trial virtual machine does not have a public IP address.

Summary

You saw how to work with the package and service resources. You now know how to work with four types of resources: file,apt_updatepackage, and service.
You also saw how to apply multiple actions. But how does Chef know what order to apply resources and actions?

Chef works in the order you specify

Let's take another quick look at our web server recipe.

Editor: ~/chef-repo/webserver.rb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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

file '/var/www/html/index.html' do
  content '
  
    

hello world

'
end
The resources are applied in the order they are specified in the recipe. So here the apt cache is updated, the package is installed, then the service is configured, and finally the home page is set. If any resource is already in the desired state, Chef simply moves on to the next one.
The same idea applies to the action list [:enable, :start] for configuring the service. The service is enabled when the server boots and then it's started.
It's important to always think about how you order things. For example, the recipe wouldn't work if we tried to configure the Apache service before the package is even installed.
A recipe stops if any step fails (don't worry – Chef provides info about the error). That's why we ordered the service actions the way we did. If the service can't be enabled on boot then we don't want to start it.

Exercises

Exercise 1

Are these two recipes the same?

Editor: webserver.rb

1
2
3
4
5
package 'apache2'
service 'apache2' do
  supports :status => true
  action [:enable, :start]
end

Editor: webserver.rb

1
2
3
4
5
service 'apache2' do
  supports :status => true
  action [:enable, :start]
end
package 'apache2'
Answer 
No, they are not. Remember that Chef applies resources in the order they appear. So the first recipe ensures that theapache2 package is installed and then configures the service. The second recipe configures the service and then ensures the package is installed.
The second recipe may not work as you'd expect because the service resource will fail if the package is not yet installed.

Exercise 2

Are these two recipes the same?

Editor: webserver.rb

1
2
3
4
5
package 'apache2'
service 'apache2' do
  supports :status => true
  action [:enable, :start]
end

Editor: webserver.rb

1
2
3
4
5
package 'apache2'
service 'apache2' do
  supports :status => true
  action [:start, :enable]
end
Answer 
No, they are not. Although both recipes ensure that the apache2 package is installed before configuring its service, the first recipe enables the service when the system boots and then starts it. The second recipe starts the service and then enables it to start on reboot.

Exercise 3

Are these two recipes the same?

Editor: file.rb

1
2
3
4
5
6
file '/etc/motd' do
  owner 'root'
  group 'root'
  mode '0755'
  action :create
end

Editor: file.rb

1
2
3
4
5
6
file '/etc/motd' do
  action :create
  mode '0755'
  group 'root'
  owner 'root'
end
Answer 
Yes, they are! Order matters with a lot of things in Chef, but you can order resource attributes any way you want.

Exercise 4

Write a service resource that stops and then disables the apache2 service from starting when the system boots.
Hint: The documentation for the service resource lists the available actions.
Answer 
First, you can verify that Apache is running.

Terminal: ~/chef-repo

$         
curl -I localhostHTTP/1.1 200 OKDate: Thu, 05 Feb 2015 22:40:54 GMTServer: Apache/2.4.7 (Ubuntu)Last-Modified: Thu, 05 Feb 2015 22:34:56 GMTETag: "2cf6-50e5ee9d3e36e"Accept-Ranges: bytesContent-Length: 11510Vary: Accept-EncodingContent-Type: text/html
Here's the code that stops and disables the Apache service.

Editor: ~/chef-repo/webserver.rb

1
2
3
4
service 'apache2' do
  supports :status => true
  action [:stop, :disable]
end
Your modified webserver.rb file looks like this.

Editor: ~/chef-repo/webserver.rb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apt_update 'Update the apt cache daily' do
  frequency 86_400
  action :periodic
end

package 'apache2'

service 'apache2' do
  supports :status => true
  action [:stop, :disable]
end

file '/var/www/html/index.html' do
  content '
  
    

hello world

'
end
Run the recipe and verify that the service is no longer running.

Terminal: ~/chef-repo

$              $ 
sudo chef-client --local-mode webserver.rb[...]Converging 4 resourcesRecipe: @recipe_files::/home/skytap/chef-repo/webserver.rb  * apt_update[Update the apt cache daily] action periodic (up to date)  * apt_package[apache2] action install (up to date)  * service[apache2] action stop    - stop service service[apache2]  * service[apache2] action disable    - disable service service[apache2]  * file[/var/www/html/index.html] action create (up to date) Running handlers:Running handlers completeChef Client finished, 2/5 resources updated in 02 secondscurl -I localhostcurl: (7) Failed to connect to localhost port 80: Connection refused

No comments:

Post a Comment