The Inside Playbook

Разработка и тестирование ролей Ansible с помощью Molecule и Podman — часть 2

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

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

По умолчанию «тест молекулы» выполняет следующие шаги в следующем порядке:

  1. Установите необходимые зависимости
  2. Линт проекта
  3. Уничтожить существующие экземпляры
  4. Запустить проверку синтаксиса
  5. Создать экземпляры
  6. Подготовить экземпляры (если требуется)
  7. Конвергенция экземпляров путем применения ролевых задач
  8. Проверить роль на идемпотентность
  9. Проверьте результаты, используя определенный верификатор
  10. Уничтожить экземпляры

Вы можете изменить эти шаги, добавив словарь «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.

Перейти к верхней панели