0
votes

I have successfully deployed my application using AWS OpsWorks, now I am trying to implement a custom Chef Cookbook that will allow me to set the bash environment variables. I have setup the Git repo the cookbook is being updated with OpsWorks. I generated the cookbook using the knife command on my dev box which is really just the directory structure with a recipes/default.rb file containing a few lines of code.

When I try to do something like the following I seem to keep getting errors

node[:deploy].each do |application, deploy|
    deploy = node[:deploy][application]
    command "ls -la"
end

(Note: ls -la is just for testing i know this will not set the environment variables)

I get the following error: ERROR: Caught exception during execution of custom recipe: xyz-enviroment: NoMethodError - undefined method command' for #<Chef::Recipe:0x7feb59200c00> - /opt/aws/opsworks/releases/20130328224322_109/vendor/bundle/ruby/1.8/gems/chef-0.9.15.5/bin/../lib/chef/mixin/recipe_definition_dsl_core.rb:56:in method_missing

Also if I try something like

execute "setting up the enviroment" do
    # TODO: Add code that does something here
end

I get the following error:

execute[setting up the enviroment] (/opt/aws/opsworks/current/site-cookbooks/xyz-enviroment/recipes/default.rb:18:in `from_file') had an error:
No such file or directory - setting up the enviroment

I'm new to Chef so I'm sure there is something simple I'm doing wrong I just haven't been able to figure it out. Thanks in advance for the help.

5

5 Answers

4
votes

I already solved my issue before seeing the responses below, they may have worked to solve the issue but I don't have the time to go back and try them now.

My solution was to use a Chef template to create an initializer file to set the variables when rails boots up the application.

# deafult.rb

node[:deploy].each do |application, deploy|
    deploy = node[:deploy][application]

    execute "restart Rails app #{application}" do
        cwd deploy[:current_path]
        command node[:opsworks][:rails_stack][:restart_command]
        action :nothing
    end

    template "#{deploy[:deploy_to]}/current/config/initializers/dev_enviroment.rb" do
        source "dev_enviroment.erb"
        cookbook 'dev-enviroment'
        group deploy[:group]
        owner deploy[:user]
        variables(:dev_env => deploy[:dev_env])

        notifies :run, resources(:execute => "restart Rails app #{application}")

        only_if do
            File.exists?("#{deploy[:deploy_to]}") && File.exists?("#{deploy[:deploy_to]}/current/config/")
        end
    end
end

dev_enviroment.erb

ENV['VAR1'] = "<%= @dev_env[:VAR1] %>"
ENV['VAR2'] = "<%= @dev_env[:VAR2] %>"

The custom Chef JSON used in the Opsworks stack layer:

{
    "deploy": {
        "myapp": {
            "dev_env": {
                "VAR1": "INFO1",
                "VAR2": "INFO2",
            }
        }
    }
}
2
votes

You didn't specify what command to run, so it's actually trying to run setting up the environment, which isn't a valid command.

Try instead specifying the command attribute inside the block:

execute "setting up the enviroment" do
  command "/path/to/command --flags"
end

Alternatively, set the resource name to the command itself:

execute "/path/to/command --flags" do
  # TODO: Add code that does something here
end
2
votes

Your second question was correctly answered by clb. As for your first, 'command' is not a valid chef resource, you want something like:

node[:deploy].each do |application, deploy|
  deploy = node[:deploy][application]
  execute "running a command for #{application}" do
    command "ls -la"
  end
end
1
votes

OpsWorks has a new feature, where you can add Environmentvariables on the App

You can access them via

node[:deploy]['appshortname'][:environment_variables][:variable_name]

( see http://docs.aws.amazon.com/opsworks/latest/userguide/attributes-json-deploy.html#attributes-json-deploy-app-environment )

So you can directly set them for your chef context like this:

node[:deploy]['magento']['environment_variables'].each {|key, value| ENV[key]=value }

And you can "dump" that into a shell script for example like this:

file "#{release_path}/environment.sh" do
  content ENV.reduce("#!/bin/bash\n") { |a, e| a + "export #{e[0]}=\"#{e[1]}\"\n" }
  mode '0775'
end
0
votes

We do something similar, and solved it by adding our environment variables to the json config file in Opsworks dashboard. In chef, we write the file on deploy with this template: https://github.com/octocall/opsworks-cookbooks/blob/34e60267a4d3b5b9cf84e91829cc80c98c26f8ed/deploy/definitions/opsworks_rails.rb#L26, and then we symlink it using the "symlink_before_migrate" property of the json file, like this:

{
  "deploy": {
    "APPNAME": {
      "symlink_before_migrate": {
        "config/.env": ".env"
      }
    }
  }
}