Использование Vagrant для управления средами разработки и производства?

Как люди обрабатывают простую автоматизацию (с марионеткой) для сред dev/prod с бродягой (в идеале от одного и того же бродяга)?

Использовать случай, который я пытаюсь решить

  • Мне бы хотелось развернуть машину производства с бродягой, если она не создана.
  • Мне бы хотелось перезагрузить nginx или apache confs на производстве с бродягой, если они были изменены в файлах марионеток для моей среды dev.

Проблема

Когда вы вызываете бродягу с таким провайдером, как AWS или Digital Ocean, он становится активным провайдером, и вы не можете переключиться. Вы получите эту ошибку:

Активная машина была найдена с другим поставщиком. бродяга в настоящее время позволяет каждой машине воспитывать только одну провайдера за раз. Будущая версия устранит это ограничение. До тех пор, пожалуйста, уничтожьте существующую машину до новой провайдера.

Кажется, ответ он уничтожит, но мне просто нужно переключиться. Я не хочу уничтожать.

Я хотел бы сказать

vagrant up prod

или

vagrant reload prod

а затем простой бродячий вверх вернется к машине по умолчанию.

Этот синтаксис аналогичен тому, как работают несколько машин, но я не хочу разворачивать dev и производственную среду, когда я просто call vagrant up (это поведение по умолчанию).

Должен ли я рассматривать упаковщик как часть рабочего процесса? Я смотрел весь разговор на puppetconf 2013 о Митчелле, говорящий на Multi-Provider http://puppetlabs.com/presentations/multi-provider-vagrant-aws-vmware-and-more

Я все еще не вижу решения для своей проблемы.


ОБНОВЛЕНИЕ 9/27/13

В случае, если кто-то другой борется с этой идеей, эта статья прояснила множество вопросов, которые у меня были. http://pretengineer.com/post/packer-vagrant-infra/

Ответы

Ответ 1

Что касается обходного пути, вы должны определить config.vm.define (как предложено здесь), чтобы поддерживать несколько поставщиков.

Пожалуйста, найдите следующую конфигурацию, отправленную @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

Или в следующем примере размещен в строке @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

Ответ 2

Не идеальное решение, но как насчет использования ветвей git? Мое мышление состоит в том, что он может быть концептуально похож на использование герою, где у вас могут быть мастера, постановки и производственные версии (поскольку они обычно являются разными пультами).

В этом случае вы начинаете с ветки prod с небольшим изменением в Vagrantfile, чтобы назвать VM немного по-другому. Затем вы сможете объединить все изменения из dev с дочерней веткой по мере их возникновения. Таким образом, ваш рабочий процесс будет выглядеть следующим образом:

$ git checkout prod
$ vagrant up
$ git checkout master
...  make changes to puppet ...
$ git checkout prod
$ git merge master
$ vagrant reload
$ git checkout master

Вы могли бы script и псевдоним, чтобы вы закончили с

$ start_production
$ reload_production

Ответ 3

Вот простой способ динамического изменить имя машины по умолчанию в зависимости от указанного --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

См. также: Несколько провайдеров в одном бродяжном файле?

Ответ 4

то, что я придумал для работы с этим сценарием, - это управлять 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, а бродяга будет работать с правой виртуальной машиной.

Я не придумал script, поскольку в основном большую часть времени, когда я работаю с dev, и очень мало раз мне нужно переключиться на другого провайдера. но я не думаю, что будет слишком сложно прочитать параметр из CLI и сделать переименование более динамичным.