Тестирование автоматизации Ansible с помощью Molecule Часть 1

от автора

В статье много информации об Ansible. Давайте посмотрим, как тестировать роли с помощью Molecule, Docker и Testinfra.

Molecule – это проект Red Hat, призванный помочь в тестировании ролей Ansible. Он обеспечивает поддержку тестирования с различными операционными системами и дистрибуями. Molecule также является весьма разноплановым проектом, позволяющим использовать множество провайдеров виртуализации, тестовых фреймворков и тестовых сценариев. Такой подход обеспечивает последовательность в разработке и обслуживании ролей.

Приступаем к работе

Настройка вашей среды

Python3 и pip – это необходимые условия для Ansible и Molecule. Установка и настройка этих инструментов выходят за рамки данного руководства.

Следующие команды установят Ansible и Molecule с помощью pip. Для получения информации о других вариантах установки посетите соответствующие страницы документации Ansible и Molecule.

# install ansible python3 -m pip install --user ansible # Install the latest version of molecule from source python3 -m pip install -U git+https://github.com/ansible-community/molecule #install testinfra python3 -m pip install --user pytest-testinfra #install the molecule docker driver python3 -m pip install -U "molecule[docker]"

Вам также потребуется установить docker-ce вместе с плагином Docker для Molecule. Последняя команда в приведенном выше скрипте устанавливает плагин docker. Этот метод применим к установке любых плагинов molecule, которые вы планируете использовать. После этого Docker сможет выступать в качестве драйвера в Molecule.

Инициализация новой роли с помощью Molecule

Теперь, когда предустановки готовы, начнем с некоторых основ. Начните с запуска molecule init role sample.demo_role --driver-name docker --verifier-name testinfra. Вуаля, Молекула создаёт новую роль, уже настроенную в тестовом каталоге. Давайте посмотрим на каталог, а затем более подробно рассмотрим эту команду.

demo_role/ ├── defaults │   └── main.yml ├── files ├── handlers │   └── main.yml ├── meta │   └── main.yml ├── molecule │   └── default │       ├── converge.yml │       ├── molecule.yml │       └── tests │           ├── conftest.py │           ├── __pycache__ │           │   ├── conftest.cpython-38.pyc │           │   └── test_default.cpython-38.pyc │           └── test_default.py ├── README.md ├── tasks │   └── main.yml ├── templates ├── tests │   ├── inventory │   └── test.yml └── vars     └── main.yml

Правда впечатляет? Molecule создал все необходимое для создания роли и одновременного ее тестирования.

Изучение команды и результатов её применения

Ниже описание команды и опций, которые мы использовали:

Molecule инициирует sample.demo_role

init role задействует ansible-galaxy  для создания каталога шаблонов <NAME_SPACE>.<ROLE_NAME>. Команда также подготавливает каталог Molecule, чтобы помочь начать работу. В качестве альтернативы, если у вас уже есть роль, вы можете инициировать Molecule как сценарий с molecule init scenario -r <ROLE_NAME>.

--driver-name Docker

Указывает на то, какой драйвер следует использовать для вашей тестовой среды. Драйвер определяет, какую платформу или инфраструктуру развернуть для тестов. Несколько доступных драйверов включают podman, libvirt, Azure и многие другие. Независимо от вашего драйвера, необходимо установить модуль с помощью pip. Здесь мы сосредоточимся на использовании Docker.

--verifier-name testinfra

Указывает, какой верификатор вы хотите использовать для вашего сценария по умолчанию. Верификатор – это механизм, используемый для тестирования ваших ролей. Некоторые доступные опции включают Ansible, test infra и inspect. Хотя Ansible является верификатором по умолчанию, мы будем использовать testinfra для этой демонстрации.

Вот описание созданных файлов Molecule:

./molecule/default/molecule.yml

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

--- dependency:   name: galaxy driver:   name: docker platforms:   - name: instance     image: quay.io/centos/centos:stream8     pre_build_image: true provisioner:   name: ansible verifier:   name: testinfra

./molecule/default/converge.yml

Это плейбук, который Molecule запустит, чтобы обеспечить цели для тестирования. Ниже приведен файл, который создает Molecule. Если вы можете использовать этот файл в сборнике воспроизведения, вы можете использовать его здесь.

--- - name: Converge   hosts: all   tasks:     - name: "Include sample.demo_role"       include_role:         name: "sample.demo_role"

./molecule/default/tests/test_default.py

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

"""Role testing files using testinfra.""" def test_hosts_file(host):     """Validate etc/hosts file"""     f = host.file("etc/hosts") assert f.exists     assert f.user == "root"     assert f.group == "root"

Приступаем к практике

Каждая роль должна что-то выполнять. У нас есть роль, которая в настоящее время ничего не делает, давайте исправим это, добавив некоторые задачи в ./tasks/main.yml. В этой статье мы будем придерживаться основ, добавив лишь несколько вещей, для которых мы можем писать тесты. В данном случае несколько пакетов yum, пользователь и конфигурационный файл предусмотрены в приведенном ниже коде.

