Урок 4-5: Ad-Hoc команды и Playbooks
Часть 1: Ad-Hoc команды
Что такое Ad-Hoc?
Ad-Hoc команды — это однократные команды без использования playbook файлов. Используются для быстрых операций.
Синтаксис
ansible <hosts> -i <inventory> -m <module> -a '<arguments>'
# Пример:
ansible all -i inventory.ini -m ping
ansible webservers -i inventory.ini -m shell -a 'whoami'
Основные Ad-Hoc команды
Проверка состояния
# Ping (проверить доступность)
ansible all -i inventory.ini -m ping
# Получить информацию о хосте
ansible web1 -i inventory.ini -m setup
# Посмотреть определенный fact
ansible all -i inventory.ini -m debug -a "msg={{ ansible_os_family }}"
Выполнение команд
# Выполнить shell команду
ansible all -i inventory.ini -m shell -a 'df -h'
ansible all -i inventory.ini -m shell -a 'ps aux | grep nginx'
# Выполнить command (безопаснее, чем shell)
ansible all -i inventory.ini -m command -a 'whoami'
# Выполнить с sudo
ansible all -i inventory.ini -b -m shell -a 'apt update'
Управление файлами
# Скопировать файл
ansible all -i inventory.ini -m copy -a 'src=local.txt dest=/tmp/remote.txt'
# Скопировать с содержимым
ansible all -i inventory.ini -m copy -a 'content="test" dest=/tmp/test.txt'
# Удалить файл
ansible all -i inventory.ini -m file -a 'path=/tmp/test.txt state=absent'
# Создать директорию
ansible all -i inventory.ini -m file -a 'path=/tmp/mydir state=directory'
# Изменить права
ansible all -i inventory.ini -m file -a 'path=/tmp/test.txt mode=0644'
Управление пакетами
# Установить пакет (Debian/Ubuntu)
ansible all -i inventory.ini -m apt -a 'name=nginx state=present'
# Установить пакет (CentOS/RHEL)
ansible all -i inventory.ini -m yum -a 'name=nginx state=present'
# Удалить пакет
ansible all -i inventory.ini -m apt -a 'name=nginx state=absent'
# Обновить все пакеты
ansible all -i inventory.ini -m apt -a 'upgrade=dist'
Управление сервисами
# Запустить сервис
ansible all -i inventory.ini -m service -a 'name=nginx state=started'
# Остановить сервис
ansible all -i inventory.ini -m service -a 'name=nginx state=stopped'
# Перезагрузить сервис
ansible all -i inventory.ini -m service -a 'name=nginx state=restarted'
# Включить автозапуск
ansible all -i inventory.ini -m service -a 'name=nginx enabled=yes'
Управление пользователями
# Создать пользователя
ansible all -i inventory.ini -m user -a 'name=john'
# Добавить пользователя в группу
ansible all -i inventory.ini -m user -a 'name=john groups=sudo'
# Удалить пользователя
ansible all -i inventory.ini -m user -a 'name=john state=absent'
# Установить пароль
ansible all -i inventory.ini -m user -a 'name=john password="{{ password | password_hash }}"'
Полезные флаги
# Dry-run (не применять, только показать что будет)
ansible all -i inventory.ini -m apt -a 'name=nginx' --check
# Очень подробный вывод
ansible all -i inventory.ini -m ping -vvv
# Использовать sudo
ansible all -i inventory.ini -b -m shell -a 'whoami'
# Параллельное выполнение (по умолчанию 5)
ansible all -i inventory.ini -f 20 -m ping
# Использовать специфичного пользователя
ansible all -i inventory.ini -u ubuntu -m ping
# Использовать специфичный SSH ключ
ansible all -i inventory.ini --private-key=/path/to/key -m ping
Часть 2: Первые Playbooks
Что такое Playbook?
Playbook — это файл с инструкциями для Ansible на языке YAML. Содержит задачи которые нужно выполнить.
Структура Playbook
---
- name: Описание playbook
hosts: webservers # На какие хосты применять
become: yes # Использовать sudo
vars:
var_name: value # Переменные
tasks:
- name: Описание задачи
module_name: # Модуль Ansible
argument1: value1
argument2: value2
handlers:
- name: Перезагрузить сервис
service:
name: nginx
state: restarted
post_tasks:
- name: Финальная задача
debug:
msg: "Playbook завершен"
Простой Playbook: Установка Nginx
Файл: install-nginx.yml
---
- name: Установить Nginx
hosts: webservers
become: yes
tasks:
- name: Обновить кэш пакетов
apt:
update_cache: yes
- name: Установить Nginx
apt:
name: nginx
state: present
- name: Запустить Nginx
service:
name: nginx
state: started
enabled: yes
- name: Проверить Nginx работает
shell: curl -s http://localhost/ | head -5
register: result
- name: Показать результат
debug:
var: result.stdout_lines
Запуск Playbook
# Базовый запуск
ansible-playbook install-nginx.yml -i inventory.ini
# Сухой запуск (не применять)
ansible-playbook install-nginx.yml -i inventory.ini --check
# Verbose вывод
ansible-playbook install-nginx.yml -i inventory.ini -v
ansible-playbook install-nginx.yml -i inventory.ini -vv
# Запуск только на определенной группе
ansible-playbook install-nginx.yml -i inventory.ini -l webservers
# Запуск только определенной задачи
ansible-playbook install-nginx.yml -i inventory.ini --start-at-task "Установить Nginx"
# Паралельное выполнение
ansible-playbook install-nginx.yml -i inventory.ini -f 10
Playbook с переменными
Файл: deploy-app.yml
---
- name: Развернуть приложение
hosts: webservers
become: yes
vars:
app_name: myapp
app_user: appuser
app_dir: /opt/myapp
app_port: 8080
tasks:
- name: Создать пользователя {{ app_user }}
user:
name: "{{ app_user }}"
state: present
- name: Создать директорию {{ app_dir }}
file:
path: "{{ app_dir }}"
state: directory
owner: "{{ app_user }}"
mode: '0755'
- name: Скопировать файлы приложения
copy:
src: app/
dest: "{{ app_dir }}"
owner: "{{ app_user }}"
- name: Установить зависимости
shell: cd {{ app_dir }} && pip install -r requirements.txt
- name: Запустить приложение на порту {{ app_port }}
shell: cd {{ app_dir }} && nohup python app.py --port {{ app_port }} &
Playbook с циклами
---
- name: Установить пакеты
hosts: all
become: yes
tasks:
- name: Установить необходимые пакеты
apt:
name: "{{ item }}"
state: present
loop:
- curl
- wget
- git
- build-essential
- python3-dev
Playbook с условиями
---
- name: Условное выполнение
hosts: all
tasks:
- name: Получить версию ОС
setup:
filter: ansible_os_family
- name: Установить для Debian/Ubuntu
apt:
name: nginx
state: present
when: ansible_os_family == "Debian"
- name: Установить для CentOS/RHEL
yum:
name: nginx
state: present
when: ansible_os_family == "RedHat"
Playbook с Handlers
Важно: Handlers выполняются только если было изменение!
---
- name: Nginx конфигурация с handlers
hosts: webservers
become: yes
tasks:
- name: Скопировать Nginx конфиг
copy:
src: nginx.conf
dest: /etc/nginx/nginx.conf
notify: Перезагрузить Nginx
- name: Создать HTML файл
copy:
content: "<h1>Welcome</h1>"
dest: /var/www/html/index.html
notify: Перезагрузить Nginx
handlers:
- name: Перезагрузить Nginx
service:
name: nginx
state: restarted
Playbook с Register
---
- name: Проверка результатов
hosts: all
tasks:
- name: Выполнить команду
shell: df -h / | tail -1
register: disk_usage
- name: Проверить свободное место
debug:
msg: "Свободное место: {{ disk_usage.stdout }}"
- name: Показать вывод
debug:
var: disk_usage
Часть 3: Лучшие практики Playbook
Структура проекта
playbooks/
├── site.yml # Главный playbook
├── webservers.yml # Playbook для вебсерверов
├── databases.yml # Playbook для БД
├── roles/
│ ├── webserver/
│ ├── database/
│ └── common/
├── group_vars/
│ ├── all.yml
│ ├── webservers.yml
│ └── databases.yml
├── host_vars/
│ ├── web1.yml
│ └── db1.yml
└── files/
└── configs/
Хорошие практики
# ✅ DO
---
- name: Ясное описание what playbook делает
hosts: webservers
become: yes
gather_facts: yes # Получить информацию о системе
pre_tasks:
- name: Обновить кэш пакетов
apt:
update_cache: yes
tasks:
- name: Ясное описание каждой задачи
apt:
name: nginx
state: present
register: nginx_install
until: nginx_install is succeeded # Повторить если ошибка
retries: 3
delay: 10
post_tasks:
- name: Проверка
debug:
msg: "Playbook завершен успешно"
handlers:
- name: Перезагрузить сервис
service:
name: nginx
state: restarted
# ❌ DON'T
---
- hosts: all
tasks:
- shell: apt-get install nginx && systemctl start nginx
Проверочный список
- [ ] Понимаете синтаксис Ad-Hoc команд
- [ ] Можете использовать основные модули (apt, copy, service)
- [ ] Создали первый простой playbook
- [ ] Запустили playbook успешно
- [ ] Понимаете структуру YAML
- [ ] Используете переменные в playbooks
- [ ] Готовы к ролям
Готовы? Переходите к Уроку 6 - Роли и структурирование! 🚀