Всем привет, недавно мы начали цикл статей о тестировании в Chef, но сегодня я расскажу о более вводных и универсальных вещах: зачем тестировать инфраструктуру, какие инструменты для этого есть и как все это автоматизировать. Также затрону тему публикации инфраструктурного кода в open source. Статья будет интересна пользователям любой из популярных систем управления конфигурацией — Chef, Puppet, Ansible или SaltStack.

Статья основана на моем выступлении на конференции Стачка в Ульяновске, слайды доступны здесь. После прочтения пишите про свой опыт в тестировании инфраструктуры, думаю, всем будет интересно.

Поехали.

Тесты?


Если инфраструктура становится кодом, то хороший код должен быть покрыт тестами. Тесты помогают не бояться вносить изменения, повышают качество и скорость написания кода, дают обратную связь. Код, покрытый тестами, проще поддерживать, он проще в эксплуатации и проще для новичков. В концепции «инфраструктура как код» тесты позволяют автоматизировать ручные действия и сохраняют много времени, а также являются документацией, они показывают, как работать с вашим кодом.

Когда актуально?


Тесты особенно актуальны, когда код изменяется, когда над ним работают несколько человек, а изменения затрагивают сложную логику или сторонний код. От изменений никуда не деться, выходят новые версии операционных систем и программ, меняются API и ваш инфраструктурный код устаревает и требует изменений. Когда в код вносят изменения несколько человек, вы уже не можете быть уверены, что ваши изменения не затронут другие, а если вы меняете сложную логику или сторонний код, то вероятность ошибки еще выше. Стандартный подход проверки инфраструктурного кода в Vagrant здесь уже не работает, так как занимает много времени и требует ручной проверки изменений и конечного состояния.

Что делать?


Поэтому в системах управления конфигурацией появились свои инструменты для тестирования инфраструктурного кода. Я рассмотрю самые популярные и универсальные инструменты, которые подойдут для любой из систем управления конфигурацией, будь то Chef, Puppet, Ansible или SaltStack.


Что тестировать?


Но сначала надо определиться с тем, какие части будем тестировать и что проверять.
Тестировать будем основные части из которых состоит инфраструктурный код, то есть кукбуки, модули, роли или формулы, в зависимости от того, какой системой вы пользуетесь.

Что проверяем?


Проверять будем следующие вещи:
  • синтаксис и стиль написания кода
  • функционал
  • результат работы системы управления конфигурацией


Стиль языка



Популярные системы управления конфигурацией на написаны на двух языках, Ruby и Python. Для них созданы свои стайл гайды по написанию кода и желательно им следовать, чтобы ваш инфраструктурный код было легче читать и поддерживать. Для проверки стиля языка используются стандартные анализаторы кода, такие как rubocop для Ruby и pep8 для Python. Их можно запускать вручную или они могут быть встроены в ваш редактор или IDE.

Стиль кода


Со временем и в системах управления конфигурацией выработались свои рекомендации, появились стайл гайды и специальные инструменты — линтеры. Их нужно учитывать для выявления известных проблем. Работают они на основе набора правил. Список линтеров для систем приведен ниже:


Функционал


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

Результат


Для проверки результата работы системы управления конфигурацией используется инструмент Serverspec. Это специальный фреймворк для тестирования инфраструктуры. С его помощью проверяется конечное состояние виртуальной машины или сервера. Написан на Ruby и является расширением RSpec, поддерживает все популярные Linux и BSD дистрибутивы, а также Windows. Serverspec содержит в себе около 40 встроенных ресурсов, с помощью которых можно проверить, что пакет в системе установлен, в конфиге указаны нужные параметры, сервис запущен или слушает порт. Если этого недостаточно, то можно вызвать любую shell команду и проверить ее вывод. Serverspec отличная альтернатива shell скриптам и позволяет выполнять проверки как локально, так и удаленно. Serverspec активно используется в community инфраструктурном коде, а недавно Chef анонсировали поддержку Serverspec и в рецептах.

Как тестировать?


Инфраструктурные тесты можно запускать вручную, локально или удаленно, они могут быть встроены в редактор или IDE, выполняться при каком-либо событии, например, изменении файлов на файловой системе или в репозитории.

Автоматизируем


Для автоматизации будем использовать систему непрерывной интеграции(CI систему). Автоматизация исключает человеческий фактор, улучшает качество и скорость тестирования. Рассмотрим следующие системы:


Test Kitchen


