How can you use a Chef recipe to set an environment variable?
Asked Answered
L

5

35

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?

Loving answered 8/6, 2011 at 20:1 Comment(2)
What's the context for the environment variable you want to set?Convulsive
Can you extend your question? It seems like it has been answered, unless you share more info or give us some feedback.Manners
S
28

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.

Springhead answered 18/10, 2011 at 13:40 Comment(2)
Could you please explain how to set an environment variable permanently via chefCampaign
@Campaign - check out the magic_shell cookbook - community.opscode.com/cookbooks/magic_shellMetcalf
B
14

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
Breezeway answered 17/2, 2013 at 4:0 Comment(9)
Just 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/* automaticallyStoicism
@Stoicism you can force that to happen by forcing an interactive login and/or sourcing /etc/profile in the Ruby script.Breezeway
thanks, @sethvargo. To update an environment variable, such as $PATH, how should I use the magic_shell cookbook?Metcalf
magic_shell_environment 'PATH' do value '$PATH:whatever' endBreezeway
@Stoicism - does my problem (#22619460) show a concrete example of the potential problem you mentioned?Metcalf
If you're trying to roll your own installer, you might want to check out Ark instead.Haig
@Breezeway 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?Afterguard
@pkyeck no, that is how shell loading works. You will need to reload the shell after setting the envar.Breezeway
@Breezeway Is there any way to source the profile file during the execution of a recipe. execute 'source /etc/profile' certainly doesn't work as source is not available in the ruby shell and it is running in a sub-shell anyway.Lather
D
5

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
Densimeter answered 27/4, 2016 at 16:55 Comment(0)
P
2

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:

  1. Create a template script (such as chef.sh.erb)
  2. Fill out the template script:

    #!/bin/bash export CHEF_LICENSE='accept' # Needed for Chef Infra Client 15

  3. 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:

template resource
windows_env resource

Pasteurism answered 14/5, 2019 at 18:33 Comment(1)
The Linux part was extremely helpful and worked perfectly. Thank you so much!Fugate
D
0

For Linux, the best way to it is by using

ENV['Var'] = 'Value'

When you use this command, every sub process spun by the recipe will be using this ENV value. You can verify it using a bash resource and echoing the value of Var.

Dorettadorette answered 14/11, 2019 at 6:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.