
Николай Месропян, системный инженер Southbridge, подробно рассказал редакции Слёрма о шестилетнем опыте работы с Ansible. Что стоит за слоганом «Simple IT automation»? Почему нельзя остановить темное движение мысли специалиста? И насколько это ясно на старте работы с Ansible? Николай досконально «разложил» все плюсы инструмента на минусы и наоборот.
Ansible – для кого, когда и зачем
Ansible — инструмент автоматизации. Он необходим, чтобы упросить и ускорить работу с IT-инфраструктурой, когда bash-скриптов уже недостаточно. Скрипты – сложны в поддержке.
Компаниям, у которых уже есть развитые и устраивающие всех средства работы с инфраструктурой, сетями, настройкой серверов и деплоем приложений, логично продолжать использовать имеющиеся инструменты. В остальных случаях он может помочь даже специалистам без навыков работы с другим подобным ПО. Для Ansible есть готовые модули стандартизации описания конфигурации и работы с инфраструктурными компонентами. Также хорошо организована работа с данными сериализованными и не очень: есть фильтры, как заимствованные из Jinja2, так и собственные.
«Точка входа» в сложные процессы
Работу с Ansible я начал с автоматизации рутинных действий по настройке серверов и созданию площадок под веб-сайты. Пару лет работал с ним не особо много. Потом втянулся, начал читать документацию и делать более сложные вещи.
За это специалисты чаще всего и хвалят Ansible. С ним можно начать работать, бегло ознакомившись с документацией и примерами, не изучая каких-то языков программирования и прочих сложностей. Так как уже написано огромное количество модулей для решения самых разных задач:
- развёртывания облачных окружений у различных провайдеров; 
- настройки операционных систем; 
- установки приложений; 
- работы с сетевыми устройствами — коммутаторами, роутерами, в том числе виртуальными; 
- работы с cgroup-контейнерами разных видов (Docker, Podman); 
- взаимодействия с Kubernetes API и так далее. 
По мере развития кодовой базы можно углублять знания, постепенно совершенствуя свои навыки работы с Ansible.
В целом, проще перечислить, чего Ansible не умеет. А недостающий модуль можно написать самому. Но лично мне не требовалось. Я всегда обходился штатными специфическими модулями + command/shell. При грамотном применении их можно сделать квази-идемпотентными. Мой пример не может быть полностью репрезентативным, разумеется. В профессиональных сообществах, связанных с Ansible, строго рекомендуют написание собственных модулей в случаях, когда реализация с помощью модулей общего назначения требует «обмазки» сложной логикой. У меня в практике не было подобного примера.
YAML: за и против
В качестве плюса можно добавить использование языка разметки YAML для описания конфигурации. Он интуитивно понятен и весьма популярен сегодня благодаря распространению решений типа Kubernetes.
Фундаментальный недостаток связан с тем, что синтаксис YAML позволяет реализовать любые, самые изощренные bad practices. Просто потому, что это универсальный язык разметки, и при его создании ничего не знали ни про какой Ansible. Он никак не ограничивает самые темные движения мысли разработчика.
Главная слабость Ansible — обратная сторона низкого порога вхождения
Можно легко и непринуждённо породить монстра, который будет выполнять свои функции, но весь состоять из bad practice — сложного в поддержке и непредсказуемо ведущего себя при нетипичных входных данных.
Наиболее зловещими и распространенными антипаттернами, с моей точки зрения, являются два. Назовем их условно «всеобъемлющие роли» и «убей их всех, бог потом рассортирует»  «запускаем плейбук на всех хостах, разбираем условия выполнения в процессе».
Всеобъемлющие роли. Бывает, что вместо набора ролей, каждая из которых делает что-то одно, но хорошо, пишется роль, пытающаяся «объять необъятное». Она, как правило, оказывается пронизанной неочевидными зависимостями и условиями выполнения тасков, крайне затрудняющими чтение и понимание кода. Такое происходит или при добавлении функционала в первоначально простенькую роль (упускается момент, в который становится нужно её декомпозировать на отдельные роли), или просто при изначальном недостатке понимания требуемой архитектуры.
Например:
roles ┐
      └ web-serverВерно:
roles ┐
      │‐nginx
      │‐php
      │‐php-fpm
      │‐rvm
      │‐nodejs
      └ selinuxНеиспользование групп хостов. Эта «bad practice» весьма распространена и встречается слишком часто, даже в больших и серьёзных проектах. Подобная проблема также связана с недостаточной декомпозицией, но уже не в контексте «UNIX way», а в контексте «потока выполнения». Вместо того чтобы разбить хосты на группы и, используя набор плеев, выполнять отдельные роли на нужных группах хостов, разработчик ставит hosts: all и внутри tasks с помощью условий разбирает, какой таск на каком хосте выполнить. В результате получается «вермишель», глядя в которую сложно понять, «кто на ком стоял».
