Chef : Opsworks : run rake task

2k Views Asked by At

My objective is to execute a rake task on my apps running in Opsworks.
It appears to me that my opsworks cookbook is not running rake from the correct directory.

How can I tell the cookbook to run in the app home dir (so it can pick up the Gemfile)?
Do I need to specify an RAILS_ENV?

My cookbooks default.rb:

Chef::Log.info("****** Audit Photo URLS : Running Rake Task ******")
execute "rake audit:audi_image_urls" do
    command "bundle exec rake audit:audi_image_urls"
end

Errors from Opsworks log:

[2014-11-28T18:36:33+00:00] INFO: Running queued delayed notifications before re-raising exception
[2014-11-28T18:36:33+00:00] ERROR: Running exception handlers
[2014-11-28T18:36:33+00:00] ERROR: Exception handlers complete
[2014-11-28T18:36:33+00:00] FATAL: Stacktrace dumped to /var/lib/aws/opsworks/cache.stage2/chef-stacktrace.out
[2014-11-28T18:36:33+00:00] ERROR: execute[rake audit:audi_image_urls] (auditphoto::default line 3) had an error: Mixlib::ShellOut::ShellCommandFailed: Expected process to exit with [0], but received '10'
---- Begin output of bundle exec rake audit:audi_image_urls ----
STDOUT: Could not locate Gemfile
STDERR: 
---- End output of bundle exec rake audit:audi_image_urls ----
Ran bundle exec rake audit:audi_image_urls returned 10
[2014-11-28T18:36:33+00:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)
1

There are 1 best solutions below

10
On BEST ANSWER

The execute resource can take a cwd attribute for the working directory from which the command is run.

execute "rake audit:audi_image_urls" do
  command       "bundle exec rake audit:audi_image_urls"
  cwd           '/over/there'
  environment   'RAILS_ENV' => 'production'
end

OpsWorks Deploy events and Execute Recipes commands

Chef 11

OpsWorks populates node[:deploy]['appshortname'] for Deploy events and Execute Recipes stack commands to house each applications configuration. With this data you could use:

execute "rake audit:audi_image_urls" do
  command       "bundle exec rake audit:audi_image_urls"
  cwd           node[:deploy]['appshortname'][:deploy_to]
  user          node[:deploy]['appshortname'][:user]
  group         node[:deploy]['appshortname'][:group]
  environment(  { 'RAILS_ENV' => node[:deploy]['appshortname'][:rails_env] } )
end

You may want to source :environment_variables for the environment if you have anything related configured there.

Chef 12

From the AWS stack settings docco

In Chef 12 Linux, stack settings are available as Chef data bags and are accessed only through Chef search. Data bags are stored on AWS OpsWorks Stacks instances in a set of JSON files in the /var/chef/runs/run-ID/data_bags directory, where run-ID is a unique ID that AWS OpsWorks Stacks assigns to each Chef run on an instance. Stack settings are no longer available as Chef attributes, so stack settings can no longer be accessed through the Chef node object. For more information, see the AWS OpsWorks Stacks Data Bag Reference.

app = search("aws_opsworks_app").first

execute "rake audit:audi_image_urls" do
  command       "bundle exec rake audit:audi_image_urls"
  cwd           app['app_source']['deploy_to']
  user          app['app_source']['user']
  group         app['app_source']['group']
  environment(  { 'RAILS_ENV' => app['app_source']['rails_env'] } )
end

Other events and commands

It looks like OpsWorks runs a little differently to a normal Chef server and supplies it's own JSON blob to a local chef instance for each run which means (as you mentioned) the :deploy attributes will be missing for other events/commands Amazon chooses not to supply JSON for.

It might be possible, but very hacky and prone to breakage, to populate the :deploy attributes from the last JSON file that contains deploy state: {"deploy": { "app_name": { "application": "app_name" } in /var/lib/aws/opsworks/chef

You would also need to source the deploy::default attributes after that JSON load to fill in any defaults.