Spec-Zone.ru › Ansible 2.8

Стратегии тестирования

Интеграция тестирования с Ansible Playbook

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

Примечание

Эта глава посвящена тестированию приложения, которое вы развёртываете, а не тестированию Ansible модулей во время разработки. Для этого, пожалуйста, перейдите к разделу «Разработка».

Встраивая определённую степень тестирования в ваш рабочий процесс развертывания, вы будете меньше удивляться, когда код попадет в производство, и в многих случаях тесты можно использовать в производстве, чтобы предотвратить распространение неудачных обновлений по всей установке. Поскольку это основанная на push-системе, очень легко запускать шаги на локальном сервере или тестовых серверах. Ansible позволяет вставлять столько проверок и балансировок в ваш рабочий процесс обновления, сколько вам нужно.

Правильный уровень тестирования

Ansible ресурсы — это модели желаемого состояния. Поэтому нет необходимости проверять, запущены ли службы, установлены ли пакеты или другие подобные вещи. Ansible — это система, которая гарантирует, что эти вещи будут декларативно истинны. Вместо этого, утверждайте эти вещи в своих playbook.

tasks:
  - service:
      name: foo
      state: started
      enabled: yes

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

Режим проверки как тест дрифта

В вышеприведённой настройке режим проверки в Ansible также может использоваться в качестве уровня тестирования. Если вы выполняете playbook развертывания на существующей системе, использование флага –check для команды ansible покажет, считает ли Ansible, что ему пришлось бы внести какие-либо изменения для приведения системы к желаемому состоянию.

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

roles:
  - webserver

tasks:
  - script: verify.sh
    check_mode: no

Модули, полезные для тестирования

Определённые модули playbook особенно подходят для тестирования. Ниже приведен пример, который гарантирует открытость порта:

tasks:

  - wait_for:
      host: "{{ inventory_hostname }}"
      port: 22
    delegate_to: localhost

Вот пример использования модуля URI для проверки того, что веб-служба возвращает:

tasks:

  - action: uri url=http://www.example.com return_content=yes
    register: webpage

  - fail:
      msg: 'service is not happy'
    when: "'AWESOME' not in webpage.content"

Легко запустить произвольный скрипт (на любом языке) на удалённом хосте, и скрипт автоматически завершится с ошибкой, если у него есть ненулевой код возврата:

tasks:

  - script: test_script1
  - script: test_script2 --parameter value --parameter2 value

Если вы используете роли (вы должны, роли отличные!), скрипты, добавленные модулем скрипта, могут храниться в каталоге «files/» роли.

И модуль assert очень упрощает проверку различных истин:

tasks:

   - shell: /usr/bin/some-command --parameter value
     register: cmd_result

   - assert:
       that:
         - "'not ready' not in cmd_result.stderr"
         - "'gizmo enabled' in cmd_result.stdout"

Если вам нужно проверить наличие файлов, которые не декларативно устанавливаются вашей конфигурацией Ansible, модуль «stat» — отличный выбор:

tasks:

   - stat:
       path: /path/to/something
     register: p

   - assert:
       that:
         - p.stat.exists and p.stat.isdir

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

Ansible — это система «быстрой ошибки», поэтому при возникновении ошибки при создании пользователя выполнение playbook прекратится. Вам не нужно следить за этим.

Жизненный цикл тестирования

Если вы напишете какую-то базовую валидацию вашего приложения в ваши playbooks, они будут выполняться каждый раз при развертывании.

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

Ваш рабочий процесс может быть следующим:

- Use the same playbook all the time with embedded tests in development
- Use the playbook to deploy to a staging environment (with the same playbooks) that simulates production
- Run an integration test battery written by your QA team against staging
- Deploy to production, with the same integrated tests.

Если вы являетесь разработчиком веб-сервиса в производстве, ваша команда QA должна написать что-то вроде набора тестов интеграции. Это должно включать такие вещи, как тесты Selenium или автоматизированные API-тесты, и обычно это не должно быть чем-то, встроенным в ваши Ansible playbooks.

