В предыдущей статье вы узнали, как использовать специальные команды Ansible для выполнения одной задачи на управляемых хостах. В этой статье вы узнаете, как автоматизировать несколько задач на управляемых хостах путем создания и запуска сценариев Ansible.
Чтобы лучше понять различия между специальной командой Ansible и сценариями Ansible; вы можете думать о специальных командах Ansible как о командах Linux, а playbook – как о сценариях bash.
Специальные команды Ansible идеально подходят для выполнения задач, которые не выполняются часто, таких как получение данных о работоспособности серверов, получение системной информации и т. д.
С другой стороны, плейбуки Ansible идеально подходят для автоматизации сложных задач, таких как системные исправления, развертывание приложений, конфигурации брандмауэра, управление пользователями и т. д.
Обратите внимание, что мы включили все сценарии, сценарии и файлы, которые я собираюсь обсудить в этой серии, в этот репозиторий GitHub.
Прежде чем следовать этой статьи по Ansible Playbook, вам следует обратиться к настройке, упомянутой в первой главе серии статей о Ansible.
Создание вашей первой Ansible playbook
Плейбуки написаны в формате YAML (еще один язык разметки). Если вы не знаете YAML; Мы включили наиболее важные правила синтаксиса YAML на рисунок ниже, чтобы вы могли легко следовать всем примерам статьи:
Вы также должны знать, что файлы YAML также должны иметь расширение .yaml или .yml. Мы лично предпочитаем .yml, потому что в нем меньше печатать.
Кроме того, YAML чувствителен к отступам. Отступ в два пробела рекомендуется использовать в YAML; однако YAML будет следовать любой системе отступов, которую использует файл, если она согласована.
Постоянно нажимать два пробела на клавиатуре не раздражает, поэтому сделайте себе одолжение и включите следующую строку в файл ~ /.vimrc:
autocmd FileType yaml setlocal ai ts=2 sw=2 et
Это преобразует вкладки в два пробела всякий раз, когда вы работаете с файлом YAML. Понравился этот удобный совет по Vim?
Теперь давайте создадим ваш первый сценарий. В каталоге проекта создайте файл с именем first-playbook.yml со следующим содержимым:
[destroyer@andreyex]$ cat first-playbook.yml --- - name: first play hosts: all tasks: - name: create a new file file: path: /tmp/foo.conf mode: 0664 owner: destroyer state: touch
Playbook будет работать на всех хостах и использует файловый модуль для создания файла с именем /tmp/foo.conf ; вы также устанавливаете режим: 0664 и параметры модуля owner: destroyer, чтобы указать права доступа к файлу и владельца файла. Наконец, вы устанавливаете опцию state: touch, чтобы убедиться, что файл создается, если он еще не существует.
Чтобы запустить playbook, вы можете использовать команду ansible-playbook, за которой следует имя файла playbook:
ansible-playbook first-playbook.yml
Вот полный вывод вышеуказанной команды:
[destroyer@andreyex]$ ansible-playbook first-playbook.yml PLAY [first play] ************************************************************** TASK [Gathering Facts] ********************************************************* ok: [node4] ok: [node3] ok: [node1] ok: [node2] TASK [create a new file] ******************************************************* changed: [node4] changed: [node3] changed: [node1] changed: [node2] PLAY RECAP ********************************************************************* node1 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 node2 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 node3 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 node4 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Результат запуска playbook довольно понятен. На данный момент обратите особое внимание на значение changed = 1 в сводке PLAY RECAP, которое означает, что одно изменение было успешно выполнено на управляемом узле.
Давайте запустим следующую специальную команду, чтобы убедиться, что файл /tmp/foo.conf действительно создан на всех управляемых хостах:
[destroyer@andreyex]$ ansible all -m command -a "ls -l /tmp/foo.conf" node4 | CHANGED | rc=0 >> -rw-rw-r-- 1 destroyer root 0 Oct 25 03:20 /tmp/foo.conf node1 | CHANGED | rc=0 >> -rw-rw-r--. 1 destroyer root 0 Oct 25 03:20 /tmp/foo.conf node2 | CHANGED | rc=0 >> -rw-rw-r--. 1 destroyer root 0 Oct 25 03:20 /tmp/foo.conf node3 | CHANGED | rc=0 >> -rw-rw-r--. 1 destroyer root 0 Oct 25 03:20 /tmp/foo.conf
Обратите внимание, что вы также можете запустить специальную команду Ansible, которая будет делать то же самое, что и playbook first- playbook.yml:
ansible all -m file -a "path=/tmp/foo.conf mode=0664 owner=destroyer state=touch"
Чтобы узнать больше о файловом модуле, посетите его страницу документации Ansible:
[destroyer@andreyex]$ ansible-doc file
Запуск нескольких сценариев с помощью Ansible Playbook
Вы создали только один сценарий, который содержит одну задачу в playbook first- playbook.yml. Playbook может содержать несколько сценариев, и каждый сценарий, в свою очередь, может содержать несколько задач.
Давайте создадим книгу с именем multiple-plays.yml со следующим содержимым:
[destroyer@andreyex]$ cat multiple-plays.yml --- - name: first play hosts: all tasks: - name: install tmux package: name: tmux state: present - name: create an archive archive: path: /var/log dest: /tmp/logs.tar.gz format: gz - name: second play hosts: node4 tasks: - name: install git apt: name: git state: present
В этой пьесе есть две пьесы:
- Первая игра (состоит из двух задач) – проходит на всех хостах.
- Вторая игра (содержит одно задание) – работает только на node4.
Обратите внимание, что мы использовали модуль пакета при первом воспроизведении, поскольку это универсальный модуль для управления пакетами, и он автоматически определяет диспетчер пакетов по умолчанию на управляемых узлах. Мы использовали модуль apt во второй игре, так как мы запускаем его только на хосте Ubuntu ( node4 ).
Модули yum и dnf также существуют и они работают на системах CentOS и RHEL.
Мы также использовали модуль архива для создания сжатого с помощью gzip архива /tmp/logs.tar.gz, который содержит все файлы в каталоге /var/log.
Идите вперед и запустите playbook multi-plays.yml :
[destroyer@andreyex]$ ansible-playbook multiple-plays.yml PLAY [first play] ************************************************************** TASK [install tmux] ************************************************************ changed: [node4] changed: [node2] changed: [node3] changed: [node1] TASK [create an archive] ******************************************************* changed: [node2] changed: [node3] changed: [node1] changed: [node4] PLAY [second play] ************************************************************* TASK [install git] ************************************************************* changed: [node4] PLAY RECAP ********************************************************************* node1 : ok=2 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 node2 : ok=2 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 node3 : ok=2 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 node4 : ok=3 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Все выглядит хорошо. Вы можете быстро проверить, существует ли архив /tmp/logs.tar.gz на всех узлах, выполнив следующую специальную команду:
[destroyer@andreyex]$ ansible all -m command -a "file -s /tmp/logs.tar.gz" node4 | CHANGED | rc=0 >> /tmp/logs.tar.gz: gzip compressed data, was "/tmp/logs.tar", last modified: Sun Oct 25 04:40:46 2020, max compression node1 | CHANGED | rc=0 >> /tmp/logs.tar.gz: gzip compressed data, was "/tmp/logs.tar", last modified: Sun Oct 25 04:40:47 2020, max compression, original size 107458560 node3 | CHANGED | rc=0 >> /tmp/logs.tar.gz: gzip compressed data, was "/tmp/logs.tar", last modified: Sun Oct 25 04:40:47 2020, max compression, original size 75560960 node2 | CHANGED | rc=0 >> /tmp/logs.tar.gz: gzip compressed data, was "/tmp/logs.tar", last modified: Sun Oct 25 04:40:47 2020, max compression, original size 52326400
Мы также рекомендуем вам проверить следующие страницы документации Ansible и проверить раздел примеров:
[destroyer@andreyex]$ ansible-doc package [destroyer@andreyex]$ ansible-doc archive [destroyer@andreyex]$ ansible-doc apt [destroyer@andreyex]$ ansible-doc yum
Проверка playbooks (перед запуском)
Хотя мы уже показали вам шаги по запуску плейбуков Ansible, всегда полезно проверить свой плейбук перед его запуском. Это гарантирует, что ваш playbook не содержит потенциальных ошибок.
Вы можете использовать опцию –syntax-check, чтобы проверить, есть ли в вашей книге синтаксические ошибки:
[destroyer@andreyex]$ ansible-playbook --syntax-check first-playbook.yml playbook: first-playbook.yml
Вы также можете использовать опцию –check для пробного прогона вашей playbook перед фактическим запуском playbook:
[destroyer@andreyex]$ ansible-playbook --check first-playbook.yml PLAY [first play] ************************************************************** TASK [Gathering Facts] ********************************************************* ok: [node4] ok: [node3] ok: [node1] ok: [node2] TASK [create a new file] ******************************************************* ok: [node4] ok: [node1] ok: [node2] ok: [node3] PLAY RECAP ********************************************************************* node1 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 node2 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 node3 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 node4 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Обратите внимание, что сухой запуск playbook не зафиксирует никаких изменений на управляемых узлах.
Вы можете использовать –list-options для перечисления хозяев каждой игры в вашей книге:
[destroyer@andreyex]$ ansible-playbook --list-hosts multiple-plays.yml playbook: multiple-plays.yml play #1 (all): first play TAGS: [] pattern: ['all'] hosts (4): node4 node2 node1 node3 play #2 (node4): second play TAGS: [] pattern: ['node4'] hosts (1): node4
Вы также можете перечислить задачи каждой игры в своей книге, используя опцию –list-tasks:
[destroyer@andreyex]$ ansible-playbook --list-tasks multiple-plays.yml playbook: multiple-plays.yml play #1 (all): first play TAGS: [] tasks: install tmux TAGS: [] create an archive TAGS: [] play #2 (node4): second play TAGS: [] tasks: install git TAGS: []
Вы также можете проверить справочную страницу ansible-playbook для получения полного списка опций.
Повторное использование задач и учебников
Вы можете написать несколько сценариев, которые имеют общий список задач. В этом случае лучше создать файл, содержащий список всех общих задач, а затем вы сможете повторно использовать их в своих сборниках.
Для демонстрации создадим файл с именем group-tasks.yml , содержащий следующие задачи:
[destroyer@andreyex]$ cat group-tasks.yml - name: create developers group group: name: developers - name: create security group group: name: security - name: create finance group group: name: finance
Теперь вы можете использовать модуль import_tasks для запуска всех задач в group-tasks.yml в вашей первой книге воспроизведения следующим образом:
[destroyer@andreyex]$ cat first-playbook.yml --- - name: first play hosts: all tasks: - name: create a new file file: path: /tmp/foo.conf mode: 0664 owner: destroyer state: touch - name: create groups import_tasks: group-tasks.yml
Вы также можете использовать модуль import_playbook для повторного использования всей playbook. Например, вы можете создать новую книгу воспроизведения с именем reuse-playbook.yml со следующим содержимым:
[destroyer@andreyex]$ cat reuse-playbook.yml --- - name: Reusing playbooks hosts: all tasks: - name: Reboot the servers reboot: msg: Server is rebooting ... - name: Run first playbook import_playbook: first-playbook.yml
Также обратите внимание, что вы можете импортировать пьесу только на новом уровне игры; то есть вы не можете импортировать игру в другую.
Вы также можете использовать модуль include для повторного использования задач и playbook. Например, вы можете заменить оператор import_playbook на оператор include следующим образом:
[destroyer@andreyex]$ cat reuse-playbook.yml --- - name: Reusing playbooks hosts: all tasks: - name: Reboot the servers reboot: msg: Server is rebooting ... - name: Run first playbook include: first-playbook.yml
Единственное отличие состоит в том, что операторы импорта предварительно обрабатываются во время синтаксического анализа playbook. С другой стороны, операторы include обрабатываются по мере их появления во время выполнения playbook. Таким образом, импорт является статическим, а включение – динамическим.
Выполнение выборочных задач и игр с помощью Ansible playbook
Вы можете выбрать не запускать всю книгу воспроизведения и вместо этого захотите запустить определенные задачи или игры в книге. Для этого можно использовать теги.
Например, вы можете пометить задачу install git в playbook multiple-plays.yml следующим образом:
[destroyer@andreyex]$ cat multiple-plays.yml --- - name: first play hosts: all tasks: - name: install tmux package: name: tmux state: present - name: create an archive archive: path: /var/log dest: /tmp/logs.tar.gz format: gz - name: second play hosts: node4 tasks: - name: install git apt: name: git state: present tags: git
Теперь вы можете использовать параметры –tags , за которыми следует имя тега git, только для запуска задачи установки git:
[destroyer@andreyex]$ ansible-playbook multiple-plays.yml --tags git PLAY [first play] ************************************************************** PLAY [second play] ************************************************************* TASK [install git] ************************************************************* ok: [node4] PLAY RECAP ********************************************************************* node4 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Как видите, первые две игры были пропущены, и запустился только install git. Вы также можете увидеть changed = 0 в PLAY RECAP, потому что git уже установлен на node4.
Вы также можете применить теги к пьесе аналогичным образом.