Production-ready гайд по созданию полноценного Ansible-репозитория с ролями
Представлен production-ready гайд по созданию полноценного Ansible-репозитория с ролями. Структура соответствует современным best practices (Ansible 9–10+, 2024–2026), учитывает безопасность, тестируемость и масштабируемость.
1. Рекомендуемая структура репозитория
ansible-infra/
├── ansible.cfg
├── inventory/
│ ├── production/
│ │ ├── hosts.yml
│ │ └── group_vars/
│ └── staging/
│ ├── hosts.yml
│ └── group_vars/
├── group_vars/ # Фоллбэк для общих переменных
│ ├── all.yml
│ └── webservers.yml
├── host_vars/ # Специфичные для хостов (редко)
├── roles/
│ ├── common/
│ ├── nginx/
│ └── app_deploy/
├── playbooks/
│ ├── site.yml
│ └── deploy_app.yml
├── collections/ # Опционально, если используете Collections
├── requirements.yml
├── .ansible-vault/ # Для хранения ключей Vault в CI/CD
├── .github/workflows/ # или .gitlab-ci.yml
├── README.md
└── .gitignore
Ключевые файлы:
ansible.cfg– централизованная конфигурация.inventory/– разделение по окружениям.roles/– изолированные, переиспользуемые компоненты.playbooks/– оркестрация ролей под конкретные задачи.requirements.yml– зависимости (роли/коллекции).
2. Внутренняя структура роли
Каждая роль должна следовать стандарту:
roles/nginx/
├── defaults/main.yml # Переменные с наименьшим приоритетом (можно переопределять)
├── vars/main.yml # Внутренние переменные роли (не переопределяются извне)
├── tasks/main.yml # Основная логика
├── handlers/main.yml # Реагируют на notify
├── templates/ # Jinja2-шаблоны
├── files/ # Статические файлы
├── meta/main.yml # Зависимости, автор, платформы
└── README.md # Документация роли
Пример roles/nginx/tasks/main.yml
---
- name: Установить nginx
ansible.builtin.apt:
name: nginx
state: present
update_cache: true
when: ansible_os_family == "Debian"
- name: Развернуть конфигурацию
ansible.builtin.template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: "0644"
validate: nginx -t -f %s
notify: Restart nginx
- name: Убедиться, что nginx запущен
ansible.builtin.service:
name: nginx
state: started
enabled: true
Пример roles/nginx/handlers/main.yml
---
- name: Restart nginx
ansible.builtin.service:
name: nginx
state: restarted
Пример roles/nginx/defaults/main.yml
---
nginx_worker_processes: auto
nginx_worker_connections: 1024
nginx_site_enabled: true
3. Управление переменными (Precedence)
Ansible использует строгую иерархию. Кратко (от высшего к низшему приоритету):
extra_vars(-e)host_vars/иgroup_vars/из инвентаряroles/*/vars/main.ymlroles/*/defaults/main.yml
Рекомендации:
- В ролях используйте
defaults/для настраиваемых параметров. - В
group_vars/храните окруженческие настройки (staging vs production). - Избегайте хардкода в
tasks/. Всё выносите в переменные. - Используйте
ansible.builtin.set_factтолько когда значение вычисляется динамически во время выполнения.
4. Инвентаризация (Inventory)
Современный формат: YAML.
inventory/staging/hosts.yml
---
all:
children:
webservers:
hosts:
web01.staging.example.com:
web02.staging.example.com:
databases:
hosts:
db01.staging.example.com:
vars:
ansible_user: dbadmin
inventory/staging/group_vars/webservers.yml
---
env: staging
nginx_worker_connections: 512
app_branch: develop
Примечание:
- Не храните
ansible_connection,ansible_userвhosts.ymlнапрямую, если они общие. Вынесите вgroup_vars/all.yml.
5. Playbooks и запуск
playbooks/site.yml – точка входа:
---
- name: Настройка базовых серверов
hosts: all
become: true
roles:
- common
- name: Развертывание веб-серверов
hosts: webservers
become: true
roles:
- nginx
- app_deploy
Запуск:
# Проверка синтаксиса
ansible-playbook -i inventory/staging/hosts.yml playbooks/site.yml --syntax-check
# Dry-run
ansible-playbook -i inventory/staging/hosts.yml playbooks/site.yml --check --diff
# Реальный запуск
ansible-playbook -i inventory/staging/hosts.yml playbooks/site.yml --limit web01.staging.example.com
Используйте --tags и --skip-tags для выборочного выполнения.
6. Зависимости и Ansible Galaxy
requirements.yml
---
roles:
- name: geerlingguy.docker
version: 5.1.0
- name: myorg.internal_role
src: git+https://git.example.com/ansible/internal_role.git
version: v2.3.1
collections:
- name: community.general
version: ">=8.0.0"
- name: ansible.posix
Установка:
ansible-galaxy install -r requirements.yml --roles-path roles --force
ansible-galaxy collection install -r requirements.yml
Примечание:
- В enterprise-средах используйте приватный Galaxy-сервер или Git-репозитории с проверкой подписей.
7. Тестирование и линтинг
Статический анализ:
ansible-lint playbooks/ roles/
yamllint inventory/ group_vars/ host_vars/ roles/*/defaults/
Molecule (тестирование ролей):
pip install molecule[docker] ansible-lint yamllint
molecule init scenario -r roles/nginx
roles/nginx/molecule/default/molecule.yml (фрагмент)
---
dependency:
name: galaxy
driver:
name: docker
platforms:
- name: instance
image: ubuntu:22.04
privileged: true
provisioner:
name: ansible
verifier:
name: ansible
Запуск тестов:
cd roles/nginx && molecule test
8. Секреты и Ansible Vault
Никогда не храните пароли/ключи в plaintext.
# Создание зашифрованного файла
ansible-vault encrypt group_vars/production/vault.yml
# Редактирование
ansible-vault edit group_vars/production/vault.yml
# Запуск с паролем
ansible-playbook -i inventory/production/hosts.yml playbooks/site.yml --ask-vault-pass
Best Practices:
- В CI/CD используйте
ANSIBLE_VAULT_PASSWORD_FILEили переменные среды. - Для крупных проектов рассмотрите интеграцию с HashiCorp Vault, AWS Secrets Manager или Azure Key Vault через плагины
community.hashi_vault. - Регулярно ротируйте ключи:
ansible-vault rekey --new-vault-password-file new_pass.txt vault.yml
9. CI/CD интеграция (GitHub Actions пример)
.github/workflows/ansible.yml
name: Ansible CI
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install dependencies
run: pip install ansible ansible-lint yamllint
- name: Lint
run: |
yamllint inventory/ group_vars/ roles/
ansible-lint playbooks/ roles/
- name: Syntax check
run: ansible-playbook -i inventory/staging/hosts.yml playbooks/site.yml --syntax-check
deploy-staging:
needs: lint
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup SSH
run: |
mkdir -p ~/.ssh
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan staging.example.com >> ~/.ssh/known_hosts
- name: Deploy
run: |
ansible-playbook -i inventory/staging/hosts.yml playbooks/site.yml \
--ask-vault-pass
env:
ANSIBLE_VAULT_PASSWORD_FILE: ${{ secrets.VAULT_PASSWORD }}
10. Документация и поддержка
README.md должен содержать:
- Краткое описание инфраструктуры
- Требования (Ansible version, Python, зависимости)
- Как настроить окружение
- Команды для запуска
- Структура переменных
- Как добавить новую роль
- Контакты/ответственные
В каждой роли добавляйте:
Role: nginx
Описание
Устанавливает и настраивает Nginx с поддержкой TLS и reverse proxy.
Переменные
| Переменная | Default | Описание |
|---|---|---|
nginx_worker_processes |
auto |
Количество worker процессов |
Пример использования
roles:
- role: nginx
nginx_worker_connections: 2048
nginx_site_enabled: true
Чек-лист перед коммитом
- [ ]
ansible-lintпроходит без ошибок - [ ]
yamllintне ругается на инвентарь и переменные - [ ] Все секреты в Vault или внешнем хранилище
- [ ] Роли изолированы, нет кросс-зависимостей без
meta/main.yml - [ ]
defaults/содержит все настраиваемые параметры - [ ] CI проверяет синтаксис и линтит на PR
- [ ] Документация обновлена
Полезные команды
| Задача | Команда |
|---|---|
| Показать precedence | ansible-inventory -i inventory/ --list |
| Проверить fact'ы хоста | ansible <host> -m ansible.builtin.setup |
| Пересоздать кэш фактов | ansible all -m ansible.builtin.setup -a "cacheable=true" |
| Просмотреть зависимости роли | ansible-galaxy role list |
| Проверить валидность шаблона | ansible-playbook --check --diff -i ... |