More dynamic code using notifications

Wouldn't it be great if Chef knew how and what to restart automatically when a change arises? In a previous example, we added a new virtual host to our node, and we had to manually restart Apache to take the change into account. Luckily, there's a mechanism named notifications in Chef, that helps trigger an action, when a resource changes. This way, changing a virtual host can trigger a restart of the Apache HTTP server automatically.

Getting ready

To work through this recipe, you will need the following:

  • A working Chef DK installation on the workstation
  • A working Chef client configuration on the remote host
  • The Chef code from the previous recipes

How to do it…

We'll start from the apache cookbook we've left in its 0.3.0 version. Bump it right now to 0.4.0 so we're starting fresh in apache/metadata.rb:

version '0.4.0'

Every resource can notify another resource to do something when its state changes, and any resource can also subscribe to a change of state from another resource. In our case, we'd like our template resource to notify the httpd system service to restart when the Virtual Host template changes, so we're sure the change is automatically taken into account. The httpd service is coming from the default Apache recipe, so it’s better to include it right now in the apache/recipes/virtualhost.rb file, so we’re sure this particular recipe works alone and not by side-effect of a previous inclusion:

include_recipe 'apache::default'

  1. In the apache/recipes/virtualhost.rb file, add the following highlighted notification section:
    template "/etc/httpd/conf.d/#{node["sitename"]}.conf" do
      source "virtualhost.erb"
      owner 'root'
      group 'root'
      mode '0644'
      variables(
        :website => "#{node["sitename"]}"
      )
      notifies :restart, resources(:service => "httpd")
    end

    Note

    By default, actions are delayed at the end of the Chef run. If we need an action to take place immediately, at the risk of breaking the state of the system, we can add the :immediately timer at the end of the line.

  2. To validate it's working, we need to change something in our Virtual Host template in apache/templates/virtualhost.erb. For this example, I simply set the local IP the node is listening to, but feel free to adapt to your own case:
    <VirtualHost 192.168.146.129:80>
            ServerName <%= @website %>
            DocumentRoot /var/www/<%= @website %>
            ErrorLog /var/log/httpd/error-<%= @website %>.log
            CustomLog /var/log/httpd/access-<%= @website %>.log combined
    </VirtualHost>
  3. Now upload the updated cookbook (we've already bumped it):
    $ knife cookbook upload apache
    
  4. Run the Chef client on the node and see the magic happen:
    $ sudo chef-client
    [...]
      * template[/etc/httpd/conf.d/defaultsite.conf] action create
        - update content in file /etc/httpd/conf.d/defaultsite.conf from 6f4d47 to 05ea5b
        --- /etc/httpd/conf.d/defaultsite.conf   2016-10-17 01:05:49.243799676 +0000
        +++ /etc/httpd/conf.d/.chef-defaultsite20161017-14052-1xt951m.conf       2016-10-17 01:10:27.452670052 +0000
        @@ -1,4 +1,4 @@
        -<VirtualHost *:80>
        +<VirtualHost 192.168.146.129:80>
                 ServerName defaultsite
                 DocumentRoot /var/www/defaultsite
                 ErrorLog /var/log/httpd/error-defaultsite.log
    [...]
    Recipe: apache::default
      * service[httpd] action reload
        - reload service service[httpd]
    

The cool thing is we can even see a diff of the change in the logs so we always know what's changed, as well as see the httpd service being reloaded after the change happened.

Our system is now perfectly dynamic and can reload its configuration at will at every change.

There's more…

Puppet has exactly the same feature, using the notify attribute. When the content of /etc/apache2/sites-enabled is modified, Apache configuration needs to be reloaded.

Let's change our Apache manifest to do this.

Apache configuration needs to be reloaded when the default vhost is removed, so we need to modify modules/apache/manifests/init.pp with the corresponding notify attribute:

class apache {
    package {'apache2':
       ensure => present,
    }

    service {'apache2':
       ensure => running,
       enable => true
    }

    file {'/etc/apache2/sites-enabled/000-default.conf':
       ensure => absent,
       notify => Service['apache2'],
    }
}

The same logic applies for the virtual host creation (modules/apache/manifests/vhost.pp):

define apache::vhost (
     $website,
     $docroot
) {

  file { "/etc/apache2/sites-available/$website.conf":
     ensure  => present,
     owner   => 'root',
     group   => 'root',
     mode    => '0640',
     content => epp('apache/vhost.epp', 
                      {'website' => $website, 
                       'docroot'=>$docroot}),
  }

  file { "/etc/apache2/sites-enabled/$website.conf":
     ensure  => link,
     target  => "/etc/apache2/sites-available/$website.conf",
     require => File["/etc/apache2/sites-available/$website.conf"],
     notify  => Service['apache2'],
  }
}

Let's try to run the Puppet agent on fresh Vagrant boxes, we will see that the two modifications will schedule a configuration reload, that will be done at the end of the Puppet Agent run. (refer to the lines with Scheduling refresh of Service[apache2] and Triggered 'refresh' from 2 events):

Notice: /Stage[main]/Apache/File[/etc/apache2/sites-enabled/000-default.conf]/ensure: removed
Info: /Stage[main]/Apache/File[/etc/apache2/sites-enabled/000-default.conf]: Scheduling refresh of Service[apache2]
...
...
Notice: /Stage[main]/Main/Node[web.pomes.pro]/Apache::Vhost[web.pomes.pro]/File[/etc/apache2/sites-enabled/web.pomes.pro.conf]/ensure: created
Info: /Stage[main]/Main/Node[web.pomes.pro]/Apache::Vhost[web.pomes.pro]/File[/etc/apache2/sites-enabled/web.pomes.pro.conf]: Scheduling refresh of Service[apache2]
Notice: /Stage[main]/Apache/Service[apache2]: Triggered 'refresh' from 2 events
Notice: Applied catalog in 45.46 seconds

Now we can access the phpinfo page at http://web.pomes.pro without manually restarting Apache.

See also

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.107.96