Git для скриптов и конфигов: первый pull request на правку сервера
Переводим bash-скрипты и Puppet-манифесты в Git-репозиторий. История изменений, ревью конфигураций и откат как рабочий инструмент - не для кода, а для инфраструктуры.
Git становится де-факто стандартом для версионирования кода и конфигурационных файлов в 2013 году
Несколько недель назад мы перевели Puppet-манифесты клиента в Git. Сегодня один из коллег открыл pull request с правкой конфигурации sshd - и это ощущалось немного странно. Не потому что плохо, а потому что раньше такое изменение делалось руками на сервере и максимум фиксировалось строчкой в тикете. Теперь оно живёт в репозитории с диффом, комментарием и историей автора.
Мы ведём инфраструктуру клиентов на сопровождении, и вопрос «кто и когда это поменял» периодически возникает в самые неподходящие моменты. Обычно - во время разбора инцидента, когда что-то перестало работать, а последнее изменение на сервере датировано «пару недель назад, кто-то из наших».
Откуда взялась идея
После того как мы описали конфигурацию серверов в Puppet-манифестах, логика подсказала следующий шаг сама. Манифесты уже лежали в каталоге. Каталог надо куда-то класть. Git - очевидный ответ. Но дальше выяснилось, что в репозиторий хочется положить не только манифесты: там же оказались bash-скрипты для резервного копирования, cron-задачи, шаблоны конфигов nginx и список специфичных для клиента sysctl-параметров.
Когда всё это попало в один репозиторий и мы написали первый git log, стало ясно: раньше аудитного следа по инфраструктуре просто не существовало. Не потому что кто-то халтурил - просто такой инструмент не был частью процесса.
Что изменилось на практике
Раньше правка конфигурации выглядела так: зайти по SSH, открыть файл в vim, поправить, рестартовать сервис, проверить что работает. Всё. Если что-то шло не так через три дня, разбор начинался с опроса коллег.
Теперь схема другая:
- Правка делается в репозитории - в ветке или прямо в main, зависит от критичности.
- Изменение коммитится с осмысленным сообщением - не «fix» и не «правка», а «разрешить agent forwarding только для bastion-хоста, закрыть PermitRootLogin».
- Puppet подхватывает изменение через
git pullпо крону и применяет манифест. - В
git logвиден полный след: кто, когда, что именно и зачем.
Pull request как таковой - это уже дополнительный слой. Не всегда нужный, но для правок, которые затрагивают production-конфиги сети или безопасности, стал нормой. Второй взгляд на diff перед применением - не бюрократия, а просто страховка от опечатки в /etc/ssh/sshd_config.
Структура репозитория
Мы не изобретали ничего сложного. Для одного клиента получилось примерно так:
infra/
puppet/
manifests/
modules/
scripts/
backup.sh
cleanup-logs.sh
cron/
root.crontab
docs/
network-map.txt
Отдельный репозиторий на клиента - не один общий. Это решение принималось из соображений изоляции: конфигурации разных клиентов не должны смешиваться, права доступа проще разграничить, случайный push в не тот репозиторий менее катастрофичен.
Где возникли вопросы
Секреты в репозитории. Первый же коллега попробовал закоммитить файл с паролем к базе данных прямо в шаблон. Остановили, разобрались, сделали правило: ничего с credentials в репозиторий не идёт. Секреты передаются через отдельный механизм или хранятся вне дерева манифестов. Это обсуждается, единого решения в команде не выработали.
Права доступа к репозиторию. Кто имеет право merge в main, кто только review - вопрос организационный, не технический. Пока работает на договорённостях внутри команды, но очевидно что при росте числа клиентов и людей нужна будет более явная политика.
Синхронизация по cron vs. немедленное применение. Cron раз в час - это компромисс. Быстрое изменение приходится прогонять puppet apply руками прямо на сервере, что немного нарушает идею репозитория как единственного источника правды. Пока живём с этим.
Что даёт в реальности
Главная ценность не в откате - откаты бывают редко. Главная ценность в том, что разбор любого инцидента начинается с git log --since="2 weeks ago" и сразу видно, что менялось. Это экономит время и снимает часть неловкости из разговора «а это не ты случайно...».
Второе - порог осознанности при внесении изменений чуть вырос. Когда надо написать commit message, начинаешь думать что именно ты делаешь и зачем. Мелочь, но работает.
Третье - новый человек в команде или новый сотрудник клиента может посмотреть историю и понять как сложилась текущая конфигурация. Без этого такое знание существует только в головах.
Пока это работает для одного клиента в полную силу, у остальных - частично. Переход занимает время, не в плане технического усилия, а в плане привычки.
- Puppet 3: первый манифест вместо баш-скриптов · 7 февраля 2013