31

Can anyone guide me to how do I include variables in my VagrantFile? I am trying to inject configs into the Vagrantfile from an external file so that I can distribute the config to my colleagues without having them to hardcode configs directly on the Vagrantfile.

I had thought that since it was Ruby based I could just include a Ruby file but I get an error Message: unintialized constant MyVars

My VagrantFile simplified

# -*- mode: ruby -*-
# vi: set ft=ruby :
require 'vagrant.rb'
include MyVars

Vagrant.configure("2") do |config|

  # Web
  config.vm.define :joe do |joe|
    joe.vm.box = "precise64_4.2.12"
    joe.vm.hostname = WEBVMNAME
    joe.vm.network :private_network, ip: "192.168.140.141"

    # Port Forwarding
    joe.vm.network :forwarded_port, guest: 22, host: 2201
    joe.vm.network :forwarded_port, guest: 80, host: 8080

    # Bootstrap Bash Script
    joe.vm.provision :shell, :path => "bootstrap.sh"
  end

end

And vagrant.rb contains

module MyVars

    WEBVMNAME = "rex"

end

Do note that I am also a newbie at Ruby so I am not sure as well if its just the syntax I got wrong?

Edit: Updated code I am using

MechaStorm
  • 1,432
  • 3
  • 17
  • 29
  • 1
    Similar: [Override Vagrant configuration settings locally (per-dev)](http://stackoverflow.com/q/13065576/55075) – kenorb Jan 07 '16 at 15:51
  • in addition to below answers: if you were to use your variable `WEBVMNAME` within your bash provision script, you could follow the approach pointed out [here](https://stackoverflow.com/questions/19648088/pass-environment-variables-to-vagrant-shell-provisioner) and use `joe.vm.provision "shell", path: "bootstrap.sh", env: {"HOSTNAME" => "#{WEBVMNAME}"}` – Wolfson Apr 27 '20 at 13:43

4 Answers4

65

I use the approach of https://puphpet.com, I create a file config.yaml in the same directory of the Vagrantfile and...

In my Vagrantfile:

# encoding: utf-8
# -*- mode: ruby -*-
# vi: set ft=ruby :

require 'yaml'

current_dir    = File.dirname(File.expand_path(__FILE__))
configs        = YAML.load_file("#{current_dir}/config.yaml")
vagrant_config = configs['configs'][configs['configs']['use']]

Vagrant.configure('2') do |config|

    config.vm.network 'public_network', ip: vagrant_config['public_ip']
    ...

In my config.yaml:

---
configs:
    use: 'home'
    office:
        public_ip: '192.168.2.117'
        <more variables>...
    home:
        public_ip: '192.168.1.117'
        <more variables>...
geedelur
  • 1,159
  • 10
  • 11
7

Use require_relative:

require_relative 'vagrant.rb'
include MyVars
# ...
strager
  • 88,763
  • 26
  • 134
  • 176
5

Try changing your require to this:

require './vagrant'
Matt Cooper
  • 9,962
  • 2
  • 31
  • 26
1

I created a library directory:

require './lib/cfpEnvironment.rb'
include CFPEnvironment

And then did the scripting of what I need to be dynamic, defining the variables in the module created...

CFPPorts.select{ |key, value| value.numeric? }.each { |key, value|
   config.vm.network :forwarded_port, guest: value, host: value
}

Thanks to @Matt and @strager for their answers above!

Marcello DeSales
  • 21,361
  • 14
  • 77
  • 80