Это инструмент для запуска инфраструктурного кода и его тестирования. Test Kitchen запускает виртуальную машину, в ней запускает ваш инфраструктурный код и тесты для проверки результата. Test Kitchen позволяет запускать виртуальные машины как локально, так и удаленно. Является отличной альтернативой Vagrant для запуска инфраструктурного кода, так как вводит понятия набор тестов (suites), поддерживает все системы управления конфигурацией, Chef в базе, остальные через плагины (Puppet, Ansible, SaltStack), и поддерживает тестовый фреймворк Serverspec.

Travis CI


Это SaaS система непрерывной интеграции для GitHub проектов. Бесплатна для публичных репозиториев. Подходит для тестирования инфраструктурного кода. Есть интеграция с Chef Supermarket и Puppet Forge, о них я расскажу позже.

Но есть и ограничения, тестовое окружение в Travis CI основано на Ubuntu 12.04 LTS, поэтому если вы используете другой дистрибутив или пишете кросс-платформенный код, то не сможете его протестировать. Плюс тестовое окружение идет вместе с предустановленными пакетами и переменными окружения, которые могут вызвать конфликты.

Test Kitchen + Travis CI


Чтобы обойти эти ограничения, можно использовать две системы Test Kitchen и Travis CI вместе и запускать виртуальные машины в облаке, например, Amazon или DigitalOcean.

Другие CI системы


Если вы уже используете какую-либо CI систему, то процесс по тестированию инфраструктуры можно построить и на ней, также используя Test Kitchen для запуска кода и набора тестов.

Делимся с сообществом


Итого, инфраструктурный код у нас будет в одном стиле, удобный для поддержки, внесения изменений и обучения. Не стыдно показать другим. Поэтому делимся с сообществом и выкладываем в open source. С помощью сообщества можно улучшить тестирование и функционал инфраструктурного кода. За счет экспертизы и взгляда со стороны развитие не останавливается.

Делимся


Разработчики систем управления конфигурацией выпустили специальные платформы для обмена инфраструктурным кодом:



Не забываем


Выкладывая код в open source не забываем про следующие моменты:
  • Удалить приватную информацию (ключи, пароли, внутренние компоненты)
  • Добавить тесты и статус сборки, это повышает степень доверия к коду
  • Вести историю изменений и документацию, их можно создавать автоматически
  • Подумать о совместимости, зависимостях и конфликтах
  • Синхронизировать код с платформой сообщества
  • Добавить лицензию


Как это делаем мы


Как это делаем мы, на примере нашего Chef кукбука postgresql_lwrp:
  • Код лежит в репозитории на GitHub
  • На каждое изменение запускается билд в Travis CI
  • Выполняются проверки стиля языка и кода с помощью Rubocop и Foodcritic
  • Далее Test Kitchen запускает виртуальную машину в облаке Digital Ocean и выполняет код и Serverspec тесты
  • Если все тесты прошли и был релиз, то кукбук загружается в Chef Supermarket
  • А нам приходит нотификация в Slack чат и обновляется статус сборки на странице кукбука


Выводы


Тестируйте изменения, автоматизируйте и делитесь с сообществом.

Ссылки



На GitHub у нас есть примеры тестирования для Chef, самый популярный это postgresql кукбук. В ближайшее время мы выложим еще несколько классных кукбуков. Также мы продолжаем цикл статей на Хабрахабре про тестирование Chef, слушайте наш подкаст Devops Дефлопе и приходите на DevOps митапы в Москве.

