Spec-Zone.ru › Ansible

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

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

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

Примечание

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

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

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

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

tasks:
  - ansible.builtin.service:
      name: foo
      state: started
      enabled: true

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

Режим проверки как тест на отклонение

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

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

roles:
  - webserver

tasks:
  - ansible.builtin.script: verify.sh
    check_mode: false

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

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

tasks:

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

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

tasks:

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

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

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

tasks:

  - ansible.builtin.script: test_script1
  - ansible.builtin.script: test_script2 --parameter value --parameter2 value

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

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

tasks:

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

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

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

tasks:

   - ansible.builtin.stat:
       path: /path/to/something
     register: p

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

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

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

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

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

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

Ваш рабочий процесс может быть таким:

- 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 playbook.

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

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

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

Вот итоговый пример встроенных тестов:

---

- hosts: webservers
  serial: 5

  pre_tasks:

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

  tasks:

    - ansible.builtin.include_role:
        name: "{{ item }}"
      loop:
        - common
        - webserver

    - name: run any notified handlers
      ansible.builtin.meta: flush_handlers

    - name: test the configuration
      ansible.builtin.include_role:
        name: apply_testing_checks

  post_tasks:

    - name: add back to load balancer pool
      ansible.builtin.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
      ansible.builtin.command: /usr/bin/take_out_of_pool {{ inventory_hostname }}
      delegate_to: 127.0.0.1

  roles:

     - common
     - webserver

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

  post_tasks:

    - name: add back to load balancer pool
      ansible.builtin.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 используют вышеописанный подход для развертывания десятка или двух раз в час, не выводя всю свою инфраструктуру из строя. Важно установить культуру автоматизированного QA, если вы хотите достичь этого уровня.

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

Заключение

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

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

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

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

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

См. также

Индекс коллекций

Просмотрите существующие коллекции, модули и плагины

Работа с playbooks

Введение в playbooks

Управление местом выполнения задач: делегирование и локальные действия

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

Связь

Есть вопросы? Нужна помощь? Хотите поделиться своими идеями? Посетите руководство Ansible по общению

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

Spec-Zone.ru

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