Є такий тренд зараз - працювати з IT-інфраструктурою як з кодом. Добре мета цього методу описується цією цитатою:
"Enable the reconstruction of the business from nothing but a source code repository, an application data backup, and bare metal resources"
Я повністю підтримую цю ідею, причому саме в цьому трактуванні.
Якщо говорити про парадигму, яку нам пропонує цей метод, то ось вона:
Підтримувати модульну, легко піддається автоматизації інфраструктуру, і описувати цю інфраструктуру за допомогою мови високого рівня.
Це означає для нас, як сисадмінів, що ми повинні користуватися всіма напрацюваннями розробників ПЗ, такими як:
- Версіонування опису інфраструктури;
- повноцінне тестування опису з використанням декількох стадій (dev, QA, staging, prod);
- внутрішні стандарти "кодинга";
- безперервна інтеграція (continuous integration).
Проблема ж, на мій погляд, полягає в тому, що багато хто розуміє "Інфраструктуру як код" в іншому сенсі - "Давайте писати опис нашої інфраструктури за допомогою Chef / Puppet, немов це звичайний код". Причому у Chef це виражено помітно сильніше, оскільки в якості DSL використовується чистий Ruby.
Звичайно, програмісти, яким-небудь чином стали відповідальними за адміністрування серверів за допомогою Chef, з радістю починають використовувати звичний інструмент (Ruby) звичним же чином, і виходить рівно те, що вони звикли робити. Замість декларативного опису інфраструктури, на яке можна нацькувати який-небудь інструмент для управління конфігураціями і отримати налаштовану інфраструктуру, на виході отримуємо програму з купою хаков, з множинним розгалуженням, з виконанням коду на Shell, яка може імперативно привести систему до потрібного стану.
Прикладом може бути практично будь-який стандартний кукбук Chef. Взяти хоча-б Nginx cookbook. Він вміє ставити Nginx декількома способами, включаючи складання з вихідних, і містить в собі тонну змінних, покликаних замінити написання осудної шаблону конфіга Nginx завданням значень цієї купи змінних.
Це вже сам по собі поганий підхід - намагатися впихнути всі можливості Nginx (та ще й зі сторонніми модулями) в один мега-шаблон, і правити тільки змінні.
Збірка з вихідних в кукбуке теж викликає масу питань. Навіщо це робити на бойовому сервері? Зібрати пакет на build-сервері, протестувати його, і поширити зі свого сховища з усіх серверів - ось це нормальний підхід.
І все це породжує стільки складнощів, стільки праці потрібно для написання, тестування і підтримки в актуальному стані цього кукбука, замість того, щоб розділити весь процес на кілька простих кроків:
- Зібрати пакет Nginx з потрібними модулями на build-сервері, протестувати і помістити в репозиторій;
- Написати шаблон конфіга Nginx під ваші завдання, що враховує відмінності між наявними середовищами (staging / prod);
- Написати кукбук / маніфест / роль, який буде ставити пакет з вашого сховища, заповнювати шаблон змінними, які відрізняються в ваших середовищах, і класти цей шаблон на сервер.
Ось і все, не потрібні тонни коду на Ruby зі вставками на Shell, не потрібні сотні змінних. У нас є опис процесу складання пакета (spec-файл або Makefile), і декларативне опис необхідного стану системи.
І це прекрасно підходить під один з принципів Екстремального Програмування. який звучить так:
Do The Simplest Thing That Could Possibly Work
Тобто, треба зробити так, щоб наш кукбук / маніфест / роль був досить простим для того, щоб задовольняти нашим сьогоднішнім вимогам. Звичайно, захоплюватися і робити щось "в лоб", не думаючи, буде невірно, але і створювати псевдо-універсальних монстрів точно не варто. У всьому потрібна міра.
Що найгірше - люди, які пишуть сам Chef, і написали цей кукбук для Nginx. Написали добре, але написали як програмісти, а не як системні адміністратори. А коли сисадміни пишуть кукбукі в такому стилі, на їх творіння взагалі без сліз не поглянеш.
Саме тому я вибрав для управління серверами Ansible, створений Michael DeHaan, людиною, який працював в Puppet Labs, створив Func і Cobbler, а потім, маючи великий досвід і бачачи помилки попередників, написав Ansible. Ansible помітно простіше Chef або Puppet, і декларативний yaml-файл з описом необхідного стану системи обмежує можливість вистрілити собі в ногу і навернути лапшеобразного імперативного коду.
Якщо цю замітку прочитають програмісти, які адмініструють сервера - перестаньте тлумачити "Інфраструктуру як код" невірно! Ми беремо кращі напрацювання зі світу програмування, але це не традиційне програмування. Не треба перевинаходити Bash-скрипти на Ruby.