Contents
Molecule — это полная среда тестирования, которая помогает разрабатывать и тестировать роли Ansible, что позволяет вам сосредоточиться на содержимом роли, а не на управлении инфраструктурой тестирования. В первой части этой серии мы успешно установили, настроили и использовали Molecule для настройки новых тестовых экземпляров.
Теперь, когда экземпляры запущены, давайте начнем разработку новой роли и применим Molecule, чтобы убедиться, что она работает в соответствии со спецификациями.
Эта базовая роль развертывает веб-приложение, поддерживаемое веб-сервером Apache. Он должен поддерживать Red Hat Enterprise Linux (RHEL) 8 и Ubuntu 20.04.
Разработка роли Ansible с помощью Molecule
Molecule помогает на этапе разработки, позволяя «сводить» экземпляры с содержимым роли. Вы можете протестировать каждый шаг, не беспокоясь об управлении экземплярами и тестовой средой. Он обеспечивает быструю обратную связь, позволяя вам сосредоточиться на содержимом роли, гарантируя, что она работает на всех платформах.
В первой части этой серии мы инициализировали новую роль «mywebapp». Если вы еще не там, переключитесь в каталог ролей «mywebapp» и добавьте первую задачу, установив пакет Apache «httpd» с помощью модуля «package» Ansible. Отредактируйте файл «tasks/main.yaml» и включите эту задачу:
$ vi tasks/main.yml
---
# tasks file for mywebapp
- name: Ensure httpd installed
package:
name: "httpd"
state: present
Сохраните файл и «сведите» экземпляры, запустив «Molecule Converge». Команда converge применяет текущую версию роли ко всем работающим экземплярам контейнера. Молекула «сходится» не перезапускает экземпляры, если они уже запущены. Он пытается объединить эти экземпляры, приводя их конфигурацию в соответствие с желаемым состоянием, описанным ролью, которая в настоящее время тестируется.
$ molecule converge
... TRUNCATED OUTPUT ...
TASK [mywebapp : Ensure httpd installed] ***************************************
Saturday 27 June 2020 08:45:01 -0400 (0:00:00.060) 0:00:04.277 *********
fatal: [ubuntu]: FAILED! => {"changed": false, "msg": "No package matching 'httpd' is available"}
changed: [rhel8]
... TRUNCATED OUTPUT ...
Обратите внимание, что текущая версия хорошо работала на экземпляре RHEL8, но не работала на экземпляре Ubuntu. С помощью Molecule вы сможете быстро оценить результат своих задач на всех платформах и проверить, работает ли роль в соответствии с требованиями! Однако в этом примере задачи не удались, потому что в Ubuntu нет пакета с именем «httpd». Для этой платформы имя пакета — «apache2».
Итак, давайте изменим роль, включив в нее переменные с правильным именем пакета для каждой платформы. Начните с RHEL8, добавив файл «RedHat.yaml» в подкаталог «vars» со следующим содержимым:
$ vi vars/RedHat.yaml
---
httpd_package: httpd
Сохраните этот файл и добавьте соответствующий файл «vars/Debian.yaml» для Ubuntu:
$ vi vars/Debian.yaml
---
httpd_package: apache2
Сохраните этот файл и измените файл «tasks/main.yaml», чтобы включить эти файлы переменных в соответствии с семейством ОС, определенным Ansible через системную фактическую переменную «ansible_os_family». Мы также должны включить задачу по обновлению кеша пакетов для систем семейства «Debian», поскольку в противном случае их менеджер пакетов кэширует результаты. Наконец, мы обновляем задачу установки, чтобы использовать переменную «httpd_package», которую вы определили в файлах переменных:
$ vi tasks/main.yml
- name: Include OS-specific variables.
include_vars: "{{ ansible_os_family }}.yaml"
- name: Ensure package cache up-to-date
apt:
update_cache: yes
cache_valid_time: 3600
when: ansible_os_family == "Debian"
- name: Ensure httpd installed
package:
name: "{{ httpd_package }}"
state: present
Сохраните этот файл и снова «сведите» экземпляры, чтобы убедиться, что на этот раз все работает:
$ molecule converge
... TRUNCATED OUTPUT ...
TASK [mywebapp : Ensure httpd installed] ***************************************
Saturday 27 June 2020 08:59:13 -0400 (0:00:07.338) 0:00:12.925 *********
ok: [rhel8]
changed: [ubuntu]
... TRUNCATED OUTPUT ...
Поскольку пакет уже был установлен в экземпляре RHEL8, Ansible вернул статус «ОК» и не внес никаких изменений. На этот раз он правильно установил пакет в экземпляре Ubuntu.
Мы установили пакет, но проблема с именами также существует с самой службой: они называются по-разному в RHEL и Ubuntu. Итак, мы добавляем переменные имени службы в плейбуки и файлы переменных. Начните с RHEL8:
$ vi vars/RedHat.yaml
---
httpd_package: httpd
httpd_service: httpd
Сохраните этот файл, а затем отредактируйте файл «vars/Debian.yaml» для Ubuntu:
$ vi vars/Debian.yaml
---
httpd_package: apache2
httpd_service: apache2
Сохраните файл и добавьте новую задачу в конец файла «tasks/main.yml»:
$ vi tasks/main.yml
- name: Ensure httpd svc started
service:
name: "{{ httpd_service }}"
state: started
enabled: yes
Сохраните файл и снова «сведите» экземпляры, чтобы запустить службу Apache httpd:
$ molecule converge
... TRUNCATED OUTPUT ...
TASK [mywebapp : Ensure httpd svc started] *************************************
Saturday 27 June 2020 09:34:38 -0400 (0:00:06.776) 0:00:17.233 *********
changed: [ubuntu]
changed: [rhel8]
... TRUNCATED OUTPUT ...
Давайте добавим последнюю задачу по созданию контента для веб-приложения. Для каждой платформы требуются файлы HTML, принадлежащие разным группам. Добавьте новые переменные в каждый файл переменных, чтобы определить имя группы:
$ vi vars/RedHat.yaml
---
httpd_package: httpd
httpd_service: httpd
httpd_group: apache
Сохраните этот файл, затем отредактируйте файл «vars/Debian.yaml» для Ubuntu:
$ vi vars/Debian.yaml
---
httpd_package: apache2
httpd_service: apache2
httpd_group: www-data
Сохраните файл и добавьте новую задачу в конец файла «tasks/main.yml»:
$ vi tasks/main.yml
- name: Ensure HTML Index
copy:
dest: /var/www/html/index.html
mode: 0644
owner: root
group: "{{ httpd_group }}"
content: "{{ web_content }}"
Эта задача позволяет пользователю роли указать содержимое с помощью переменной «web_content» при вызове роли. Добавьте к этой переменной значение по умолчанию, если пользователь его не укажет:
$ vi defaults/main.yml
---
# defaults file for mywebapp
web_content: There's a web server here
Сохраните этот файл и «сведите» экземпляры еще раз, чтобы добавить содержимое:
$ molecule converge__
... TRUNCATED OUTPUT ...
TASK [mywebapp : Ensure HTML Index] ********************************************
Saturday 27 June 2020 09:50:11 -0400 (0:00:03.261) 0:00:17.753 *********
changed: [rhel8]
changed: [ubuntu]
... TRUNCATED OUTPUT ...
В это время оба экземпляра сходятся. Вручную проверьте, что роль работает, используя команду molecule login для входа в один из экземпляров и запуская команду «curl» для получения содержимого:
$ molecule login -h rhel8
[root@2ce0a0ea8692 /]# curl http://localhost
There's a web server here
[root@2ce0a0ea8692 /]# exit
Вы использовали Molecule, чтобы помочь в разработке роли, убедившись, что она правильно работает на нескольких платформах на каждом этапе пути.
Далее давайте автоматизируем процесс проверки.
Проверка роли с помощью Molecule
Molecule не только помогает вам конвергировать экземпляр для помощи в разработке роли, но и автоматизирует процесс тестирования, выполняя задачу проверки. Чтобы проверить результаты вашего плейбука, Molecule может использовать либо фреймворк «testinfra», либо сам Ansible.
Давайте воспользуемся Ansible Playbook, чтобы проверить результаты этой новой роли. По умолчанию Molecule предоставляет в качестве отправной точки базовый верификатор «Molecule/default/verify.yml». Этот учебник содержит базовую необходимую структуру, но не выполняет никакой полезной проверки. Обновите этот плейбук, чтобы проверить результат этой роли, используя модуль «uri» Ansible для получения контента с работающего веб-сервера и модуль «assert», чтобы убедиться, что это правильный контент:
$ vi molecule/default/verify.yml
---
# This is an example playbook to execute Ansible tests.
- name: Verify
hosts: all
vars:
expected_content: "There's a web server here"
tasks:
- name: Get index.html
uri:
url: http://localhost
return_content: yes
register: this
failed_when: "expected_content not in this.content"
- name: Ensure content type is text/html
assert:
that:
- "'text/html' in this.content_type"
- name: Debug results
debug:
var: this.content
Сохраните и закройте этот файл. Проверьте результаты, запустив «Molecule Verify»:
$ molecule verify
... TRUNCATED OUTPUT ...
TASK [Ensure content type is text/html] ****************************************
Saturday 27 June 2020 10:03:18 -0400 (0:00:03.131) 0:00:07.255 *********
ok: [rhel8] => {
"changed": false,
"msg": "All assertions passed"
}
ok: [ubuntu] => {
"changed": false,
"msg": "All assertions passed"
}
... TRUNCATED OUTPUT ...
Verifier completed successfully.
Molecule запускает playbook верификатора для всех экземпляров, гарантируя соответствие результатов ожидаемым значениям.Внутренний сборник игр
Вы можете изменить значения по умолчанию для теста, отредактировав плейбук конвергенции, чтобы обновить переменную «web_content»:
$ vi molecule/default/converge.yml
---
- name: Converge
hosts: all
tasks:
- name: "Include mywebapp"
include_role:
name: "mywebapp"
vars:
web_content: "New content for testing only"
Затем обновите переменную «expected_content» в плейбуке верификатора:
$ vi molecule/default/verify.yml
---
# This is an example playbook to execute Ansible tests.
- name: Verify
hosts: all
vars:
expected_content: "New content for testing only"
tasks:
Соедините экземпляры еще раз, чтобы обновить содержимое веб-сервера, затем проверьте результаты:
$ molecule converge
... TRUNCATED OUTPUT ...
TASK [mywebapp : Ensure HTML Index] ********************************************
Saturday 27 June 2020 10:09:34 -0400 (0:00:03.331) 0:00:19.607 *********
changed: [rhel8]
changed: [ubuntu]
... TRUNCATED OUTPUT ...
$ molecule verify
... TRUNCATED OUTPUT ...
TASK [Debug results] ***********************************************************
Saturday 27 June 2020 10:10:15 -0400 (0:00:00.299) 0:00:10.142 *********
ok: [rhel8] => {
"this.content": "New content for testing only"
}
ok: [ubuntu] => {
"this.content": "New content for testing only"
}
... TRUNCATED OUTPUT ...
Verifier completed successfully.
Используя верификатор, вы можете определить playbook для выполнения проверок и убедиться, что роль дает требуемые результаты.
На последнем этапе давайте объединим все это с помощью автоматических тестов.
Автоматизация полного рабочего процесса тестирования
Теперь, когда все части собраны вместе, автоматизируйте весь рабочий процесс процесса тестирования с помощью команды «Molecule Test».
В отличие от «молекулярной конвергенции», которая помогала в разработке роли, цель «молекулярного теста» — предоставить автоматизированную и воспроизводимую среду, чтобы гарантировать, что роль работает в соответствии с ее спецификациями. Поэтому процесс тестирования уничтожает и воссоздает экземпляры для каждого теста.
По умолчанию «тест молекулы» выполняет следующие шаги в следующем порядке:
- Установите необходимые зависимости
- Линт проекта
- Уничтожить существующие экземпляры
- Запустить проверку синтаксиса
- Создать экземпляры
- Подготовить экземпляры (если требуется)
- Конвергенция экземпляров путем применения ролевых задач
- Проверить роль на идемпотентность
- Проверьте результаты, используя определенный верификатор
- Уничтожить экземпляры
Вы можете изменить эти шаги, добавив словарь «test_sequence» с необходимыми шагами в файл конфигурации Molecule. Для получения дополнительной информации обратитесь к официальной документации .
Выполните тестовый сценарий:
$ molecule test
... TRUNCATED OUTPUT ...
--> Test matrix
└── default
├── dependency
├── lint
├── cleanup
├── destroy
├── syntax
├── create
├── prepare
├── converge
├── idempotence
├── side_effect
├── verify
├── cleanup
└── destroy
--> Scenario: 'default'
... TRUNCATED OUTPUT ...
Если тестовый рабочий процесс завершается ошибкой в любой момент, команда возвращает код состояния, отличный от нуля. Вы можете использовать этот код возврата для автоматизации процесса или интеграции Molecule с рабочими процессами CI/CD.
Вывод
Теперь, когда вы успешно применили Molecule для разработки и тестирования роли, которая хорошо написана и надежно работает в различных средах, вы можете интегрировать ее в свой цикл разработки, чтобы последовательно создавать роли высокого стандарта, не беспокоясь об инфраструктуре тестирования.
Molecule помогает в процессе разработки роли, обеспечивая постоянную обратную связь, которая гарантирует, что ваша роль работает так, как задумано на каждом этапе пути.
Для более сложных сценариев Molecule поддерживает дополнительные драйверы, позволяющие тестировать роли с различными платформами, виртуализацией и облачными провайдерами.
Наконец, вы можете интегрировать Molecule с рабочими процессами CI/CD, чтобы автоматизировать весь процесс тестирования для ваших ролей Ansible.