Vagrant Multi-Machine 功能看起来很酷,但是困扰我的一件事(或者不是立即显而易见)是,似乎没有一种好方法在“父”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
想必网络和工作 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
我意识到这个例子是人为的,但是很容易看出一旦你得到越来越复杂的配置声明,在两个地方重复该配置是很烦人和危险的。
您可能想知道“为什么每个项目都有自己的 Vagrantfile?”这样做为应如何设置应用程序运行的服务器提供了单一事实来源。我意识到您可以使用一些配置程序(并且我将使用它们),但是您仍然必须声明除此之外的一些其他内容,并且我想保持干燥,以便我可以通过 Multi- 启动一组应用程序机器,或者我可以在单个应用程序上工作并更改其虚拟机/服务器设置。
我真正喜欢的是一种将其他 Vagrantfiles 合并到“父”文件中的方法。
这可能吗?或者我疯狂地尝试?关于如何实现这一目标有什么聪明的想法吗?我已经用一些 yaml 文件和 PORO 来解决这个问题,但没有一个 hack 让人感到非常满意。
事实上,您可以在 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
第二: 为“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”设置。
有两件事你可以看(可能更多,但我想到的是这两件事)
查看如何使用 Ruby 构建 Vagrantfile 模板?这是一个如何读取另一个文件内容的示例,Vagrantfile 只是一个 ruby 脚本,因此您可以使用 ruby 的所有功能。
vagrant 有一个加载和合并的概念,请参阅 from doc 所以如果你想要做某事随时你运行一个 vagrant 命令,你可以在你的
~/.vagrant.d/
文件夹下创建一个 Vagrantfile 并且它将始终运行 一个缺点(或者至少要注意):Vagrantfile 是一个 ruby 脚本,它会在每次(每次)执行 vagrant 命令时进行评估(up、status、halt ....)