Pull to refresh
EPAM
Компания для карьерного и профессионального роста

Паттерны и антипаттерны Chef

Reading time 4 min
Views 11K
Original author: Doug Ireton

Предисловие от переводчика


Однажды мой коллега скинул мне ссылку на статью-источник. Сначала я не воспринял её всерьёз. Но затем, наступив на кучу граблей и набив несколько своих шишек, понял, о чём шла речь.

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

Статья будет полезна как для видавших виды «поваров», так и для новичков.


Антипаттерн: Изменение (forking) комьюнити cookbook-ов


Я так делал, возмонжно вы тоже. Всё начинается довольно невинно и не предвещает ничего плохого. Вы добавляете парочку атрибутов, меняете metadata.rb. Вскоре вам нужно добавить свой рецепт, и может даже LWRP. Теперь у вас каша из ваших изменений и комьюнити кода, особенно если cookbook в активной разработке на GitHub-е. Рано или поздно придётся исправлять конфликты. Будет сложно выделить логические ошибки, если и в исходном cookbook-е, и в вашем изменения почти одинаковые. И как теперь вы будете версионировать этого «Франкенштейна»? Использовать ту же версию, что и в апстриме? Короче говоря, это антипаттерн, который потом трудно исправить.

Единственное исключение из правила «не форкай комьюнити cookbook-и» — это если вы собираетесь свои изменения вернуть назад сообществу. Тогда нужно создать фичер ветку в git-е и послать pull request. Это должна быть ветка живущая только до тех пор, пока изменения не объединятся с основной веткой.

Паттерн: Создать свою обёртку (wrapper-cookbook) со своими атрибутами и рецептами


Вместо форканья комьюнити кукбука лучше использовать его «как есть» при помощи кукбука-обёртки. В этом кукбуке-обертке в metadata.rb нужно прописать зависимость от этого кукбука и использовать include_recipe для запуска рецептов из комьюнити кукбука. Нужно поменять дефолтные атрибуты? Тогда нужно переписать их в кукбуке-обертке.

С этим паттерном может помочь gem Chef-Rewind.

Антипаттерн: Использование аттрибутов в ролях


Перечисление аттрибутов в ролях опасный антипаттерн, который может поломать ваш продакшн. Представьте следующий сценарий. У вас есть web_server роль с атрибутами для имен и настроек двух сайтов, которые нужно установить на этот сервер. Теперь представьте, что вам нужно разделить эти сайты на две роли app_server и blog_server. Ну и как вы собираетесь это тестировать на dev окружении? Можно рискнуть и надеяться, что все будет ОК или перезаписать атрибуты в Chef Environments (сначала на dev, потом на qa и т.д.) и не забыть почистить их после того, как они попадут на продакшн. Не самый лучший вариант.

Лучше использовать атрибуты в кукбуке-обёртке.

Паттерн: Установка своих аттрибутов в кукбуке-обёртке


Роли версионировать Chef не умеет, зато кукбуки — да. Устанавливая нужные атрибуты в кукбуке-обёртке и указвая в Chef Environment нужную версию кукбука, можно продвигать изменения от dev к production-у.

В идеале это должно быть частью CI процесса с тестами и постепенным продвижением изменений в автоматическом режиме. Но это уже отдельная история.

Антипаттерн: Установка списка запуска (run list) в роли


Chef роли кажутся идеальнами для хранения списка запускаемых рецептов. Однако, этот подход страдает теми же недостатками, что и предыдущий антипаттерн. Если вы добавите или удалите рецепт из списка run_list в роли, то эти изменения применятся ко всем серверам с этой ролью, включая продакшн серверы.

Так делать не нужно:
name "web_server"
description "Role for web servers"

run_list(

  "recipe[base_server::disk_configuration]",
  "recipe[base_server::dhcp_reservation]",
  "recipe[base_server::pagefile]",
  "recipe[utility::install_tools]",
  "recipe[web_server::web_sites]",
  "recipe[base_server::ssl_certs]"

)


Паттерн: Укажите run list в рецепте default в созданном спциально для этого cookbook-e (т.н. role-cookbook или application-cookbook)


Храните в роли минимальный список рецептов. Полный список рецептов должен храниться в application-cookbook-е. Например, вот так может выглядеть роль web_server:
name "web_server"
description "Role for web servers"

run_list(
  "role[base]",
  "recipe{web_server]"
)
 

Рецепт default вашего application-cookbook-а будет выглядеть примерно так:
# web_server cookbook recipes/default.rb

  include_recipe "base_server::disk_configuration",
  include_recipe "base_server::dhcp_reservation",
  include_recipe "base_server::pagefile",
  include_recipe "utility::install_tools",
  include_recipe "web_server::web_sites",
  include_recipe "base_server::ssl_certs"


Опять же, это для того, чтобы можно было легко управлять версиями кукбуков и тестировать изменения до версии 2.1.0 на dev окружении в то время, как на продкшене будет стабильная 1.5.0.

Заключение


Следуя приведенным выше паттернам, вы сэкономите кучу сил и времени. Вам не нужно будет делать сложных мёрджей, так как все изменения хранятся в кукбуке-обёртке(wrapper cookbook).

Устанавливая необходимые атрибуты и run_list в кукбуках, а не в ролях, вы не получите проблем с версионированием и изоляцией окружений.
Tags:
Hubs:
+8
Comments 38
Comments Comments 38

Articles

Information

Website
www.epam.com
Registered
Founded
1993
Employees
over 10,000 employees
Location
США
Representative
vesyolkinaolga