Spec-Zone.ru › Ansible 2.6

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

Интеграция тестирования с 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 проверяет их автоматически. Вместо проверки существования пользователя, рассмотрите использование модуля пользователя для его создания.

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

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

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

Таким образом, развертывание на локальной виртуальной машине разработки и в среде подготовки (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.

Однако имеет смысл включить некоторые базовые проверки работоспособности в ваши playbook, и в некоторых случаях может быть возможно запустить подмножество набора 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 и выяснить, какие тесты были бы уместны при каждом развертывании виртуальных машин разработки и какие тесты они хотели бы запускать в среде подготовки при каждом развертывании. Очевидно, что на стадии разработки модульные тесты также хороши. Но не модульно тестируйте свой playbook. Ansible описывает состояния ресурсов декларативно, поэтому это не требуется. Однако если есть случаи, когда вам нужно что-то подтвердить, это хорошо, и модули stat/assert отлично подходят для этой цели.

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

См. также

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

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

Spec-Zone.ru

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