是否可以从另一个 Vagrantfile 中加载 Vagrantfile 配置?

jam*_*ant 7 vagrant vagrantfile

Vagrant Multi-Machine 功能看起来很酷,但是困扰我的一件事(或不是很明显)是似乎没有一种在“父”Vagrantfile 和“子”之间共享配置选项的好方法流浪文件。有没有办法在父级和它的子级之间有效且可维护地共享配置选项?一个例子可能会更清楚地说明这一点。

假设我有一个由 3 个应用程序/服务组成的平台:API、Web 和 Worker。

让我们假设以下目录结构:

/some_platform
  /api
    # app code...
    Vagrantfile
  /web
    # app code...
    Vagrantfile
  /worker
    # app code...
    Vagrantfile
  Vagrantfile
Run Code Online (Sandbox Code Playgroud)

让我们说/some_platform/api/Vagrantfile看起来像:

Vagrant.configure("2") do |config|
  config.vm.box = "debian/jessie64"
end
Run Code Online (Sandbox Code Playgroud)

大概 web 和 worker Vagrantfiles 看起来很相似。

现在,使用多机的奇迹,我依靠 Vagrant 协调这些虚拟机,/some_platform/Vagrantfile看起来像:

Vagrant.configure("2") do |config|
  config.vm.define "web" do |api|
    api.vm.box = "debian/jessie64"
  end

  config.vm.define "web" do |web|
    web.vm.box = "debian/jessie64"
  end

  config.vm.define "web" do |worker|
    worker.vm.box = "debian/jessie64"
  end
end
Run Code Online (Sandbox Code Playgroud)

我意识到这个例子是人为的,但是很容易看出,一旦您获得越来越复杂的配置声明,在两个地方复制该配置是令人讨厌和危险的。

您可能想知道“为什么每个项目都有自己的 Vagrantfile?” 这样做为应该如何设置应用程序运行的服务器提供了单一的事实来源。我意识到你可以使用一些配置器(我会使用它们),但你仍然需要声明一些其他的东西,我想保持 DRY,这样我就可以通过 Multi-机器,或者我可以在单个应用程序上工作并更改它的 VM/服务器设置。

我真正喜欢的是一种将其他 Vagrantfile 合并到“父”文件中的方法。

那可能吗?还是我疯狂尝试?关于如何实现这一目标的任何聪明想法?我已经用一些 yaml 文件和 PORO 来解决这个问题,但没有一个黑客感到非常令人满意。

Mir*_*kiy 8

好消息!
实际上,您可以在Vagrantfile 中应用DRY 原则

首先:创建一个文件/some_platform/DRY_vagrant/Vagrantfile.sensible来保存一些合理的默认值:

Vagrant.configure("2") do |config|
  # With the setting below, any vagrantfile VM without a 'config.vm.box' will 
  # automatically inherit "debian/jessie64"
  config.vm.box = "debian/jessie64"
end
Run Code Online (Sandbox Code Playgroud)

第二:/some_platform/DRY_vagrant/Vagrantfile.worker为“工人”虚拟机创建一个文件:

Vagrant.configure("2") do |config|
  config.vm.define "worker" do |worker|
    # This 'worker' VM will not inherit "debian/jessie64". 
    # Instead, this VM will explicitly use "debian/stretch64"
    worker.vm.box = "debian/stretch64"
  end
end
Run Code Online (Sandbox Code Playgroud)

最后:创建一个文件/some_platform/Vagrantfile将它们联系在一起:

# Load Sensible Defaults
sensible_defaults_vagrantfile = '/some_platform/DRY_vagrant/Vagrantfile.sensible'
load sensible_defaults_vagrantfile if File.exists?(sensible_defaults_vagrantfile)

# Define the 'api' VM within the main Vagrantfile
Vagrant.configure("2") do |config|
  config.vm.define "api" do |api|
    # This 'api' VM will automatically inherit the "debian/jessie64" which we
    # configured in Vagrantfile.sensible

    # Make customizations to the 'api' VM
    api.vm.hostname = "vm-debian-jessie64-api"
  end
end

# Load the 'worker' VM
worker_vm_vagrantfile = '/some_platform/DRY_vagrant/Vagrantfile.worker'
load worker_vm_vagrantfile if File.exists?(worker_vm_vagrantfile)
Run Code Online (Sandbox Code Playgroud)

这种方法几乎可以用于任何其他 vagrantfile 配置选项。它不仅限于“config.vm.box”设置。

希望这有帮助!


Fré*_*nri 3

有两件事你可以看(可能更多,但我想到的是这两件事)

  1. 看看如何使用 Ruby 模板 Vagrantfile?这是一个如何读取另一个文件内容的示例,Vagrantfile 只是一个 ruby​​ 脚本,因此您可以使用 ruby​​ 的所有功能。

  2. vagrant 有一个加载和合并的概念,请参阅文档,因此如果您想在运行 vagrant 命令执行某些操作,您可以在您的~/.vagrant.d/文件夹下创建一个 Vagrantfile 并且它将始终运行

一个缺点(或者至少要注意):Vagrantfile 是一个 ruby​​ 脚本,每次(每次)执行 vagrant 命令时都会对其进行评估(up、status、halt ....)