31

I've got vagrant running Ubuntu for development purposes. I've used a shell script provisioner to download/install my dependencies and create some aliases, but I've hit a wall in terms of using the provisioner to create environment variables (which are used for several flags within my project). Originally I had something like:

export MY_VAR='value'

Into my provisioner script, but then found out that you can't add environment variables from inside a shell script by running it normally. Fair enough, so I tried instead changing my line of the Vagrantfile to:

config.vm.provision "shell", inline: “source setup.sh"

Which didn't solve the problem. Environment variables still weren't there. I tried adding the exports directly as an inline:

config.vm.provision "shell", inline: “export MY_VAR='value'"

No luck. Still no global environment when I ssh'ed in. Is there a way to use the shell script to set a bash environment variable, or is it time to throw in the towel on shell provisioners and learn chef?

Community
  • 1
  • 1
MBrizzle
  • 1,783
  • 1
  • 18
  • 31

6 Answers6

34

You should have the provisioning script add a line to your .profile:

echo "export VAR=value" >> ~/.profile

On login, the .profile script will be read by bash and the variable will be set.

rje
  • 6,388
  • 1
  • 21
  • 40
20

Seeing as the accepted answer does indeed add an export VAR=value to your .profile (or .bashrc) file each time you run vagrant provision, here's how I've added environment variables quickly

source ~/.profile && [ -z "$VAR" ] && echo "export VAR=value" >> ~/.profile

Breakdown:

  • source ~/.profile: load the current .profile file
  • [ -z "$VAR"]: check whether or not VAR is set, if not:
  • echo "export VAR=value" >> ~/.profile: add the export line to .profile

Putting it all together:

I normally use puphpet for my vagrant boxes, so I tend to stick to the directory structure it uses, which means putting my provisioning script in puphpet/shell/* (relative to the Vagrantfile file). In that file, you can add as many environment variables as you like:

#!/usr/bin/env bash
#Replace .profile with .bashrc if required
source ~/.profile
if [ -z "$VAR" ]; then # only checks if VAR is set, regardless of its value
    echo "export VAR=value" >> ~/.profile
fi
#other env variables and profile stuff here

If you want to set the environment variables to a specific value, even if they're set, you can replace [ -z "$VAR" ] with this (As Maks3w suggested):

if [ -z "$VAR" ] || [ "$VAR" != "value" ]; then
    #same as before
fi

Then simply add this to your Vagrantfile:

config.vm.provision "shell", path: "puphpet/shell/your-script.sh"

That ought to do the trick...

Valter Silva
  • 16,446
  • 52
  • 137
  • 218
Elias Van Ootegem
  • 74,482
  • 9
  • 111
  • 149
  • I like the use of -z switch instead grep – Maks3w Mar 04 '15 at 14:04
  • I have answer with a 100% full Vagrant wat (without external script file) – Maks3w Mar 04 '15 at 14:21
  • @Maks3w: That would be a valid option, too. Not sure about the `[ $VAR != "value" ]` bit, since the env variable might could've been changed by the user of the vbox for development reasons, and he might not want the values to change by provisioning – Elias Van Ootegem Mar 04 '15 at 14:35
  • The provision phase of Vagrant since 1.4 (IIRC) is under user demand. So if he/she launch the provision phase then really wants reset the configs. – Maks3w Mar 04 '15 at 16:03
  • @Maks3w: Not necessarily. I use vagrant at work, we work in teams, and it often happens that someone updates the vagrant repo (add a vhost, or set up a new tool), which requires us to provision the boxes. I'd like the provisioning to _add_ the new stuff, without it disrupting my own changes. It's all down to the specific requirements/use-case of the OP IMHO – Elias Van Ootegem Mar 04 '15 at 17:51
  • We could chat about this but that approach IMO break the wonderful vagrant destroy && vagrant up for to have clean workspaces. – Maks3w Mar 04 '15 at 17:58
  • Works better than the approved answer. – iaforek Oct 26 '17 at 09:26
6

Here's how I got $GOPATH working:

config.vm.provision "shell", inline: <<-SHELL
  echo -n                              >  /etc/profile.d/gopath.sh
  echo 'export GOPATH=$HOME/go'        >> /etc/profile.d/gopath.sh
  echo 'export PATH=$PATH:$GOPATH/bin' >> /etc/profile.d/gopath.sh
SHELL

The use of single quotes and $HOME (instead of ~) were necessary---I couldn't make it work otherwise.

rubicks
  • 4,912
  • 1
  • 30
  • 41
5

This answer shows how to add environment variables just modifying VagrantFile using Ruby HEREDOC (Here doc) syntax

  $install_user_vars = <<SCRIPT
    source ~/.profile

    if [ -z "$VAR" ] || [ "$VAR" != "value" ]; then
      echo "export VAR=value" >> ~/.profile
    fi

    if [ $(pwd) != "/vagrant" ]; then
      echo "cd /vagrant" >> ~/.profile
    fi

SCRIPT

  config.vm.provision "shell", inline: $install_user_vars

Note: The close SCRIPT must be the first character in his own line

Elias Van Ootegem
  • 74,482
  • 9
  • 111
  • 149
Maks3w
  • 6,014
  • 6
  • 37
  • 42
1

I was looking for the same thing. I wanted to set http(s)_proxy environment variables in Vagrantfile. The requirement was that I can change these variables at any time and vagrant reload to apply them.

Finally, I came up with the solution:

config.vm.provision "shell", inline: "> /etc/profile.d/myvars.sh", run: "always"
config.vm.provision "shell", inline: "echo \"export http_proxy=http://proxy.somedomain.com:3128\" >> /etc/profile.d/myvars.sh", run: "always"
config.vm.provision "shell", inline: "echo \"export https_proxy=https://proxy.somedomain.com:3128\" >> /etc/profile.d/myvars.sh", run: "always"

0) /etc/profile.d/*.sh scripts are run at the startup of the bash shell
1) removes everything from myvars.sh
2) sets the first variable
3) sets the second variable

Because of run: "always" I can add/remove variables and after vagrant reload they are applied.

starikovs
  • 3,240
  • 4
  • 28
  • 33
0

In CentOs7 you need to place env vars under /etc/profile.d/ This worked in my case:

machine.vm.provision 'shell',
  inline: 'sudo su - && echo "export VAR1=test export VAR2=test" > /etc/profile.d/vars.sh'
hoisu
  • 305
  • 2
  • 14