3

Does anyone have experience/success using the whenever gem on aws opsworks? Is there a good recipe? Can I put that recipe on a separate layer and associate one instance with that additional layer? Or is there a better way to do it? Thanks!!!

EDIT:

We ended up doing it a bit differently...

Code:

Can’t really post the real code, but it’s like this:

in deploy/before_migrate.rb:

[:schedule].each do |config_name|
  Chef::Log.info("Processing config for #{config_name}")
  begin
    template "#{release_path}/config/#{config_name}.rb" do |_config_file|
      variables(
        config_name => node[:deploy][:APP_NAME][:config_files][config_name]
      )
      local true
      source "#{release_path}/config/#{config_name}.rb.erb"
    end
  rescue => e
    Chef::Log.error e
    raise "Error processing config for #{config_name}: #{e}"
  end
end

in deploy/after_restart.rb:

execute 'start whenever' do
  cwd release_path
  user node[:deploy][:APP_NAME][:user] || 'deploy'
  command 'bundle exec whenever -i APP_NAME'
end

in config/schedule.rb.erb:

 <% schedule = @schedule || {} %>

set :job_template, "bash -l -c 'export PATH=/usr/local/bin:${PATH} && :job'"
job_type :runner,  'cd :path && bundle exec rails runner -e :environment ":task" :output'
job_type :five_runner, 'cd :path && timeout 300 bundle exec rails runner -e :environment ":task" :output'
set :output, 'log/five_minute_job.log' 
every 5.minutes, at: <%= schedule[:five_minute_job_minute] || 0 %> do
  five_runner 'Model.method'
end
nroose
  • 1,689
  • 2
  • 21
  • 28
  • 1
    We ended up handling this as follows: Add a value in the stack json to specify which host to run the whenever cron, and default to rails_app1 Have a deploy hook in the rails project that runs whenever only on that host. This puts the cron on the first host or whichever we specify and is pretty easy to configure and manage. We also have an erb file that gets evaluated to schedule.rb so that we can set various parameters like the time something gets run each day or the minute it gets run each hour. This erb file is evaluated in the deploy hooks as well. – nroose Apr 16 '15 at 22:11
  • If possible, could you share the code please ? – jwako Apr 17 '15 at 00:50
  • Yes please nroose, some more detailed advice would be awesome. – Alex Arvanitidis Jun 25 '15 at 20:14
  • Sorry for the delay. In our stack json we have `{ "deploy" : {"my_app" : { "job_hosts" : { "whenever" : "rails-app1"...`. In the deploy hook after_restart.rb, we have something like `if node[:deploy][:my_app][:job_hosts][:whenever] == node[:opsworks][:instance][:hostname] execute 'start whenever' do cwd release_path user node[:deploy][:yardhound][:user] || 'deploy' command 'bundle exec whenever -i my_app' environment 'RAILS_ENV' => rails_env end end ` – nroose Jun 26 '15 at 21:05

1 Answers1

7

We have a whenever cookbook in our repo we use that you would be more than welcome to use here: https://github.com/freerunningtech/frt-opsworks-cookbooks. I assume you're familiar with adding custom cookbooks to your opsworks stacks.

We generally run it on its own layer that also includes the rails cookbooks required for application deployment (while not the app server):

  • Configure: rails::configure
  • Deploy: deploy::rails whenever
  • Undeploy: deploy::rails-undeploy

However, we usually also deploy this instance as an application server, meaning we do end up serving requests from the box we're using for whenever as well.

There is one "gotcha", in that you must set your path in the env at the top of the schedule.rb like this:

env :PATH, ENV['PATH']
Clarke Brunsdon
  • 305
  • 2
  • 6
  • 1
    How do you set up running a recipe on just one of a layer's instances ? I think you use `--roles` option, but does it woks all right ? In rails app, `layers` are the same as `rails-app` across instances. – jwako Apr 16 '15 at 13:09