【问题标题】:Is it possible to load a Vagrantfile config from within another Vagrantfile?是否可以从另一个 Vagrantfile 中加载 Vagrantfile 配置?
【发布时间】:2017-09-28 03:13:08
【问题描述】:

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

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

假设目录结构如下:

/some_platform
  /api
    # app code...
    Vagrantfile
  /web
    # app code...
    Vagrantfile
  /worker
    # app code...
    Vagrantfile
  Vagrantfile

假设/some_platform/api/Vagrantfile 看起来像:

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

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

现在,使用 Multi-Machine 的奇迹,我依靠 Vagrant 协调这些 VM,/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

我知道这个例子是人为的,但是很容易看出,一旦你得到越来越复杂的配置声明,在两个地方重复该配置是很烦人和危险的。

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

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

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

【问题讨论】:

    标签: vagrant vagrantfile


    【解决方案1】:

    好消息!
    事实上,您可以在 Vagrantfile 中应用 DRY principles

    首先:创建一个文件/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
    

    第二步:为'worker'虚拟机创建一个文件/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
    

    最后:创建一个文件/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)
    

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

    希望这有帮助!

    【讨论】:

    • 我能问一下如果/some_platform/Vagrantfile 有一个变量/some_platform/DRY_vagrant/Vagrantfile.sensible 需要你如何将它传递给后者会发生什么?使用全局变量...?
    • @DaveMackey 根据我的经验,我在加载Vagrantfile.sensible 之前在Vagrantfile 中定义的所有变量都可以在Vagrantfile.sensible 中访问
    • 感谢@Miron V,我将不得不进一步研究......这似乎对我不起作用。
    【解决方案2】:

    您可以查看两件事(可能更多,但我想到了这两件事)

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

    2. vagrant 有加载和合并的概念,请参阅from doc,所以如果你想随时运行 vagrant 命令,你可以在 ~/.vagrant.d/ 下创建一个 Vagrantfile文件夹,它将始终运行

    一个缺点(或至少要注意):Vagrantfile 是一个 ruby​​ 脚本,每个(并且每次)执行一个 vagrant 命令(up、status、halt ... .)

    【讨论】:

      猜你喜欢
      • 2018-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多