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.
To work through this recipe, you will need the following:
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'
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
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>
$ knife cookbook upload apache
$ 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.
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.
18.119.107.96