Environment Variables


#1

Hi,

Chef open source server v11.1.7
chef-client v12.5.1

I am aware I can manually set environment variables that are persistent throughout the chef-client run via
ENV[‘FOO’] = ‘bar’

BUT

I have a requirement in my chef automation to source multiple environment variables by sourcing a shell script.

e.g.

source /u01/server/bin/setEnv.sh
OR
. /u01/server/bin/setEnv.sh

This setEnv script sets various environment variables and also internally invokes further shell scripts which set even more environment variables, all of which are required for the subsequent command to run properly.

Is there a way I can set environment variables in a recipe by sourcing from a shell script instead of having to manually set each environment var one by one? (which sometimes I don’t even know the values because the setENV script is dynamically calculating the env values)


e.g. what i would like to do:

Start Recipe

  <step 1 - set various environment variables *by sourcing from a shell script*>
  <step 2 - run chef resources which require all the env vars set in step 1>

End Recipe



#2

Short of writing a Bash parser (https://github.com/poise/poise-languages/blob/master/lib/poise_languages/scl/mixin.rb#L56-L79), no. source is a bash internal function, which means it only affects the environment variables set in the bash process and environment variables are only passed from parent to child process, not vice versa. You could run all the relevant commands in script resources and source the required file in each of them, or maybe make a custom resource to handle that pattern.


#3

Thanks coderanger.

Not really elegant, but managed to work-around by running a “env” before and after Step 1 above and manually comparing the differences in env variables set after the setEnv.sh command.

Then had to create the 30+ env vars using the [ENV] directive - messy but will have to do for now.

BTW, just wondering…if I create a bash script and within it set the env var as well as execute step 2, would the env vars be available then?

e.g.

bash ‘do something’ do
code <<-EOH
source /u01/server/bin/setEnv.sh
{ Run step # 2 here }
EOH
end


#4

Just in case anyone else has the same problem, this is ultimately what I implemented:

In the attributes file, create a hash of all the environment variables you want, like so…

default['my_cookbook']['env'] = {'JAVA_USE_64BIT' => "true",
                                    'JAVA_VENDOR' => 'Oracle'}

Then, in the cookbook/recipe, for example in a execute resource, refer the environment hash in this way:

execute ‘some command’ do
user 'someuser’
group 'somegroup’
cwd 'somecwd’
environment (node[‘my_cookbook’][‘env’])
command 'somecommandwhichneedsenvvarsset’
end

You can also directly set multiple env vars within the execute block like so…

execute ‘some command’ do
user 'someuser’
group 'somegroup’
cwd 'somecwd’
environment ({‘JAVA_USE_64BIT’ => “true”,
‘JAVA_VENDOR’ => ‘Oracle’})
command 'somecommandwhichneedsenvvarsset’
end