--- # tasks file for demo_role - name: install some packages   yum:     name: "{{ item.name }}-{{item.version}}.{{ item.arch }}"     state: installed   with_items:     - { name: 'epel-release', version: '8-11.el8', arch: 'noarch' }     - { name: 'htop', version: '3.0.5-1.el8', arch: 'x86_64' }     - { name: 'nginx', version: '1.14.1-9.module_el8.0.0+1060+3ab382d3', arch: 'x86_64' }     - { name: 'git', version: '2.31.1-2.el8', arch: 'x86_64' } - name: add webapp user   ansible.builtin.user:     name: webapp     system: true - name: create an app directory owned by webapp   ansible.builtin.file:     path: /opt/webapp     state: directory     owner: webapp     group: webapp - name: create app.conf owned by webapp   ansible.builtin.file:     path: /opt/webapp/app.conf     state: touch     owner: webapp     group: webapp     mode: '0755'     access_time: preserve     modification_time: preserve

Create и Converge

У нас есть роль, которая будет обрабатывать некоторые задачи, что же дальше? Во-первых, мы можем запустить команду molecule create в директории  ./demo_role. Create использует настройки, определенные в конфигурации molecule.yml, чтобы определить драйвер и платформу. Для этого примера Molecule будет использовать следующие строки в molecule.yml.

driver:   name: docker platforms:   - name: instance     image: quay.io/centos/centos:stream8     pre_build_image: true

Он будет использовать Ansible для запуска контейнера Docker на основе образа quay.io/centos/centos:stream8, при необходимости извлекая его из реестра контейнеров.

Теперь, когда у нас есть цель и роль, давайте объединим их с molecule converge. Команда converge запускает плейбук converge.yml по отношению к целевой платформе. 

INFO     default scenario test matrix: dependency, create, prepare, converge INFO     Performing prerun with role_name_check=0... INFO     Set ANSIBLE_LIBRARY=/home/pcritchfield/.cache/ansible-compat/54dfe2/modules:/home/pcritchfield/.ansible/plugins/modules:/usr/share/ansible/plugins/modules INFO     Set ANSIBLE_COLLECTIONS_PATH=/home/pcritchfield/.cache/ansible-compat/54dfe2/collections:/home/pcritchfield/.ansible/collections:/usr/share/ansible/collections INFO     Set ANSIBLE_ROLES_PATH=/home/pcritchfield/.cache/ansible-compat/54dfe2/roles:/home/pcritchfield/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles INFO     Using /home/pcritchfield/.cache/ansible-compat/54dfe2/roles/sample.demo_role symlink to current repository in order to enable Ansible to find the role using its expected full name. INFO     Running default > dependency WARNING  Skipping, missing the requirements file. WARNING  Skipping, missing the requirements file. INFO     Running default > create WARNING  Skipping, instances already created. INFO     Running default > prepare WARNING  Skipping, prepare playbook not configured. INFO     Running default > converge INFO     Sanity checks: 'docker' PLAY [Converge] **************************************************************** TASK [Gathering Facts] ********************************************************* ok: [instance] TASK [Include sample.demo_role] ************************************************ TASK [sample.demo_role : install some packages] ******************************** changed: [instance] => (item=epel-release) changed: [instance] => (item=htop) changed: [instance] => (item=nginx) changed: [instance] => (item=git) TASK [sample.demo_role : add webapp user] ************************************** changed: [instance] TASK [sample.demo_role : create an app directory owned by webapp] ************** changed: [instance] TASK [sample.demo_role : create an app directory owned by webapp] ************** changed: [instance] PLAY RECAP ********************************************************************* instance                   : ok=5    changed=4    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Глядя на этот результат, мы можем видеть, как выполняются шаги Molecule. На линии, показывающей INFO default scenario test matrix: dependency, create, prepare, converge. Это означает, что запуск molecule create  не всегда является необходимым. Часто можно просто запустить команду converge, поскольку она уже включает create.

Написание тестов и Verify

Теперь, когда мы запустили converge и развернули контейнеры, давайте проведем несколько тестов. Используйте команду molecule verify, чтобы запустить тест по умолчанию test_default.py. Вы должны увидеть вывод, похожий на:

