2013-03-05

Forcing a service to stop during Chef execution

My latest project at work has been to get a Chef installation going for a client who is migrating a site from a traditional datacenter to Amazon Web Services. And part of the unique snowflake of a deploy process for this application is that it must be restarted on every deploy because the config files are included in the deploy - apache's httpd.conf, tomcat's server.xml, etc. etc. Most importantly is that if you don't stop the service before the first deploy, it will most likely not stop at all because it makes significant changes to the configuration (pid file locations, etc.). NOTE: I would NOT have designed the deploy process this way, but I'm stuck with it for  now. So, in the meantime, this is how I deal with it:

1) Right after the service definition in the default recipe (e.g. apache2::default), create a semaphore file that forces the service to stop if this file doesn't exist (it shouldn't):

file "/tmp/gather-apache2-semaphore" do
    mode 00644
    owner "root"
    group "root"
    action :create
    content "must stop apache"
    notifies :stop, resources(:service => "apache2"), :immediately
end

2) Make sure your application deploy recipe notifies a restart of the service (e.g. apache2::example_app_config):

ruby_block "copy_httpd.conf" do
    block do
         FileUtils.copy_file("#{deploy_directory}/example_app/build_out/dist/conf/httpd.conf","/etc/apache2/httpd.conf")
    end
    notifies :restart, resources(:service => "apache2")
end

and/or if you are calling this from another recipe (e.g. example_app::deploy):

include_recipe "apache2"

bash "copy_example_app_htdocs.tar" do
    user "root"
    cwd "#{deploy_directory}/example_app/build_out/dist"
    code <<-EOH
        tar --extract --file=example_app_htdocs.tar --directory /etc/apache2/htdocs
    EOH
    only_if { ::File.exists?("/etc/apache2/htdocs") }
    notifies :restart, resources(:service => "apache2")
end

3) Finally, after all the key recipes have been run to deploy your unique snowflake, the service will have been restarted and you can clean-up your semaphore that will force the service to be restarted next time you deploy.

file "/tmp/gather-apache2-semaphore" do
    action :delete
end

Now the service will be guaranteed to be stopped while your application deploying.

Ratings and Recommendations by outbrain