The Inside Playbook

by moiseevrus

Разработка и тестирование ролей 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.

You may also like

Leave a Comment