INFO     default scenario test matrix: verify INFO     Performing prerun with role_name_check=0... INFO     Set ANSIBLE_LIBRARY=/home/pcritchfield/.cache/ansible-compat/54dfe2/modules:/home/pcritchfield/.ansible/plugins/modules:/usr/share/ansible/plugins/modules INFO     Set ANSIBLE_COLLECTIONS_PATH=/home/pcritchfield/.cache/ansible-compat/54dfe2/collections:/home/pcritchfield/.ansible/collections:/usr/share/ansible/collections INFO     Set ANSIBLE_ROLES_PATH=/home/pcritchfield/.cache/ansible-compat/54dfe2/roles:/home/pcritchfield/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles INFO     Using /home/pcritchfield/.cache/ansible-compat/54dfe2/roles/sample.demo_role symlink to current repository in order to enable Ansible to find the role using its expected full name. INFO     Running default > verify INFO     Executing Testinfra tests found in /home/pcritchfield/Projects/ansible_molecule/roles/demo_role/molecule/default/tests/... ============================= test session starts ============================== platform linux -- Python 3.8.10, pytest-7.1.2, pluggy-1.0.0 rootdir: /home/pcritchfield plugins: testinfra-6.8.0 collected 1 item molecule/default/tests/test_default.py .                                 [100%] ============================== 1 passed in 1.50s =============================== INFO     Verifier completed successfully.

Успешно! Наш тест по умолчанию работает и подтверждает, что root является пользователем.  molecule verify также позволяет нам повторять наши тесты на существующем контейнере. Нет необходимости повторять  create и converge.

Теперь давайте напишем несколько тестов, чтобы подтвердить, что наша роль выполняет то, что должна. Мы начнем с проверки того, что установлены соответствующие пакеты и версии. Добавьте следующее к ./molecule/default/tests/test_default.py:

import pytest # Confirm that specific packages and versions are installed @pytest.mark.parametrize("name,version", [     ("epel-release", "8"),     ("htop", "3.0"),     ("nginx", "1.14"),     ("git", "2.31"), ]) def test_packages(host, name, version):     pkg = host.package(name)     assert pkg.is_installed     assert pkg.version.startswith(version)

Для тех, кто новичок в тестировании, это может показаться многовато. К счастью, это довольно просто. Мы используем pytest для параметризации сопоставления имени и версии. Затем передаем это в test_packages и проверяем имя пакета и его версию. Использование карты позволяет нам написать один тест для всех пакетов. Продолжайте, сохраните этот файл и запустите molecule verify. Вы должны увидеть, что четыре теста были успешно выполнены.

======================= test session starts ======================== platform linux -- Python 3.8.10, pytest-7.1.2, pluggy-1.0.0 rootdir: /home/pcritchfield plugins: testinfra-6.8.0 collected 4 items molecule/default/tests/test_default.py ....                              [100%] ======================== 4 passed in 2.77s ========================= INFO     Verifier completed successfully.

Далее мы можем протестировать для пользователя webapp и файла app.conf. Добавьте следующее к test_default.py:

# Test that the webapp user is available. @pytest.mark.parametrize("user,group", [     ("webapp", "webapp"), ]) def test_users(host, user, group):     usr = host.user(user)     assert usr.exists     assert usr.group == group # Test that app.conf is present and has expected permissions @pytest.mark.parametrize("filename,owner,group,mode", [     ("/opt/webapp/app.conf", "webapp", "webapp", 0o755), ]) def test_file(host, filename, owner, group, mode):     target = host.file(filename)     assert target.exists     assert target.user == owner     assert target.group == group     assert target.mode == mode

Запустите molecule verify еще раз, и теперь вы увидите шесть проходящих тестов:

======================= test session starts ======================== platform linux -- Python 3.8.10, pytest-7.1.2, pluggy-1.0.0 rootdir: /home/pcritchfield plugins: testinfra-6.8.0 collected 6 items molecule/default/tests/test_default.py ......                            [100%] ======================== 6 passed in 4.09s =========================

Наконец, чтобы всё очистить, мы можем запустить molecule destroy. Это удаляет контейнеры, которые мы развернули и подготовили с помощью create или converge. Это дает нам прекрасную возможность начать все сначала. Обеспечивая уверенность в том, что мы получим последовательные развертывания при каждом использовании нашей demo_role.

Одна команда, чтобы управлять ими всеми

Одна последняя команда Molecule, которую мы рассмотрим, это molecule test. Команда test запустит весь сценарий: создание, конвергенцию, проверку и многое другое. Давайте посмотрим, что делает тест в качестве сценария по умолчанию. Запустите команду molecule matrix test, чтобы вывести списком все этапы, которые будет проходить test:

INFO     Test matrix ---                                                                                        default:                                                                                     - dependency                                                                               - lint                                                                                     - cleanup                                                                                  - destroy                                                                                  - syntax                                                                                   - create                                                                                   - prepare                                                                                  - converge                                                                                 - idempotence                                                                              - side_effect                                                                              - verify                                                                                   - cleanup                                                                                  - destroy

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

Вы можете найти демонстрационный код в этом посте на GitHub (https://github.com/PCritchfield/ansible/tree/master/ansible_molecule_pt1)

В следующий раз

В следующей статье мы углубимся в конфигурацию molecule.yml. Мы рассмотрим тестирование нескольких операционных систем, линтинг и идемпотентность.

Видеокурс Ansible: Infrastructure as Code с практикой на стендах.


ссылка на оригинал статьи https://habr.com/ru/company/southbridge/blog/711432/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *