How can you use a Chef recipe to set an environment variable?
Solution 1
If you need an env var set strictly within the Chef process, you can use ENV['foo'] = 'bar
' since it's a ruby process.
If you need to set one for an execute provider, Chef exposes an environment hash:
execute 'Bootstrap the database' do
cwd "#{app_dir}/current"
command "#{env_cmd} rake db:drop db:create db:schema:load RAILS_ENV=#{rails_env}"
environment 'HOME' => "/home/#{app_user}"
user app_user
action :run
not_if %[psql -U postgres -c "\\l" | grep #{db_name}]
end
If you're looking to set a persistent environment variable then you may want to have Chef edit /etc/profile.d/chef.sh
, /etc/environment
, a users' profile, etc.
Solution 2
If you want to set it on the system with Chef, checkout the magic_shell cookbook.
magic_shell_environment 'RAILS_ENV' do
value 'production'
end
Solution 3
If you want to set it at the system level in /etc/environment
, you can do so directly per the following example without adding an additional recipe (this adds two env variables for Java):
sys_env_file = Chef::Util::FileEdit.new('/etc/environment')
{
'JAVA_HOME' => '/usr/lib/jvm/java-1.7.0-openjdk-amd64',
'LD_LIBRARY_PATH' => '/usr/lib/jvm/java-1.7.0-openjdk-amd64/lib'
}.each do |name, val|
sys_env_file.insert_line_if_no_match /^#{name}\=/, "#{name}=\"#{val}\""
sys_env_file.write_file
end
Solution 4
The way to do this is different between Windows and Linux. The easiest way would be:
Windows
Use the windows_env resource to create a System environment variable:
windows_env 'CHEF_LICENSE' do
value 'accept'
end
Linux
If you only need it for the cookbook run and its children, then use the Ruby ENV resource. This will NOT be permanent:
ENV['CHEF_LICENSE'] = 'accept'
If you need it to be permanent (and use bash):
Create a script in /etc/profile.d:
- Create a template script (such as chef.sh.erb)
-
Fill out the template script:
#!/bin/bash export CHEF_LICENSE='accept' # Needed for Chef Infra Client 15
-
Put the template resource in your recipe (You may want to set attributes and owner/group settings, I wanted to keep this example simple)
template '/etc/profile.d/chef.sh' do source 'chef.sh.erb' end
Here are some additional resources to read up on the different resources referenced here:
Comments
-
Brandon over 3 years
How can you use a Chef recipe to set an environment variable?
I need to set an environment variable using a Chef recipe. Can you provide an example of how to accomplish this?
-
matt about 11 yearsJust a note for others who are googling -- magic_shell_environment is fantastic, with one gotcha. Any command invoked with system("/new/process/to/call") from a ruby script will not pull from /etc/profile.d/* automatically
-
sethvargo about 11 years@matt you can force that to happen by forcing an interactive login and/or sourcing
/etc/profile
in the Ruby script. -
Kevin Meredith about 10 yearsthanks, @sethvargo. To update an environment variable, such as
$PATH
, how should I use themagic_shell
cookbook? -
sethvargo about 10 yearsmagic_shell_environment 'PATH' do value '$PATH:whatever' end
-
Kevin Meredith about 10 years@matt - does my problem (stackoverflow.com/questions/22618960/…) show a concrete example of the potential problem you mentioned?
-
Prats about 10 yearsCould you please explain how to set an environment variable permanently via chef
-
Kevin Meredith almost 10 years@Prats - check out the
magic_shell
cookbook - community.opscode.com/cookbooks/magic_shell -
Zook almost 10 yearsIf you're trying to roll your own installer, you might want to check out Ark instead.
-
Philipp Kyeck about 9 years@sethvargo I want to use the variable right after I set it but it is empty. next time I run the recipes, everything is fine ...!? am I doing something wrong?
-
sethvargo about 9 years@pkyeck no, that is how shell loading works. You will need to reload the shell after setting the envar.
-
Cristian Vrabie about 8 years@sethvargo Is there any way to
source
the profile file during the execution of a recipe.execute 'source /etc/profile'
certainly doesn't work assource
is not available in the ruby shell and it is running in a sub-shell anyway. -
Arijit almost 5 yearsThe Linux part was extremely helpful and worked perfectly. Thank you so much!