AWS OpsWorks Environment variables not working
Asked Answered
S

3

10

I am running Ubuntu 14.04 LTS 64 bit Rails Application and I am unable to access my App environment variables.

In OpsWorks App panel, I set my environment variables, say:

MYKEY: 1234

Then I save and deploy my app again to make these visible.

In my Rails app, or the rails console I get nil:

$ bundle exec rails c production
>ENV["MYKEY"]
=> nil

I have tried restarting the server. I'm not sure what I am missing, I have been using environment variables in other services.

How can I trace where these should be set?

Soonsooner answered 28/2, 2015 at 0:54 Comment(7)
If I ssh in and run sudo opsworks-agent-cli get_json I do see the MYKEY is there { "deploy": { "server": { "environment": { "MYKEY": "1234" } .. Soonsooner
Did you get solution for this?Lobito
Weird thing is it turned out it works in the Passenger production instances, but doesn't work when I $ bundle exec rails c production as deploy user (Which is the same user Passenger is running under). Apache is running under www-data, but if I sign in as either www-data or deploy I don't see any env vars set. So I'm running, but I have no idea what is going on under the hood.Soonsooner
Are you sayin in application you have the access to the ENV variables?Lobito
Yes. And I also see them in the output log when running deploy in opsworks portal (not sure if I saw them there when I first posted)Soonsooner
Great, I will check nowLobito
I answered with more details and with a full how-to-do guide. Please check out that and think about to mark it as the right answer. Thank youGalvanotropism
R
4

OpsWorks stores environmental variables in different places depending on what kind of app you're deploying. On Rails / Passenger they should be saved in the Apache config file #{your_app_name}.conf. (Source)

This means they aren't available in your normal shell environment.

I know the Node.js recipes stored everything in an /srv/www/#{app_name}/shared/app.env file... which is then sourced to pull in the environment to run the Node server. This implementation detail also meant you could write shell scripts that sourced that app.env file, then called some Node script or whatever.

Of course, Rails isn't Node. I have no idea if the environmental variables are also stored somewhere else or not: a quick look at the Rails recipes in the OpsWorks cookbooks didn't find anything obvious, but maybe I missed something.

Depending on the amount of modifications you have going on in your OpsWorks cookbook, you could create a deploy recipe that does something like this:

application_environment_file do user deploy[:user] group deploy[:group] path ::File.join(deploy[:deploy_to], "shared") environment_variables deploy[:environment_variables] end

(maybe adjusting the path)

Then to run your console, when you're SSHed into the server, do something like

sudo source /srv/www/my_app_name/shared/app.env; bundle exec rails console -e production or whatever.

Rumple answered 16/3, 2015 at 15:26 Comment(2)
Thank you so much, this is the right information! If I view /etc/apache2/sites-enables/myapp.conf I do see in there SetEnv "PKTEST" "testing" so clearly that is where OpsWorks is actually writing to, and why it can't be seen running rails console.Soonsooner
I answered with more details and with a full how-to-do guide. Please check out that and think about to mark it as the right answer. Thank you.Galvanotropism
G
3

AWS OpsWorks console lets you declare environment variables but to let them be available for our Rails app we need to use a Chef cookbook recipe plus some precautions.

In a nutshell we use the config/secrets.yml file combined with config/application.yml file, Figaro gem and a Chef cookbook recipe. The chef cookbook recipe read the variables defined in OpsWorks console and let them available to Rails app writing the config/application.yml file.

I have published a detailed guide to explain how exactly do it. Link here.

These are the core points that I covered:

  1. Use config/secrets.yml file (added from Rails 4.1)
  2. Use Figaro gem to load variables in the environment
  3. Declare environment variables inside AWS OpsWorks Console
  4. Use a custom Chef recipe to create a config/application.yml file that Figaro will use to let variables available
Galvanotropism answered 14/3, 2016 at 14:32 Comment(0)
U
1

I (with some help from Bruno at the AWS PopUp Loft in NYC) added some custom Chef code inside the after_restart.rb deploy hook, simply add the folder "deploy" to your apps root directory and inside add "after_restart.eb." In it ....

Chef::Log.info("Running deploy/after_restart.rb")

contents = []

node[:deploy].each do |application, deploy|
  deploy[:environment_variables].each do |key, value|
    contents << "export #{key}=\"'#{value}'\""
  end
end


Chef::Log.info("Adding the environment variables to /etc/profile.d/startup_env_config.sh")

bash "create_startup_env_config.sh" do
  user "root"
  cwd  "/etc/profile.d"
  code <<-EOH
    echo \''#{contents.join(" ")}\'' > startup_env_config.sh
    source startup_env_config.sh
    cd #{release_path}

    EOH
  end

And that's it. If you update the environment variables inside the OpsWorks panel remember to restart your instances.

Underskirt answered 5/12, 2015 at 1:14 Comment(3)
I tried this recipe but it didn't work! I added my answer below with a full detailed how-to-do guideGalvanotropism
I made a slight changeUnderskirt
Hmm - sorry it didn't work for you. I've been using this method for several months now in a production environment w/o fail. Glad you found an alt solutionUnderskirt

© 2022 - 2024 — McMap. All rights reserved.