Ответ
В инфраструктурных проектах я постоянно работаю с целевым выполнением плейбуков. Вот основные практики, которые использую.
1. Определение целей в инвентари (inventory) — основной метод.
Группирую хосты в inventory/production.ini:
[webservers]
web01.example.com ansible_user=deploy
web02.example.com
[databases]
db01.example.com
[all:vars]
ansible_python_interpreter=/usr/bin/python3
Затем в плейбуке указываю группу:
- name: Configure Nginx on web servers
hosts: webservers # Выполнится ТОЛЬКО на этой группе
tasks: ...
2. Динамическое ограничение с помощью --limit:
Запускаю плейбук для подмножества хостов из группы, например, для одного сервера из webservers:
ansible-playbook site.yml --limit "web01.example.com"
# Или по шаблону:
ansible-playbook site.yml --limit "*.example.com"
3. Использование тегов (tags):
Позволяет выполнять не весь плейбук, а только задачи с определенными тегами на любой группе хостов.
- name: Deploy application
hosts: all
tasks:
- name: Copy configs
copy: src=app.conf dest=/etc/
tags: config
- name: Restart service
systemd: name=app state=restarted
tags: deploy
Запуск: ansible-playbook deploy.yml --tags "deploy" --limit "webservers"
4. Динамические группы и переменные извне:
Часто в CI/CD нужно передать целевые хосты динамически. Использую переменную hosts:
- name: Run ad-hoc update
hosts: "{{ target_hosts | default('all') }}"
tasks: ...
Запуск с передачей хостов через переменную окружения или аргумент:
export TARGET_HOSTS="web01,db01"
ansible-playbook update.yml -e "target_hosts=$TARGET_HOSTS"
Для сложной логики (например, выполнить задачу только если сервер в определенном дата-центре) использую условие when с фактами Ansible: when: ansible_facts['datacenter'] == 'ams1'.