Несколько лет я слышал только об Ansible. Это должно было решить все ваши проблемы с развертыванием. Это должно было облегчить жизнь. Черт возьми, он должен был доставить нас на Марс — пока SpaceX его использовала…

Но через некоторое время Ansible, похоже, перестал работать. По мере того как росло движение инфраструктура как код и неизменяемая инфраструктура вместе с ним, другие инструменты, казалось, обогнали Ansible. На этом этапе я перестал его изучать, так как начал работать над приложениями на основе Kubernetes, которые полностью включали неизменяемую инфраструктуру.

Однако недавно я работал над некоторыми приложениями, которые используют традиционные виртуальные машины, а не облачный подход. Чтобы управлять нашим парком из более чем 20 виртуальных машин (в одной среде!), мы обратились к Ansible. Мы используем Ansible для управления конфигурацией всех наших виртуальных машин и запуска специальных команд для отладки нашей системы или восстановления после сбоя.

Поскольку я заново изучаю Ansible, я подумал, что было бы полезно дать некоторое представление о том, что это такое, каковы его компоненты и несколько ошибок, с которыми я столкнулся. Я не буду вдаваться в подробности, поскольку Ansible БЫСТРО усложняется. Однако, поскольку Ansible очень быстро усложняется, его может быть сложно просмотреть. Я оставлю вам несколько советов о том, как проверить код вашего Ansible на предмет успеха и удобства сопровождения в долгосрочной перспективе.

Что такое Анзибл?

Ansible — это, по сути, инструмент управления инициализацией и конфигурацией. Вы пишете в основном декларативные .yml файлы, чтобы указать желаемое состояние машины. Идея состоит в том, что вместо того, чтобы писать большой bash-скрипт для установки пакетов или перемещения файлов, вы просто декларируете желаемое состояние, в котором должна находиться машина, независимо от ее текущего или текущего состояния.

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

Как это работает?

Я буду краток, так как полное объяснение может получиться очень длинным и очень сложным. Ansible работает, по существу, создавая ssh-подключения к набору целевых хостов, копируя код Python на эти машины и выполняя этот Python на этих машинах для внесения изменений в систему. Майкл ДеХаан (создатель) назвал это ssh в петле.

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

Как ты это используешь?

С Ansible у вас обычно есть следующие компоненты:

  • Инвентарь — набор машин/хостов, которыми вы хотите управлять/настраивать. Вы можете сгруппировать их в иерархии с дочерними элементами и т. д. Вы также можете настроить таргетинг на несколько групп, используя различные шаблоны и команды ограничения.
  • Модули. Модули по сути являются абстракциями для управления целевым хостом. Думайте о них как о слое API, предоставляемом Ansible для всех вещей, которые вы хотели бы делать на хосте. Вы используете различные модули для взаимодействия с разными частями изменяемых хостов. Модули, как правило, связаны либо с конкретной подсистемой компьютера (файлы, пакеты, сеть), либо с широко используемыми пакетами (systemctl), но также существуют для облачных провайдеров или конкретных потребностей, связанных с поставщиком.
  • Задачи — задачи представляют собой одиночные вызовы модуля. Они, как правило, очень малы и вносят постепенные изменения. Думайте о задаче как о взаимодействии с определенным API для хоста, на который вы ориентируетесь. Задачи используют модули для выполнения этого взаимодействия
  • Роли — роли фактически представляют собой группу задач. Во многих проектах Ansible у вас будут плейбуки, которые вызывают серию игр как ролей с определенными переменными (см. переменные ниже). Роли, как правило, рассматриваются как основной строительный блок для Ansible, поскольку они могут позволить кому-то сгруппировать все задачи, необходимые для определенного желаемого состояния. Например, установка и запуск базы данных на хосте.
  • Playbooks – набор "игр", которые вы запускаете против набора хостов. Игры, как правило, представляют собой определенные группы ролей или задач, которые целиком применяют одно логическое изменение.
  • Vars — переменные, которые динамически используются в играх во время выполнения для настройки машин в вашем инвентаре. Переменные быстро усложняются, поэтому важно знать приоритет переменных.

В чем хорош Ansible? Где это терпит неудачу?

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

Ansible также очень хорошо делает общие команды, которые могут понадобиться для отладки, доступными и пригодными для повторного использования. Вместо того, чтобы заходить на более чем 20 машин, чтобы искать запись в журнале или проверять, работает ли служба, вы можете настроить таргетинг на все хосты, используя playbook или специальную команду, чтобы просмотреть все машины и отчитаться.

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

Другая большая проблема с Ansible, которую я обнаружил, заключается в том, что он может легко ощущаться как паутина или спагетти. Vars может поступать откуда угодно и переопределяться на каждом уровне в соответствии с правилами приоритета переменных Ansible. По мере роста сложности среды растет и сложность необходимых переменных. Будучи мощным и гибким, я провел часы, разочаровываясь в Ansible, когда переменная, которая, как мне казалось, имела определенное значение, была переопределена в месте, которое, как я думал, не применимо.

На что обратить внимание при обзоре Ansible

Со всеми этими ловушками может быть сложно эффективно просматривать изменения кода Ansible. Я обнаружил, что несколько вещей могут помочь.

  • Используйте линтер — всякий раз, когда я говорю о проверках кода, я всегда рекомендую использовать линтер, чтобы поддерживать стандарты формата и синтаксиса в вашей команде. В Ansible это очень важно. Пробелы в фигурных скобках? Цитаты здесь или нет? Правда, правда или да? Просто используйте пакет ansible-lint и не оглядывайтесь назад :)
  • Приоритет переменных — я уже упоминал об этом несколько раз, но приоритет переменных — очень важная вещь для понимания в Ansible. Если вы плохо понимаете это, вы будете часами сидеть за клавиатурой, не понимая, почему это значение постоянно меняется на вас.
  • Организация группы хостов — вы используете группы хостов для таргетинга на хосты, на которых вы хотите запускать определенные игры и задачи. Вы должны знать, как они организованы! Если вы видите изменения, из-за которых сложно определить, на каких хостах будет запускаться игра, сообщите об этом! Когда вы не можете понять, как организованы ваши группы хостов, все остальные настройки Ansible бесполезны.
  • Имена переменных — имена переменных встречаются почти во всех формах проверки кода, но в Ansible это особенно актуально. Переменные в Ansible настроены либо на глобальную область действия, либо на область воспроизведения, либо на область хоста, но вы быстро обнаружите, что на переменные ссылаются на протяжении всей игры, и это может быть трудно отслеживать. Я рекомендую называть переменные с конкретным намерением и держать их как можно ближе к хосту или контексту игры, насколько это возможно. Префикс vault_ к переменным из вашего хранилища также является шаблоном, который я использовал с большим успехом.

Наконец, всегда старайтесь сгруппировать связанные задачи в роли, которые можно повторно использовать в разных сборниках сценариев. Это принесет дивиденды по мере роста вашего кода Ansible.

Это лишь краткий экскурс в мир Ansible. Я знаю, что это не было подробным руководством, но я надеюсь, что некоторые общие рекомендации и принципы помогут вам, когда вы начнете его использовать!

Удачного кодирования (написание yaml?)!

Первоначально опубликовано на https://dangoslen.me.