Всем привет, недавно мы начали цикл статей о тестировании в 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 систему). Автоматизация исключает человеческий фактор, улучшает качество и скорость тестирования. Рассмотрим следующие системы:
- Kitchen CI
- Travis CI
- Другие 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)
Daedmen
18.05.2015 17:06+1А можно поподробнее написать, так сказать best practice какие именно тесты писать, что проверять?
IgorITL Автор
20.05.2015 11:56Подробнее мы рассказываем в отдельном цикле статьей, скоро выйдет вторая часть. Какие именно тесты писать, зависит от вашего кода, примеры можно посмотреть в нашем кукбуке, если вы используете Chef. Если другую систему, то смотрите в репозиториях, как тестируют самые популярные community модули или роли.
mikhailov
18.05.2015 23:02Монолитные приложения/инфраструктуры как разворачивать так и тестировать легче; если что-то идет не так, заметить и исправить проще. Проблемы начинаются и консультанты заняты сложными задачами, поделитесь опытом решения таких сложных задач на реальном примере и цены вам, ребята, не будет. Уверен, такой опыт у вас точно есть. И более конкретный вопрос: работаете на CentOS 6, переходите на семерку, вся автоматизация идет в баню, ломается все, systemd не дает жить, умолчания другие, transparent huge pages ставят редис и базу на колени, поведение свопа другое (значение 0 не поставишь уже). Это реальные проблемы, которые автоматизация может ускорить решить, а может и не может. План такой: автоматизирую, обновляю, быстро исправляю все, что идет не так. Реально?
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 для обновления ОС, когда у вас инфраструктура в виде кода, ввод нового сервера занимает очень мало времени.
mikhailov
20.05.2015 16:27Накатить имеющиеся кукбуки и проверить, что упадет? В переходе CentOS 6-> 7 падает много всего, что сопоставимо с подбором новых кукбуков или полном их переписывании (привет, systemd). Польза в тестировании очевидна, вопрос как помочь себе тестировать правильно? Поделитесь!
mvs
19.05.2015 18:46Ох, сложную и интересную тему вы подняли, спасибо за статью и за Ansible-lint в частности!
Для своих задач сейчас пишу playbook по настройке однотипных серверов с нуля, начиная с разбиения диска на разделы и заканчивая регулярными обновлениями софта. И пока что самое удобный способ тестирования — локальная виртуалка в Vmware Player.IgorITL Автор
20.05.2015 12:49Пожалуйста, а как вы запускаете Ansible код в Vmware Player, используя Vagrant?
mvs
20.05.2015 13:50+1Нет, всё гораздо примитивнее. Задачи по автоматизации создания виртуалок в облаке (или в плеере для тестирования) нет, достаточно только автоконфигурации заранее созданных вручную, поэтому обхожусь без Vagrant'а.
А для запуска Ansible не требуется какого-либо клиента на настраиваемых виртуалках, достаточно только работающего ssh и ключа.mikhailov
20.05.2015 16:17Автор Ansible рекомендует использовать базовый образ и клонировать перед прогоном кукбуков. Vagrant в некоторых случаях — избыточная абстракция со своими зависимостями. В целом идеи в основе Ansible более традиционны (agent less, последовательность событий жестко задается контролируется, стандартный ssh прокол) и даже легко воспроизводимые напрямую через cat script.sh | ssh «bash -esx». В случае с Chef/Puppet/SaltStack vagrant несомненно полезен как инструмент и воркфлоу.
mvs
20.05.2015 22:05+1Всё верно. С Ansible, в силу его простоты, можно играться очень разнообразно: прогнать playbook на всех серверах из hosts или только на одном, сделать проверку (--check) вместо внесения реальных изменений, запустить только один или несколько сценариев (--tags) вместо всех, начать работу с определённой команды (--start), посмотреть что и как будет изменяться (--diff) или просто добавить подробностей работы по вкусу (-v, -vv, -vvv и т.д.). Ну и, естественно, все эти опции можно комбинировать.
Более того, благодаря идемпотентности операций (и прямых руках писателя сценариев, разумеется) рисков сделать что-то неправильно становится меньше и в некоторых случаях можно обходиться без отдельного тестового сервера или виртуалки.
Uburwator
Спасибо за статью, Игорь.
Небольшой вопрос: ты написал, что Test-kitchen «является отличной альтернативой Vagrant для запуска инфраструктурного кода», а я думал, что он просто является надстройкой, которая сама использует Vagrant для поднятия виртуалок, генерируя Vagrantfile по шаблону, а не альтернативой. Бывает ли Test-kitchen без Vagrant?
IgorITL Автор
Да, бывает, Test Kitchen использует Vagrant драйвер для локального тестирования, для облачных хостингов у него свои собственные провайдеры.
ILLIA
FYI: для локального тестирования можно выбрать и test-kitceh + Docker github.com/portertech/kitchen-docker, лечге и быстрее, но есть свои баги(
IgorITL Автор
да, или kitchen-lxc, а какие баги в kitchen-docker?