将环境变量传递给vagrant shell provisioner

将环境变量传递给vagrant shell provisioner,vagrant,environment-variables,Vagrant,Environment Variables,如果您使用的是Ruby provisioner,那么在调用vagrant up时传递环境变量似乎很简单: VAR=123 vagrant up 在文件中: ENV['VAR'] config.vm.provision "shell", path: "provisionscript.sh", env: {"MYVAR" => "value"} 如何使用:shellprovisioner执行此操作?简单地这样做似乎不起作用: $VAR 这并不理想,但我现在要做的是: config.vm

如果您使用的是Ruby provisioner,那么在调用
vagrant up
时传递环境变量似乎很简单:

VAR=123 vagrant up
在文件中:

ENV['VAR']
config.vm.provision "shell", path: "provisionscript.sh", env: {"MYVAR" => "value"}
如何使用
:shell
provisioner执行此操作?简单地这样做似乎不起作用:

$VAR

这并不理想,但我现在要做的是:

config.vm.provision "shell" do |s|
    s.inline = "VAR1 is $1 and VAR2 is $2"
    s.args   = "#{ENV['VAR1']} #{ENV['VAR2']}"
end

万一有人最终想知道如何在配置脚本的环境中设置变量,这对我来说很有用

config.vm.provision :shell, :inline => <<-SH
  export GRAPHITE_HOST=192.168.33.10
  /vagrant/install_app_with_monitoring.sh
SH

config.vm.provision:shell,:inline=>我为基于CentOS的资源调配提供了此解决方案:将所有必需的环境变量放置在
/etc/profile.d/vagrant.sh
文件中,然后在任何资源调配脚本中访问它

简言之:

  $before_script = <<SCRIPT
  echo # vagrant profile script > /etc/profile.d/vagrant.sh
  echo export ENV_VAR1=foo.com/bar >> /etc/profile.d/vagrant.sh
  echo export ENV_VAR2=bar.com/foo >> /etc/profile.d/vagrant.sh
  chmod +x /etc/profile.d/vagrant.sh
SCRIPT

  $after_script = <<SCRIPT
    rm -rf /etc/profile.d/vagrant.sh
SCRIPT

  config.vm.provision "shell", inline: $before_script
  config.vm.provision "shell", path: "build.sh"
  config.vm.provision "shell", inline: $after_script
$before\u script=>/etc/profile.d/vagrant.sh
echo export ENV_VAR2=bar.com/foo>>/etc/profile.d/vagrant.sh
chmod+x/etc/profile.d/vagrant.sh
剧本
$after_script=这对我很有效

VAGRANTFILE_API_VERSION = "2"

kettle_dir = ENV['KETTLE_DIR']
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
   config.vm.synced_folder kettle_dir, "/pentaho"
   config.vm.box = "ubuntu/trusty64"
end

这是我的工作原理

我从使用流浪木偶供应器的方式转变为只使用外壳供应器。我这样做主要是因为我不想以root身份运行,shell提供程序给您:privileged=>false

我的老办法:

config.vm.provision :puppet do |puppet|
  puppet.module_path = ENV.fetch('MODULES_PATH', 'modules')
  puppet.manifests_path = ENV.fetch('MANIFESTS_PATH', 'manifests')
  puppet.manifest_file  = ENV.fetch('MANIFEST_FILE', 'site.pp')
  puppet.options = "--debug"
end
我的新方式:

config.vm.provision :shell, :privileged => false do |shell|
  shell.inline = "puppet apply --debug --modulepath '/vagrant/#{ENV.fetch('MODULES_PATH', 'modules')}' --detailed-exitcodes '/vagrant/#{ENV.fetch('MANIFESTS_PATH', 'manifests')}/#{ENV.fetch('MANIFEST_FILE', 'site.pp')}'"
end
您可以在内联脚本中使用
#{ENV['VAR']}
,例如:

config.vm.provision "shell", inline: <<-END
  ...
  # Install my dotfiles are there.  If you're in a hurry you can do
  # SKIP_DOTFILES=1 vagrant up
  if ! [ -d /home/vagrant/dotfiles ] && [ -z '#{ENV['SKIP_DOTFILES']}']; then
    if ! [ -x /usr/bin/git ]; then
      DEBIAN_FRONTEND=noninteractive apt-get install -y git
    fi
    su - vagrant -c 'git clone https://github.com/mgedmin/dotfiles'
    su - vagrant -c 'dotfiles/install.sh'
  fi
  ...
  END

config.vm.provision“shell”,内联:您只需在
vagrant文件中使用
inline
指定
shell

config.vm.provision "shell", inline: %Q(/usr/bin/env FOO=1 BAR=1 bash /path/to/script.sh)
或者从YAML文件中加载一些额外变量:

