使用Vagrant管理开发和生产环境?

使用Vagrant管理开发和生产环境?,vagrant,puppet,Vagrant,Puppet,人们如何使用vagrant(理想情况下是来自同一个vagrant文件)为dev/prod环境处理简单自动化(使用puppet) 我试图解决的用例 我很想用“流浪者”来加速生产机器,如果它没有被创造出来的话 如果在我的开发环境的puppet文件中对nginx或apacheconf进行了调整,我会很乐意在生产中使用vagrant重新加载它们 问题 当你给vagrant打电话给AWS或Digital Ocean这样的提供商时,它将成为活动提供商,你无法切换。您将得到以下错误: 发现具有其他提供程序

人们如何使用vagrant(理想情况下是来自同一个vagrant文件)为dev/prod环境处理简单自动化(使用puppet)

我试图解决的用例

  • 我很想用“流浪者”来加速生产机器,如果它没有被创造出来的话
  • 如果在我的开发环境的puppet文件中对nginx或apacheconf进行了调整,我会很乐意在生产中使用vagrant重新加载它们
问题

当你给vagrant打电话给AWS或Digital Ocean这样的提供商时,它将成为活动提供商,你无法切换。您将得到以下错误:

发现具有其他提供程序的活动计算机。流浪汉 目前允许每台机器只使用一个 一次一个提供者。将来的版本将删除此限制。 在此之前,请销毁现有的机器,以更新新的 提供者

这似乎是摧毁它的答案,但我只需要切换。我不想破坏

我很想说

vagrant up prod

然后一个简单的流浪者会回到默认机器

这种语法与工作原理类似,但我不想在调用vagrant up(这是默认行为)时启动开发和生产环境

我应该把packer作为工作流程的一部分吗?我在2013年puppetconf上观看了Mitchell关于多供应商的演讲

我还没有找到解决我问题的办法


2013年9月27日更新

如果有人反对这个想法,这篇文章澄清了我的许多问题。
这不是一个理想的解决方案,但是使用git分支怎么样?我的想法是,它在概念上可能与使用heroku类似,在heroku中,您可能有主版本、暂存版本和生产版本(因为它们通常是不同的远程版本)

在本例中,您从prod分支开始,对Vagrant文件进行小的编辑,以稍微不同的方式命名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

至于解决方法,您应该定义
config.vm.define
(如建议的),以便支持多个提供程序

请查找发布的以下配置作为示例:

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
或者发布以下示例:


下面是一种通过命令行动态依赖指定的
--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


另请参见:

我想到的处理此场景的方法是管理2个distincts
.vagrant
文件夹

注意:大多数其他答案涉及设置多提供程序,假设您将在不同的提供程序上运行dev和prod,在大多数情况下,这可能是正确的,但在某些情况下,您肯定有相同的dev和prod提供程序。假设您使用的是aws,并且希望将dev和prod用作ec2实例,那么它将是相同的提供程序

假设您希望管理
dev
prod
实例,可能使用不同的提供程序(但也可能在同一个提供程序上),那么您将执行以下操作:

  • 使用普通的
    vagrant-up--provider设置
    dev
    实例。 这将创建一个可以管理的dev虚拟机

  • 备份在项目目录中创建的
    .vagrant
    文件夹,并将其重命名为
    .vagrant.dev

  • 使用您选择的提供商设置
    prod
    实例
    vagrant up--provider
    。现在,这将创建prod VM

  • 备份在项目目录中新建的
    .vagrant
    文件夹,并将其重命名为
    .vagrant.prod

现在,根据您想在dev还是prod上工作,您将
.vagrant.dev
.vagrant.prod
目录重命名为
。vagrant
,vagrant将操作正确的VM


我没有想出一个脚本,因为大部分时间我都在使用dev,很少时候我需要切换到其他提供商。但我认为从CLI读取参数并使重命名更具动态性不会太难。

分支的问题不是我需要更改的文件,而是隐藏的.vagrant文件夹。一旦提供商启动,它就会接管该文件夹。现在,我只是查看一个单独的克隆,然后在digital ocean提供商上启动生产机器。这有点恶心,但很管用。
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