23
votes

I am using vagrant with puppet to set up virtual machines for development environments. I would like to simply set a few environment variables in the .pp file. Using virtual box and a vagrant base box for Ubuntu 64 bit.

I have this currently.

$bar = 'bar'

class foobar {
   exec { 'foobar':
     command => "export Foo=${bar}",
   }
}

but when provisioning I get an error: Could not find command 'export'.

This seems like it should be simple enough am I missing some sort of require or path for the exec type? I noticed in the documentation there is an environment option to set up environment variables, should I be using that?

9

9 Answers

21
votes

If you only need the variables available in the puppet run, whats wrong with :

Exec { environment => [ "foo=$bar" ] }

?

16
votes

Simplest way to acomplish this is to put your env vars in /etc/environment, this ensures they are available to everything (or pretty much everything).

Something like this:

class example($somevar) {
    file { "/etc/environment":
        content => inline_template("SOMEVAR=${somevar}")
    }
}

Reason for having the class parameterised is so you can target it from hiera with automatic variable lookup (http://docs.puppetlabs.com/hiera/1/puppet.html#automatic-parameter-lookup) ... if you're sticking something in /etc/environment, it's usually best if you actually make it environment specific.

note: I've only tested this on ubuntu

4
votes

The way I got around it is to also use /etc/profile.d:

$bar = 'bar'
file { "/etc/profile.d/my_test.sh":
  content => "export Foo=${bar}",
  mode    => 755
}

This ensures that everytime you login (ex ssh), the variable $MYVAR gets exported to your environment. After you apply through puppet and login (ex ssh localhost), echo $Foo would return bar

4
votes

You can set an environment variable by defining it on a line in /etc/environment and you can ensure a line inside a file using file_line in puppet. Combine these two into the following solution:

file_line { "foo_env_var":
    ensure  => present,
    line    => "Foo=${bar}",
    path    => "/etc/environment",
}
2
votes

You could try the following, which sets the environment variable for this exec:

class foobar {
   exec { 'foobar' :
     command => "/bin/bash -c \"export Foo=${bar}\"",
   }
}
2
votes

Something like this would work while preserving existing contents of the /etc/environment file:

/code/environments/{environment}/manifests/environment/variable.pp:

define profile::environment::variable (
    $variable_name,
    $value,
    $ensure => present,
) {
    file_line { $variable_name:
        path   => '/etc/environment',
        ensure => $ensure,
        line   => "$variable_name=$value",
        match  => "$variable_name=",
    }
}

Usage (in the body of a node manifest):

profile::environment::variable { 'JAVA_HOME':
    variable_name  => 'JAVA_HOME',
    value => '/usr/lib/jvm/java-1.8.0',
}
0
votes

I know this is an old question, but I was able to set the PS1 prompt value and add it to my .bashrc file like this:

$PS1 = '\[\e[0;31m\]\u\[\e[m\] \[\e[1;34m\]\w\[\e[m\] \$ '

and within a class:

exec {"vagrant-prompt":
  unless =>  "grep -F 'export PS1=\"${PS1}\"' ${HOME_DIR}/.bashrc",
  command => "echo 'export PS1=\"${PS1}\"' >> ${HOME_DIR}/.bashrc",
  user => "${APP_USER}",
}

The -F makes grep it interpret it as a fixed string. Otherwise it won't find it and keeps adding to the .bashrc file.

0
votes

Another variation. This has the advantage that stdlib isn't required (as is with file_line solutions), and the existing content of /etc/environment is preserved:

exec {'echo foo=bar>>/etc/environment':
  onlyif => 'test -f /etc/environment',
  unless => 'grep "foo=bar" /etc/environment',
  path   => '/usr/bin',
}
0
votes

Check out the documentation https://puppet.com/docs/puppet/5.5/types/exec.html

class envcheck {

  file { '/tmp/test':
    ensure => file,
  }

  exec { 'foobar':
    command     => 'echo $bar >> /tmp/test',
    environment => ['bar=foo'],
    path        => ['/bin/'],
  }
}
  1. Creating an empty file because an echo would happen in the shell Puppet is running the command in, not the one we're looking at.
  2. Setting an environment variable bar to equal foo.
  3. Setting the path for the echo binary, this isn't normally necessary for system commands but useful to know about.