← Назад к вопросам

Как разрабатывал роли

1.2 Junior🔥 191 комментариев
#Ansible и управление конфигурацией#Soft skills и карьера

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Мой подход к разработке ролей Ansible

Мой процесс разработки ролей Ansible сформировался за 10+ лет практики и эволюционировал от простых скриптов до полноценных enterprise-решений. Вот как я это делаю:

Фундаментальные принципы

Идемпотентность — мой главный приоритет. Каждая задача должна безопасно выполняться многократно без побочных эффектов. Этого достигаю через:

  • Проверку состояния перед изменением (модули stat, command с register)
  • Использование встроенных модулей вместо shell/command
  • Правильную обработку changed_when и failed_when

Параметризация — роли должны быть универсальными. Все специфичные значения выношу в переменные с разумными значениями по умолчанию:

# defaults/main.yml
nginx_port: 80
nginx_worker_processes: "{{ ansible_processor_cores }}"
nginx_enable_ssl: false

# vars/main.yml  
nginx_conf_path: /etc/nginx/nginx.conf
nginx_service_name: nginx

Структура роли

Я придерживаюсь расширенной структуры, которая включает:

role_name/
├── defaults/           # Значения по умолчанию (низший приоритет)
├── vars/              # Переменные роли (высокий приоритет)
├── tasks/             # Основные задачи
│   ├── main.yml
│   ├── install.yml
│   └── configure.yml
├── handlers/          # Обработчики
├── templates/         |Шаблоны Jinja2
├── files/             |Статические файлы
├── meta/              |Зависимости и информация
├── tests/             # Интеграционные тесты
│   ├── inventory
│   └── test.yml
└── molecule/          # Molecule тестирование

Ключевые практики в разработке

1. Модульность задач

Разбиваю задачи на логические файлы для улучшения читаемости:

# tasks/main.yml
- name: Include OS-specific variables
  include_vars: "{{ item }}"
  with_first_found:
    - "{{ ansible_distribution }}_{{ ansible_distribution_major_version }}.yml"
    - "{{ ansible_distribution }}.yml"
    - "{{ ansible_os_family }}.yml"

- import_tasks: prerequisites.yml
- import_tasks: install.yml
- import_tasks: configure.yml
- import_tasks: service.yml

2. Обработка различных ОС и версий

Создаю матрицу поддержки через переменные:

# vars/RedHat.yml
nginx_package: nginx
nginx_conf_dir: /etc/nginx/conf.d
nginx_log_dir: /var/log/nginx

# vars/Debian.yml  
nginx_package: nginx-light
nginx_conf_dir: /etc/nginx/sites-available
nginx_log_dir: /var/log/nginx

3. Безопасная работа с секретами

Для чувствительных данных использую Ansible Vault или внешние системы:

# Использование vault-переменных
nginx_ssl_key: "{{ vault_ssl_private_key }}"
nginx_ssl_cert: "{{ vault_ssl_certificate }}"

# Или динамическое получение секретов
- name: Get database password from HashiCorp Vault
  ansible.builtin.uri:
    url: "{{ vault_addr }}/v1/secret/data/nginx"
    method: GET
    headers:
      X-Vault-Token: "{{ vault_token }}"
  register: vault_secret
  no_log: true

4. Теги и кондишены для гибкости

Позволяют тонко управлять выполнением:

- name: Install NGINX
  package:
    name: "{{ nginx_package }}"
    state: present
  tags:
    - install
    - nginx-install

- name: Configure SSL (only if enabled)
  template:
    src: ssl.conf.j2
    dest: "{{ nginx_conf_dir }}/ssl.conf"
  when: nginx_enable_ssl
  notify: restart nginx
  tags:
    - ssl
    - configuration

Процесс разработки

1. Планирование и проектирование

  • Определяю scope и требования
  • Проектирую интерфейс роли (переменные, теги, handlers)
  • Создаю документацию в README.md сразу

2. Итеративная разработка с тестированием

Использую Molecule для полного цикла тестирования:

# molecule/default/molecule.yml
dependency:
  name: galaxy
driver:
  name: docker
platforms:
  - name: ubuntu-2004
    image: geerlingguy/docker-ubuntu2004-ansible
  - name: centos-8
    image: geerlingguy/docker-centos8-ansible
provisioner:
  name: ansible
verifier:
  name: ansible

3. Документация и примеры

Каждая роль включает:

  • README с примерами использования
  • переменные с описанием
  • примеры playbook
  • требования и зависимости

4. Интеграция в CI/CD

Автоматизирую проверки через GitLab CI/GitHub Actions:

# .gitlab-ci.yml
stages:
  - test
  - release

ansible-lint:
  stage: test
  script:
    - ansible-lint
    
molecule-test:
  stage: test
  script:
    - molecule test --all
    
galaxy-publish:
  stage: release
  script:
    - ansible-galaxy role import
  only:
    - tags

Эволюция подходов

Раньше я создавал монолитные роли, но со временем перешел к:

  • Микроролям для повторного использования
  • Коллекциям для группировки связанных ролей
  • Полиморфным ролям с динамическим включением задач
  • Ролям-оберткам для существующих ролей из Ansible Galaxy

Пример роли-обертки для расширения функциональности:

# tasks/main.yml
- name: Import community role
  import_role:
    name: geerlingguy.nginx
  
- name: Add custom SSL configuration
  template:
    src: custom_ssl.conf.j2
    dest: /etc/nginx/ssl/custom.conf
  when: enable_custom_ssl

Критерии качества

Готовая роль должна:

  1. Иметь 100% идемпотентность при повторных запусках
  2. Поддерживать минимум 2 основные ОС
  3. Иметь полное покрытие тестами
  4. Содержать clear error messages
  5. Быть документированной с working examples
  6. Следовать Ansible best practices и community guidelines
  7. Иметь логичную систему тегов
  8. Поддерживать check mode (--check)

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