Hello,
Let’s assume the following code that sums up my current recipe i.e. installation of a package and configuration of the service from this package.
#
# install_recipe.rb
#
package 'mypackagewithmyservice'
template 'configfile1'
notifies :restart, 'service[myservice]', :immediately
end
...
template 'configfileN'
notifies :restart, 'service[myservice]', :immediately
end
service 'myservice' do
action [:start, :enable]
end
execute "a command that waits for the service to be fully responsive"
#
# specific_configuration_recipe.rb
#
execute "a command that communicate with the server to do further configuration through e.g. REST API"
The problem with this code:
- The service is restarted on every configuration change even during the first chef run when installing the package and configuring the service for the first time.
- Changing the notifies last argument to :delayed seems to not be an option here. The problem is that we need to have a fully configured server before trying to run the second recipe (specific_configuration_recipe.rb)
I guess this pattern can be quite typical for more complex services and it seems similar questions have been asked without a definitive answer (see http://stackoverflow.com/questions/21066591/minimize-service-restarts-from-chef-notifications). My current solution to the above problems is as follows.
#
# install_recipe.rb
#
package 'mypackagewithmyservice'
config_changed_action = "config changed for myservice"
template 'configfile1'
notifies :run, "ruby_block[#{config_changed_action}]", :immediately
end
...
template 'configfileN'
notifies :run, "ruby_block[#{config_changed_action}]", :immediately
end
ruby_block config_changed_action do
block { node.set[:myservice][:config_changed] = true }
action :nothing
end
ruby_block "restart myservice" do
block {}
notifies :restart, "service[myservice]", :immediately
only_if { node[:myservice][:config_changed] }
end
service 'myservice' do
action [:start, :enable]
end
execute "a command that waits for the service to be fully responsive"
#
# specific_configuration_recipe.rb
#
execute "a command that communicate with the server to do further configuration through e.g. REST API"
But the question is if there is a more elegant way to do it? Maybe it is a good starting point for a future enhancement? I was thinking about adding additional argument to the notifies property like :delay_to_the_nearest_resource_block_below_this_line.
Regards,
Piotr