require 'yaml'
dir = File.dirname(File.expand_path(__FILE__))
vconfig = YAML::load_file("#{dir}/config.yml")
config.vm.provision "shell", inline: %Q(/usr/bin/env FOO=#{vconfig['foo']} bash /path/to/script.sh)
或者,您可以从命令行实现一些可选参数,例如:

# Parse optional arguments.
opts = GetoptLong.new(
  [ '--foo',  GetoptLong::OPTIONAL_ARGUMENT ], # With optional parameter.
  [ '--bar',  GetoptLong::OPTIONAL_ARGUMENT ], # With optional parameter.files.
)
opts.each do |opt, arg|
  case opt
    when '--foo'
      foo==arg
    when '--bar'
      bar=arg
  end
end
然后使用:
opt['--foo']

另请参见:

插件正是这样做的。使用它,您可以将环境变量添加到本地目录中的
.env
文件中,该文件将加载到
Vagrant
文件中。我建议在你的
.gitignore
中保留
.env
,这样你的隐私就得到了保障

你可以从这里的其他答案中忘记那些丑陋的黑客。只需对shell provisioner()使用
env
选项即可

在您的文件中这样使用它:

ENV['VAR']
config.vm.provision "shell", path: "provisionscript.sh", env: {"MYVAR" => "value"}
这将仅为设置脚本设置环境。如果您需要为VM中的所有进程设置一个持久性环境变量,那么这就超出了Vagrant provisioning的范围,请看这里:.

用于子孙后代(在我再次搜索它的情况下也可以这样做)。。。可以通过以下方式传递键值对:

然后在脚本中引用它们:

export AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY}
export AWS_SECRET_ACCESS_KEY=${AWS_SECRET_KEY}
奖励功能:

Vagrant将处理环境变量值的引用,但 钥匙保持不变


在ubutnu框中,我在bootstrap.sh中简单地执行了以下操作:

echo "DBHOST=localhost" >> /etc/environment
echo "DBNAME=foo" >> /etc/environment
echo "DBUSER=root" >> /etc/environment
echo "DBPASSWD=root" >> /etc/environment

这些答案中的大多数似乎已经过时了。对于Vagrant 2.1.1,这对我很有用:

  VAGRANTFILE_API_VERSION = "2" //...

  machine.vm.provision "shell", 
    env: {
      "ELASTIC_XMS" => servers["elastic"]["memory_xms"], 
      "ELASTIC_XMX" => servers["elastic"]["memory_xmx"]
    }, 
    inline: "sed -i -e \"s/-Xms.*/$ELASTIC_XMS/g\" /etc/elasticsearch/jvm.options"

您还可以将
s.inline
替换为
s.path
,并使用与
:path=>“
传递的相同脚本。(我的provisioner有数百行,因此不适合内联。)或者,使用带有
:args=>“
参数的ruby方法。是否应该在
s.args
中使用逗号?能否详细说明这是正确答案的原因?这在Vagrant文件中使用了一个环境变量,当然,我注意到@Bob基本上在我发布我的答案之后就提供了相同的答案(以新的方式位)。啊!还可以看到@gertvdijk发布的答案(发布时我没有刷新页面)在Linux下对我有效(对于基于Ubuntu的VM)。令人惊叹的!不过,现在有了。我看过,但由于缺少示例,我跳过了它。一位同事指出它是有效的。@NikosAlexandris:请看我的答案:)在Vagrant 1.8.5中,
env
参数似乎只在使用
path
脚本时有效,而不是
inline
脚本。@spyle我正在运行Vagrant 1.8.5(在Mac OS X 10.11.6上使用VirtualBox 5.1.2)和
env
inline
一起工作。嗯。。。我是不是遗漏了什么?这对我不起作用:
config.vm.provision:shell,path:“bootstrap.sh”,env:{“MYSQL\u DB\u USERNAME”=>“django”,“MYSQL\u DB\u PASSWORD”=>“supersecretpasswordwasrecated”}
另一端的
os.environ['MYSQL\u DB\u USERNAME']
给出了一个关键错误:(@Tadhg仔细检查您的Vagrant版本。如果它不起作用,可能会问一个新问题?这可能是一个不相关的问题(例如,Vagrant文件版本或环境未保留在您的工具链中).Version很好。你是对的,看看文档,似乎这个配置只应该在配置时工作,所以我问了一个新问题,但为什么不在
安装带有监视的应用程序?sh
?主要是为了让知识保持在同一个位置。你可以在这里看到一个例子,将var保存在它的文件中很容易确保
私有网络
石墨主机
之间的奇偶性。甚至可以更进一步,使用
导出石墨主机=#{ip}
引用单个常见ruby变量。插件在2015年消亡,这不是最新的。