Как ограничить набор хостов в Ansible
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Ограничение набора хостов в Ansible
Ограничение набора хостов — ключевая возможность Ansible для целевого выполнения задач на конкретных серверах. Это позволяет избежать случайных изменений на всех узлах инвентаря и повышает безопасность. Методы можно разделить на статическое (через инвентарь) и динамическое (через параметры командной строки, теги, факты) ограничение.
Основные методы ограничения
1. Использование параметров командной строки
Самый простой способ — передать лимитирующий паттерн при запуске playbook.
# Выполнить playbook только на хостах из группы webservers
ansible-playbook site.yml --limit webservers
# Ограничение по нескольким хостам
ansible-playbook deploy.yml --limit 'web1,web2'
# Использование паттернов (поддерживаются wildcards)
ansible-playbook config.yml --limit '*.example.com'
# Исключение хостов через "!"
ansible-playbook update.yml --limit 'all:!db_servers'
2. Определение групп в инвентаре
Структурированный инвентарь — основа точного таргетирования. Я использую динамический инвентарь (через скрипты, AWS, Terraform) с четкой группировкой.
# inventory/production.ini
[webservers]
web1.example.com ansible_user=deploy
web2.example.com ansible_user=deploy
[dbservers]
db-primary.example.com ansible_user=admin
db-replica.example.com ansible_user=admin
[production:children]
webservers
dbservers
3. Использование тегов (tags)
Теги позволяют ограничивать выполнение конкретных задач, а не хостов, но косвенно влияют на таргетирование.
- name: Deploy application
hosts: webservers
tasks:
- name: Update web servers
apt:
name: nginx
state: latest
tags:
- update
- webserver-only
# Запуск только задач с определенными тегами
ansible-playbook playbook.yml --tags "update"
4. Динамическое ограничение через факты
Запуск на хостах, соответствующих определенным условиям.
- name: Update only Ubuntu 20.04 servers
hosts: all
tasks:
- name: Apply security patches
apt:
update_cache: yes
upgrade: dist
when: ansible_facts['distribution'] == 'Ubuntu' and ansible_facts['distribution_version'] == '20.04'
5. Использование переменных для ограничения
Можно задавать ограничивающие группы через переменные.
# playbook.yml
- name: Configure load balancers
hosts: "{{ target_hosts | default('load_balancers') }}"
tasks: [...]
# Переопределение группы через переменную
ansible-playbook playbook.yml -e "target_hosts=eu_servers"
Продвинутые техники
6. Ограничение по этапам выполнения (rolling updates)
Для обновления без простоя использую сериализацию и откаты.
- name: Rolling restart of web servers
hosts: webservers
serial: 2 # Обновлять по 2 сервера одновременно
tasks:
- name: Restart service
service:
name: nginx
state: restarted
7. Динамический инвентарь с фильтрацией
В облачных средах фильтрую хосты по тегам через динамический инвентарь.
# Пример с AWS EC2 инвентарем
ansible-playbook setup.yml --limit 'tag_Environment_Prod:&tag_Role_Web'
8. Использование inventory_dir и групп-шаблонов
Создаю шаблонные группы для сложных сценариев.
# inventory/host_vars/web1.yml
stage: production
region: eu-west-1
# inventory/group_vars/eu_servers.yml
ansible_ssh_private_key_file: ~/.ssh/eu_key.pem
Рекомендации по безопасности
- Используйте
--checkперед выполнением на production:ansible-playbook playbook.yml --limit prod_servers --check - Разделяйте инвентари по окружениям (dev/stage/prod)
- Применяйте vault для шифрования чувствительных данных:
ansible-vault encrypt inventory/prod/group_vars/secrets.yml - Логируйте выполнение с ограничением:
ansible-playbook ... --limit webservers | tee /var/log/ansible/deploy.log
Пример комбинированного подхода
# Запуск с несколькими ограничениями
ansible-playbook main.yml \
--limit 'webservers:&eu_region' \
--tags "deploy,config" \
--extra-vars "deploy_version=2.4.1" \
--forks 5 \
--diff
Ключевой принцип: всегда явно указывайте целевые хосты через лимиты или хорошо структурированные группы. Это предотвращает случайные изменения на непредназначенных серверах и делает выполнение более предсказуемым. В production-средах я дополнительно использую проверки pre-flight (через assert) и двухэтапное подтверждение для критичных операций.