人们如何处理具有流浪者的dev / prod环境的简单自动化(使用puppet)(理想情况下来自同一个vagrantfile)?
用例我正在尝试解决
问题
当您使用AWS或Digital Ocean等提供商调用vagrant时,它将成为活动提供程序,您无法切换。你收到这个错误:
找到了与其他提供商有关的活动计算机。流浪汉 目前只允许每台机器使用一台机器 提供者一次。未来版本将删除此限制。 在那之前,请用新的方法销毁现有的机器 提供商。
似乎要解决这个问题,但我只需要切换。我不想破坏。
我希望能说出来
vagrant up prod
或
vagrant reload prod
然后一个简单的流浪汉就会回到默认机器上。
这种语法类似于multiple machines的工作原理,但是当我只是调用vagrant up(这是默认行为)时,我不想启动开发和生产环境。
我应该将打包机视为工作流程的一部分吗?我在2013年的puppetconf上观看了Mitchell关于多供应商的谈话http://puppetlabs.com/presentations/multi-provider-vagrant-aws-vmware-and-more
我仍然没有找到解决问题的方法。
更新9/27/13
如果其他人正在反对这个想法,这篇文章清理了我的很多问题。 http://pretengineer.com/post/packer-vagrant-infra
答案 0 :(得分:2)
至于变通方法,您应该定义config.vm.define
(建议here),以支持多个提供商。
请查看以@kzap发布的以下配置为例:
Vagrant.configure("2") do |config|
# Store the current version of Vagrant for use in conditionals when dealing
# with possible backward compatible issues.
vagrant_version = Vagrant::VERSION.sub(/^v/, '')
# Configuration options for the VirtualBox provider.
def configure_vbox_provider(config, name, ip, memory = 2048, cpus = 1)
config.vm.provider :virtualbox do |v, override|
# override box url
override.vm.box = "ubuntu/trusty64"
# configure host-only network
override.vm.hostname = "#{name}.dev"
override.vm.network :private_network, id: "vvv_primary", ip: ip
v.customize ["modifyvm", :id,
"--memory", memory,
"--cpus", cpus,
"--name", name,
"--natdnshostresolver1", "on",
"--natdnsproxy1", "on"
]
end
end
default_provider = "virtualbox"
supported_providers = %w(virtualbox rackspace aws managed)
active_provider = ENV['VAGRANT_ACTIVE_PROVIDER'] # it'd be better to get this from the CLI --provider option
supported_providers.each do |provider|
next unless (active_provider.nil? && provider == default_provider) || active_provider == provider
#
# VM per provider
#
config.vm.define :"sample-#{provider}" do | sample_web_config |
case provider
when "virtualbox"
configure_vbox_provider(sample_web_config, "examine-web", "192.168.50.1")
when "aws"
configure_aws_provider(sample_web_config)
when "managed"
configure_managed_provider(sample_web_config, "1.2.3.4")
when "rackspace"
configure_rackspace_provider(sample_web_config)
end
end
end
或以下示例发布了at gist by @maxlinc:
# -*- mode: ruby -*-
# vi: set ft=ruby :
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "dummy"
config.vm.provider :rackspace do |rs|
rs.username = ENV['RAX_USERNAME']
rs.api_key = ENV['RAX_API_KEY']
rs.rackspace_region = :ord
end
supported_providers = %w(virtualbox rackspace)
active_provider = ENV['VAGRANT_ACTIVE_PROVIDER'] # it'd be better to get this from the CLI --provider option
supported_providers.each do |provider|
next unless active_provider.nil? || active_provider == provider
config.vm.define "exact_name_#{provider}" do |box|
box.vm.provider :rackspace do |rs|
rs.flavor = '1 GB Performance'
rs.image = 'Ubuntu 14.04 LTS (Trusty Tahr) (PVHVM)'
end
end
config.vm.define "regex_#{provider}" do |box|
box.vm.provider :rackspace do |rs|
rs.flavor = /1\s+GB\s+Performance/
rs.image = /Ubuntu.*Trusty Tahr.*(PVHVM)/
end
end
config.vm.define "id_#{provider}" do |box|
box.vm.provider :rackspace do |rs|
rs.flavor = 'performance1-1'
rs.image = 'bb02b1a3-bc77-4d17-ab5b-421d89850fca'
end
end
config.vm.define "unlisted_#{provider}" do |box|
box.vm.provider :rackspace do |rs|
rs.flavor = 'performance1-1'
rs.image = '547a46bd-d913-4bf7-ac35-2f24f25f1b7a'
end
end
end
end
答案 1 :(得分:1)
不是理想的解决方案,但使用git分支怎么样?我的想法是它可能在概念上类似于使用heroku,在那里你可能有一个master,staging和production版本(因为它们通常是不同的遥控器)。
在这种情况下,您可以通过对Vagrantfile的小编辑来启动prod分支,以便将VM命名为略有不同。然后,您应该能够将dev中的所有更改与prod分支合并。所以你的工作流程看起来像:
$ git checkout prod
$ vagrant up
$ git checkout master
... make changes to puppet ...
$ git checkout prod
$ git merge master
$ vagrant reload
$ git checkout master
您可以编写脚本并对其进行别名,以便最终得到
$ start_production
$ reload_production
答案 2 :(得分:0)
这是一种动态changing the 'default' machine name的简单方法,具体取决于命令行中指定的--provider
,因此它们不会在不同的提供者之间发生冲突:
require 'getoptlong'
opts = GetoptLong.new(
[ '--provider', GetoptLong::OPTIONAL_ARGUMENT ],
[ '--vm-name', GetoptLong::OPTIONAL_ARGUMENT ]
)
provider=ENV['PROVIDER'] || 'virtualbox'
vm_name=ENV['VM_NAME'] || 'default'
opts.each do |opt, arg|
case opt
when '--provider'
provider=arg
when '--vm-name'
vm_name=arg
end
end
Vagrant.configure(2) do |config|
# HERE you are dynamically changing the machine name to prevent conflict.
config.vm.define "mt-#{provider}-#{vm_name}"
# Below sections are just examples, not relevant.
config.vm.provider "virtualbox" do |vm|
vm.name = "test.local"
vm.network "private_network", ip: "192.168.22.22"
vm.customize ['modifyvm', :id, '--natdnshostresolver1', 'on']
config.vm.box = "ubuntu/wily64"
end
config.vm.provider :aws do |aws, override|
aws.aws_profile = "testing"
aws.instance_type = "m3.medium"
aws.ami = "ami-7747d01e"
config.vm.box = "testing"
end
end
使用示例:
VM_NAME=dev PROVIDER=virtualbox vagrant up --provider=virtualbox
VM_NAME=uat PROVIDER=aws vagrant up --provider=aws
VM_NAME=test PROVIDER=aws vagrant up --provider=aws
VM_NAME=prod PROVIDER=aws vagrant up --provider=aws
VM_NAME=uat PROVIDER=aws vagrant destroy -f
VM_NAME=test PROVIDER=aws vagrant status
答案 3 :(得分:0)
我想出了解决这个问题的方法是管理2个.vagrant
文件夹。
注意:大多数其他答案都涉及设置多提供程序,假设您将在不同的提供程序上运行dev和prod,在大多数情况下这可能是真的,但您肯定会遇到这样的情况,即您拥有相同的dev和prod提供程序。让我们说你正在使用aws并且你想使用dev和prod作为ec2实例它将是同一个提供者。
假设您要管理dev
和prod
个实例,可能使用不同的提供商(但也可能在同一个提供商处),所以您可以这样做:
使用正常dev
设置vagrant up --provider <dev_provider>
个实例。
这将创建一个可以管理的开发虚拟机
备份项目目录中创建的.vagrant
文件夹,并将其重命名为.vagrant.dev
与您选择的提供商prod
设置vagrant up --provider <prod_provider>
个实例。现在这将创建您的prod VM
备份项目目录中创建的新.vagrant
文件夹,并将其重命名为.vagrant.prod
现在,根据您是否要使用dev或prod,您将.vagrant.dev
或.vagrant.prod
目录重命名为.vagrant
,并且vagrant将运行正确的VM。< / p>
我没有提出一个脚本,主要是在大部分时间我使用dev,很少有时候我需要切换到其他提供程序。但是我不认为从CLI读取参数并使重命名更加动态是太难了。