2
votes

Background Info: I have made a Ruby on Rails application that utilizes the ruby gem Devise. When using the gem I have configured the gem's secret key in OpsWorks console as an environment variable.

Environment Variables in OpsWorks console

When running the before_migrate.rb deployment hook I run the command rake assets:precompile. But I receive an error in the deployment log.

execute "rake assets:precompile" do
   cwd release_path
   command "bundle exec rake assets:precompile"
   environment "RAILS_ENV" => rails_env
end

Error executing action run on resource 'execute[rake assets:precompile]' Mixlib::ShellOut::ShellCommandFailed

Expected process to exit with [0], but received '1' ---- Begin output of bundle exec rake assets:precompile --trace ---- STDOUT: STDERR:

** Invoke assets:precompile (first_time) ** Invoke assets:environment (first_time)

** Execute assets:environment

** Invoke environment (first_time)

** Execute environment rake aborted! Devise.secret_key was not set. Please add the following to your Devise initializer:

config.secret_key = '*****'

I know the environment variables are eventually being set because in my before_migrate.rb file I output the environment variables to log. When I hard code the config.secret_key everything works correctly.

Question: When using OpsWorks do the initializers config/initializers/* from my project get run before any of the environment variables get set? Is there another way around this without hard coding keys or SSHing into every instance?

1
Were you not able to access it simply by config.secret_key = ENV[ 'SECRET_KEY_BASE' ] ? - BinaryMee
That's correct. I tried that first, and it did not work. - Asdrubal

1 Answers

0
votes

You would be able to access the environment variable in the chef recipe by,

node[:deploy]['<YOUR_APP_SHORT_NAME>'][:environment_variables][:SECRET_KEY_BASE]

So you can write a recipe to put secrets.yml or something.yml with the environment value. Create a template,

your_cookbook/templates/default/secret.yml.erb

secret_key: <%= node[:deploy]['<YOUR_APP_SHORT_NAME>'][:environment_variables][:SECRET_KEY_BASE] %>

You can place the secret.yml in /data/YOUR_APPLICATION_SLUG_NAME/shared/config by a recipe.

your_cookbook/recipes/default/secret.rb

template "/data/#{<YOUR_APP_SLUG_NAME}/shared/config/secrets.yml" do
  source "secrets.yml.erb"
  owner 'OWNER'
end

And make sure that you are symlinking the secrets.yml in shared/config folder to your release path in before_migrate.rb in your deploy hooks.

your_code_path/deploy/before_migrate.rb

run "ln -nfs /data/<YOUR_APP_SLUG_NAME>/shared/config/secrets.yml #{release_path}/config/secrets.yml"

And have the recipe your_cookbook::secret in your deploy life cycle event.

Now you would have generated secrets.yml in your code path/config. You have to load that yaml and set it in config/initializer/devise.rb

config.secret_key = <SECRET KEY FROM THE YML GENERATED>