Например:
- name: Play for all hosts
   hosts: all  
 
  tasks:
   - name: >
	  Include role bar
	  conditionally
     include_role:
	  name: bar
     when: foo_var is defined Верно:
[foo]
bar1.example.com
bar2.example.com
- name: Play for foo hosts
  hosts: foo
  tasks:
   - name: Import role bar
     import_role:
	   name: barУмело применяя оба этих подхода можно написать проект, который при изменении входных условий может ломаться в самых неожиданных местах и будет весьма неудобен в поддержке и развитии даже для того, кто его написал.
Разумеется, список негодных практик и антипаттернов не исчерпывается двумя описанными случаями. Можно вспомнить и более очевидные вещи, которые изрядно портят жизнь новичкам.
- Так называемый «bashsible», когда вместо имеющихся специфических модулей не к месту применяются - commandи- shell. При этом теряется идемпотентность и могут возникнуть лишние сторонние эффекты.
- Использование - lineinfileвместо- template— теряется предопределённость и декларативность конфигурации.
- Использование имен переменных, не уникальных для данной роли — это, очевидно, рано или поздно приводит к конфликтам. 
Push or pull
Наиболее часто применяющийся способ работы любого сложного ПО — это взаимодействие с удалёнными хостами через ssh. Оно происходит по модели push: сам Ansible запускается на «центральном» управляющем хосте, ходит на управляемые серверы и что-то там делает. И тут возникает проблема со скоростью работы и зависимость от стабильности сети.
Справедливости ради добавлю: в последние год-два разработчики уделяют большое внимание скорости работы Ansible, и это приносит видимые результаты. Доработки позволяют нам потихоньку отказываться от использования стороннего модуля Mitogen, который ранее использовали для увеличения скорости выполнения. Тем не менее в скорости работы он уступает тем системам, которые выполняются непосредственно на конечных хостах — по модели pull.
Я выбрал Ansible. Этот инструмент показался мне более понятным для начинающего, чем один его основной конкурент и более популярным, перспективным и стабильным чем другой. Слоган Ansible: «Simple IT automation».
НЕ Ansible – для кого, когда и зачем
Поскольку это инструмент максимально универсальный, то, разумеется, в некоторых узких нишах он будет проигрывать каким-то специализированным конкурентам.
Как средство настройки и поддержания конфигурации серверов он проигрывает в скорости работы таким распространённым системам, как SaltStack и Chef. Chef конкурирует с Ansible ещё и как средство деплоя.
В нише конфигурации сетевых устройств у Ansible тоже есть конкуренты, но это, как правило, решения от вендоров, которые пишут инструменты под своё железо Так делают, например, Cisco, D-Link.
В нише доставки приложений есть целый мир инструментов, заточенных под язык/фреймворк.
В моей практике были ситуации, когда эффективнее выбрать другой инструмент. Например, те операторы Kubernetes, которые требуют постоянного согласования описанной и действительной конфигураций (reconсiling), лучше писать на Go. Ansible – слишком медленный и однопоточный для подобных задач. Приходилось идти на компромиссы за неимением квалификации для полноценного использования Golang.
Я знаю случаи, когда с Ansible уходили на SaltStack, так как для конкретного кейса нужна была более распределённая система. С другой стороны, Ansible используют даже на Windows. Признаться, я в этом плохо разбираюсь, но раз используют, значит, видят преимущество перед «родными» системами управления конфигурациями.
Подводя итог, Ansible является достаточно мощным и гибким инструментом для того, чтобы закрывать большинство инфраструктурных задач и вполне пригоден для создания верхних уровней абстракции для задач деплоя, если уметь с ним работать правильно.
Народная мудрость советует учиться на чужих ошибках.
Всеволод Севостьянов, автор курса «Ansible: Infrastructure as Code», собрал множество примеров и кейсов, демонстрирующих «что такое хорошо, а что такое плохо». Для закрепления наглядной теории студентам придется выполнить 78 тестовых и 46 практических заданий на стендах в личном кабинете. Один из 8 блоков курса посвящен горячо обсуждаемому в профессиональных сообществах вопросу: когда и как писать собственный модуль? А еще встречи со спикером, общение в чатах, настоящий IT-поединок и целая коллекция забавных мемов. Результат: быстрый «вход» в Ansible без порождения «монстров», о которых предупреждал Николай Месропян.
 
           
 
amarao
А вот, внезапно, за всё время, это первый дельный обзор.
gecube
внезапно, я согласен. Но деталей все равно не хватает.
например здесь. Какой такой инструмент менее стабильный? puppet/salt? Смешно. Ансибл более понятный для новичков? Наверное, да, но эта "кажущаяся" простота и приводит к тому, что очень легко наделать говнокода на башсибле или реализовать те самые антипримеры в статье. Никто не придет и не побьет по рукам за это. Более сложные инструменты, очевидно, имеют более высокий порог входа - это, во-первых, отсекает людей, которые не включают голову, а, во-вторых, подумаешь два раза, перед тем как приступать к решению задачи.