Однако имеет смысл включить некоторые базовые проверки состояния в ваши playbooks, и в некоторых случаях может быть возможно запустить подмножество набора тестов QA на удалённых узлах. Именно это покрывает следующий раздел.

Интеграция тестирования с поэтапными обновлениями

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

Вот кульминация встроенных тестов:

---

- hosts: webservers
  serial: 5

  pre_tasks:

    - name: take out of load balancer pool
      command: /usr/bin/take_out_of_pool {{ inventory_hostname }}
      delegate_to: 127.0.0.1

  roles:

     - common
     - webserver
     - apply_testing_checks

  post_tasks:

    - name: add back to load balancer pool
      command: /usr/bin/add_back_to_pool {{ inventory_hostname }}
      delegate_to: 127.0.0.1

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

Однако, как вы можете видеть из вышесказанного, тесты используются как ворота — если шаг «apply_testing_checks» не выполнен, машина не вернётся в пул.

Прочитайте главу о делегировании о «max_fail_percentage», и вы также можете контролировать, сколько не успешных тестов остановят поэтапное обновление.

Этот подход также можно изменить, чтобы запустить шаг с тестовой машины удалённо на машине:

---

- hosts: webservers
  serial: 5

  pre_tasks:

    - name: take out of load balancer pool
      command: /usr/bin/take_out_of_pool {{ inventory_hostname }}
      delegate_to: 127.0.0.1

  roles:

     - common
     - webserver

  tasks:
     - script: /srv/qa_team/app_testing_script.sh --server {{ inventory_hostname }}
       delegate_to: testing_server

  post_tasks:

    - name: add back to load balancer pool
      command: /usr/bin/add_back_to_pool {{ inventory_hostname }}
      delegate_to: 127.0.0.1

В приведённом выше примере скрипт выполняется с тестового сервера на удалённом узле перед тем, как вернуть его в пул.

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

Достижение непрерывного развертывания

При необходимости вышеуказанные техники можно расширить для поддержки непрерывного развертывания.

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

- Write and use automation to deploy local development VMs
- Have a CI system like Jenkins deploy to a staging environment on every code change
- The deploy job calls testing scripts to pass/fail a build on every deploy
- If the deploy job succeeds, it runs the same deploy playbook against production inventory

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

Если вы всё ещё выполняете значительный объём ручного контроля качества, вы всё ещё должны принимать решение о том, развертывать ли вручную, но это всё равно может помочь работать в шаблонах поэтапного обновления из предыдущего раздела и включить некоторые базовые проверки состояния с помощью модулей «script», «stat», «uri» и «assert».

Заключение

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

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

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

Фокус должен быть не на тестировании инфраструктуры, а на тестировании приложения, поэтому мы настоятельно рекомендуем связаться с вашей командой QA и обсудить, какие тесты будут уместны при каждом развертывании виртуальных машин разработки и какие тесты они хотели бы запускать в среде staging при каждом развертывании. Очевидно, что на стадии разработки отличным вариантом являются и unit-тесты. Но не unit-тестируйте ваш playbook. Ansible декларативно описывает состояния ресурсов, поэтому это не нужно. Если есть случаи, когда вы хотите быть уверенными в чём-то, это отлично, и такие модули, как stat/assert, отлично подходят для этой цели.

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

См. также

Все модули
Вся документация по модулям Ansible
Работа с playbook
Введение в playbooks
Делегирование, поэтапные обновления и локальные действия
Делегирование, полезное для работы с балансировщиками нагрузки, облаками и локально выполняемыми шагами.
Список рассылки пользователей
Есть вопрос? Загляните в группу Google!
irc.freenode.net
#ansible IRC чат-канал

© 2012–2018 Michael DeHaan
© 2018–2019 Red Hat, Inc.
Licensed under the GNU General Public License version 3.
https://docs.ansible.com/ansible/2.8/reference_appendices/test_strategies.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API