具有共享厨师设置但角色不同的多虚拟机 Vagrantfile

Multi-VM Vagrantfile with shared chef settings but different roles

我正在尝试使用单个 Vagrantfile 来定义具有不同 Chef 角色的 2 个 VM,并且我想在两个 vms 之间共享某些 Chef 配置,但要分别指定运行列表、环境和属性。有没有一种方法可以在不复制常用设置的情况下做到这一点?

例如,如果我做了类似的事情:

# Development system
config.vm.define "dev", primary: true do |dev|
  dev.vm.hostname = "server1"
  dev.vm.provider "virtualbox" do |v|
    v.name = "server1"
  end

  dev.vm.provision "chef_client" do |chef|
    chef.run_list = [ "role[dev-system]" ]
    chef.environment = "development"
    chef.json = {
      "key" => "value1"
    }
  end
end

# Production system
config.vm.define "pro", primary: true do |pro|
  pro.vm.hostname = "server2"
  pro.vm.provider "virtualbox" do |v|
    v.name = "server2"
  end

  pro.vm.provision "chef_client" do |chef|
    chef.run_list = [ "role[pro-system]" ]
    chef.environment = "production"
    chef.json = {
      "key" => "value2"
    }
  end
end

config.vm.provision "chef_client" do |chef|
  chef.chef_server_url = "https://example.com/organizations/tsrd"
  chef.validation_key_path = "~/my-validator.pem"
  chef.validation_client_name = "my-validator"
  chef.delete_node = true
  chef.delete_client = true
  # ... PLUS OTHER COMMON CONFIGURATIONS...
end

它会为每个 vm 应用单独的 chef 部分以及共享部分,还是只是用最后一个部分覆盖第一个部分?如果没有,是否有更简单的方法来做到这一点?也许是在每个 vm 定义块中调用的包装函数?

为此我采取了另一种方式。

我在 vagrant 文件中将我的虚拟机定义为散列,如下所示:

machinesBases = {
  'srv0643' => { 
    'ip_address' => '172.30.0.140',
    'env' => 'Z1', 
    'alias' => 'z1frnessus01',
    'roles' => ['nessus'],
    'additionnal_recipes' => ['java']
  },
  'srv0683' => {
    'ip_address' => '172.30.0.51',
    'env' => 'P1', 
    'alias' => 'p1frkegin01',
    'roles' => [],
    'additionnal_recipes' => ['kegin_cookbook']
  } 
}

然后我循环遍历它,使用哈希值

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  machinesBases.each do |hostname,properties|
    config.vm.define hostname do |box|
      box.vm.hostname = "#{hostname}.my.domain.org"

      box.vm.network :private_network, ip: properties["ip_address"]

      box.vm.provision :chef_client do |chef|
        chef.chef_server_url = CHEF_CHEF_SERVER_URL
        chef.validation_key_path = CHEF_VALIDATION_KEY_PATH
        chef.environment = properties["env"]
         chef.add_recipe "base-linux"
        properties['roles'].each do |role|
          chef.add_role role
        end
        properties['additionnal_recipes'].each do |recipe|
          chef.add_recipe recipe
        end
      end
    end
  end unless machinesBases.length == 0
end

我删除了 vagrant 文件的一些部分(例如常量定义)以避免在这里太长,但我想你明白了。

这可能不是最好的方法,但我发现 extend/update。

我相信您可以将两台机器添加到一个数组中,然后遍历该数组并在循环中添加公共元素。

a = config.vm.define "dev", primary: true do |dev|
...
end

b = config.vm.define "pro", primary: true do |pro|
...
end

[a, b].each do |next_vm|
  next_vm.provision "chef_client" do |chef|
    chef.chef_server_url = "https://example.com/organizations/tsrd"
    chef.validation_key_path = "~/my-validator.pem"
    chef.validation_client_name = "my-validator"
    chef.delete_node = true
    chef.delete_client = true
    # ... PLUS OTHER COMMON CONFIGURATIONS...
  end
end