Комментарии (14)


  1. Uburwator
    18.05.2015 16:22

    Спасибо за статью, Игорь.
    Небольшой вопрос: ты написал, что Test-kitchen «является отличной альтернативой Vagrant для запуска инфраструктурного кода», а я думал, что он просто является надстройкой, которая сама использует Vagrant для поднятия виртуалок, генерируя Vagrantfile по шаблону, а не альтернативой. Бывает ли Test-kitchen без Vagrant?


    1. IgorITL Автор
      18.05.2015 16:43
      +2

      Да, бывает, Test Kitchen использует Vagrant драйвер для локального тестирования, для облачных хостингов у него свои собственные провайдеры.


      1. ILLIA
        19.05.2015 17:15

        FYI: для локального тестирования можно выбрать и test-kitceh + Docker github.com/portertech/kitchen-docker, лечге и быстрее, но есть свои баги(


        1. IgorITL Автор
          19.05.2015 21:41

          да, или kitchen-lxc, а какие баги в kitchen-docker?


  1. Daedmen
    18.05.2015 17:06
    +1

    А можно поподробнее написать, так сказать best practice какие именно тесты писать, что проверять?


    1. IgorITL Автор
      20.05.2015 11:56

      Подробнее мы рассказываем в отдельном цикле статьей, скоро выйдет вторая часть. Какие именно тесты писать, зависит от вашего кода, примеры можно посмотреть в нашем кукбуке, если вы используете Chef. Если другую систему, то смотрите в репозиториях, как тестируют самые популярные community модули или роли.


  1. mikhailov
    18.05.2015 23:02

    Монолитные приложения/инфраструктуры как разворачивать так и тестировать легче; если что-то идет не так, заметить и исправить проще. Проблемы начинаются и консультанты заняты сложными задачами, поделитесь опытом решения таких сложных задач на реальном примере и цены вам, ребята, не будет. Уверен, такой опыт у вас точно есть. И более конкретный вопрос: работаете на CentOS 6, переходите на семерку, вся автоматизация идет в баню, ломается все, systemd не дает жить, умолчания другие, transparent huge pages ставят редис и базу на колени, поведение свопа другое (значение 0 не поставишь уже). Это реальные проблемы, которые автоматизация может ускорить решить, а может и не может. План такой: автоматизирую, обновляю, быстро исправляю все, что идет не так. Реально?


    1. IgorITL Автор
      20.05.2015 12:47

      Привет, да, у нас есть опыт перевода инфраструктурного кода с CentOS на Debian 6, с Debian 6 на 7 и с Ubuntu 12.04 на 14.04, да, даже переход с Chef 11 на Chef 12 приводит к проблемам. Алгоритм, в принципе, везде одинаковый: создаем образ с новой ОС, тестируем его локально с базовой ролью, находим ошибки, исправляем, потом проверяем с ролями сервисов, когда локальное тестирования проходит, переходим к обновлению окружений — preqa/qa/production. Я бы рекомендовал переустанавливать сервер с 0 для обновления ОС, когда у вас инфраструктура в виде кода, ввод нового сервера занимает очень мало времени.


      1. mikhailov
        20.05.2015 16:27

        Накатить имеющиеся кукбуки и проверить, что упадет? В переходе CentOS 6-> 7 падает много всего, что сопоставимо с подбором новых кукбуков или полном их переписывании (привет, systemd). Польза в тестировании очевидна, вопрос как помочь себе тестировать правильно? Поделитесь!


  1. mvs
    19.05.2015 18:46

    Ох, сложную и интересную тему вы подняли, спасибо за статью и за Ansible-lint в частности!
    Для своих задач сейчас пишу playbook по настройке однотипных серверов с нуля, начиная с разбиения диска на разделы и заканчивая регулярными обновлениями софта. И пока что самое удобный способ тестирования — локальная виртуалка в Vmware Player.


    1. IgorITL Автор
      20.05.2015 12:49

      Пожалуйста, а как вы запускаете Ansible код в Vmware Player, используя Vagrant?


      1. mvs
        20.05.2015 13:50
        +1

        Нет, всё гораздо примитивнее. Задачи по автоматизации создания виртуалок в облаке (или в плеере для тестирования) нет, достаточно только автоконфигурации заранее созданных вручную, поэтому обхожусь без Vagrant'а.
        А для запуска Ansible не требуется какого-либо клиента на настраиваемых виртуалках, достаточно только работающего ssh и ключа.


        1. mikhailov
          20.05.2015 16:17

          Автор Ansible рекомендует использовать базовый образ и клонировать перед прогоном кукбуков. Vagrant в некоторых случаях — избыточная абстракция со своими зависимостями. В целом идеи в основе Ansible более традиционны (agent less, последовательность событий жестко задается контролируется, стандартный ssh прокол) и даже легко воспроизводимые напрямую через cat script.sh | ssh «bash -esx». В случае с Chef/Puppet/SaltStack vagrant несомненно полезен как инструмент и воркфлоу.


          1. mvs
            20.05.2015 22:05
            +1

            Всё верно. С Ansible, в силу его простоты, можно играться очень разнообразно: прогнать playbook на всех серверах из hosts или только на одном, сделать проверку (--check) вместо внесения реальных изменений, запустить только один или несколько сценариев (--tags) вместо всех, начать работу с определённой команды (--start), посмотреть что и как будет изменяться (--diff) или просто добавить подробностей работы по вкусу (-v, -vv, -vvv и т.д.). Ну и, естественно, все эти опции можно комбинировать.
            Более того, благодаря идемпотентности операций (и прямых руках писателя сценариев, разумеется) рисков сделать что-то неправильно становится меньше и в некоторых случаях можно обходиться без отдельного тестового сервера или виртуалки.