Как запустить команду только на первом экземпляре определенного уровня при развертывании с помощью opsworks?

Мы развертываем приложение Laravel на aws opsworks, все работает отлично, однако нам нужно сделать еще две вещи:

1) При каждом развертывании мы хотим запускать php artisan migrate для установки обновлений базы данных.
2) У нас есть файл (app/database/run.list), который содержит список имен классов для каждой строки в файле, который нам нужен. запустить php artisan db:seed --class={line from file}. например

run.list содержит

NewSystemSeed
NewUserSeed
CreateDefaultTemplatesSeed

мы хотим бежать

php artisan db:seed --class=NewSystemSeed
php artisan db:seed --class=NewUserSeed
php artisan db:seed --class=CreateDefaultTemplatesSeed

Эти части не совсем сложные (хотя я немного застрял на последнем). Часть, на которой я застрял, заключается в том, что мы хотим сделать это только в первом экземпляре на определенном уровне (слой php-приложения).

Очевидно, что мы не хотим заполнять базу данных для каждого экземпляра!

Есть ли способ автоматизировать это, или мы должны создать еще один рецепт, а затем после развертывания вручную запустить этот рецепт на экземпляре?


person Hailwood    schedule 17.04.2014    source источник
comment
Обратите внимание: я не был уверен, был ли SO лучшим сайтом SE для этого вопроса, поэтому, если есть лучший сайт для вопросов, связанных с devops, пожалуйста, дайте мне знать!   -  person Hailwood    schedule 17.04.2014
comment
Отличный вопрос. Не могли бы вы записать что-то в базу данных при запуске сеялки и проверить ее при запуске? Таким образом, другие серверы увидят флаг и пропустят семя.   -  person ceejayoz    schedule 17.04.2014
comment
@ceejayoz, это в значительной степени то, что делают миграции, теоретически мы могли бы записать наши семена как миграции, но наши семена обычно записываются идемпотентно, поэтому, скажем, мы хотели обновить список ролей, наше семя уничтожит все роли и вставит каждую один из них снова, так что они многоразовые.   -  person Hailwood    schedule 17.04.2014
comment
Я знаю, что в эластичном бобовом стебле с ebextensions есть концепция Leader_only, которая была бы идеальной.   -  person Hailwood    schedule 17.04.2014


Ответы (2)


Вместо того, чтобы помещать один из ваших экземпляров на специальный уровень, который создает единую точку отказа, если этот экземпляр выйдет из строя, вы можете выбрать первый экземпляр из списка экземпляров Opsworks на уровне вашего приложения и всегда выполнять миграции там. Это позволяет вам сохранить вашу конфигурацию как есть и гарантирует, что вы всегда запускаете миграцию на работающем экземпляре, поскольку неудачные экземпляры не будут в списке.

migrations_instance_hostname = node[:opsworks][:layers]['app-layer'][:instances].keys.sort.first

if migrations_instance_hostname == node[:opsworks][:instance][:hostname]
  # do migrations
end
person billmccord    schedule 12.02.2015

Вы можете использовать слои в качестве тегов в OpsWorks для обозначения рецептов.

Создайте новый слой (возможно, «db-seeder»). Вместо того, чтобы добавлять новый экземпляр в этот слой, добавьте существующий экземпляр из вашего слоя PHP.

Создайте новый пользовательский рецепт, который выглядит следующим образом:

if node[:opsworks][:instance][:layers].include?("db-seeder")
  config_file = 'app/database/run.list'
  bash "migrate db" do
    code %Q^
      php artisan migrate
      for clz in `cat #{config_file}` do;
        php artisan db::seed --class=${clz};
      done^
  end
end

Приведенный выше рецепт будет работать только с экземпляром, который находится на уровне «db-seeder». Добавьте этот пользовательский рецепт в событие «развертывание» для уровня приложения PHP.

person Shlomo Swidler    schedule 27.10.2014