Пособие по Ansible
Это пособие познакомит вас Ansible пошагово. Вам понадобится (виртуальная или реальная) машина, которая будет выступать в роли ansible node. Окружение для Vagrant идет в комплекте с этим пособием.
Ansible это программное решение для удаленного управления конфигурациями. Оно позволяет настраивать удаленные узлы. Главное его отличие от других подобных систем – Ansible использует (потенциально) существующую инфраструктуру SSH, в то время как другие (chef, puppet, …) требует установки специального PKI-окружения.
Ansible использует т.н. push mode: конфигурация «проталкивается» (push) с главной машины. Другие CM-системы обычно поступают наоборот – узлы «тянут» (pull) конфигурацию с главной машины.
Этот режим интересен потому что вам не нужно иметь публично доступную главную машину для удаленной настройки узлов: это узлы должны быть доступны (позже мы увидим что скрытые узлы также могут получать конфигурацию), и большую часть времени они на самом деле доступны.
Что нужно для Ansible
Необходимы следующие Python-модули
- python-yaml
- python-jinja2
На Debian/Ubuntu запустите:
sudo apt-get install python-yaml python-jinja2 python-paramiko python-crypto
У вас также должна быть комбинация ключей в ~/.ssh.
Установка Ansible
Из исходников
Ветка devel всегда стабильна, так что используем ее. Возможно, вам нужно будет установить git (sudo apt-get install git
на Debian/Ubuntu).
git clone git://github.com/ansible/ansible.git
cd ./ansible
Теперь можно загрузить окружение Ansible.
source ./hacking/env-setup
Из deb пакета
sudo apt-get install make fakeroot cdbs python-support
git clone git://github.com/ansible/ansible.git
cd ./ansible
make deb
sudo dpkg -i ../ansible_1.1_all.deb (version may vary)
В этом пособии мы допускаем, что вы использовали именно этот способ.
Клонирование пособия
git clone https://github.com/freetonik/ansible-tuto-rus.git
cd ansible-tuto-rus
Использование Vagrant в пособии
Настоятельно рекомендуем использовать Vagrant при прохождении этого пособия. Если вы еще не установили его, следуйте простым инструкциям в step-00/README.md.
Если вы хотите продолжить без Vagnrant, переходите к шагу
step-01/README.md.
Содержание
- 00. Установка Vagrant
- 01. Basic inventory
- 02. Первые модули и факты
- 03. Группы и переменные
- 04. Playbooks
- 05. Плейбуки, отправка файлов на узлы
- 06. Плейбуки и ошибки
- 07. Плейбуки и условия
- 08. Модуль Git
- 09. Расширение до нескольких хостов
- 10. Шаблоны
- 11. Снова переменные
- 12. Миграция к ролям
Contributing
Спасибо всем, кто участвовал в создании этого пособия:
- Aladin Jaermann
- Alexis Gallagher
- Atilla Mas
- Benny Wong
- Chris Schmitz
- dalton
- Daniel Howard
- David Golden
- Eugene Kalinin
- Hartmut Goebel
- Justin Garrison
- Karlo
- Marchenko Alexandr
- mxxcon
- Patrick Pelletier
- Pierre-Gilles Levallois
- Ruud Kamphuis
- Victor Boivie
Я использую Ansible почти с самого его появления, и я узнал очень много в процессе написания пособия. Если вы хотите поучаствовать – буду рад вашим дополнениям.
От переводчика
Это перевод туториала от Michel Blanc. Разделы, работа над которыми идет в данный момент, находятся в ветке writing в оригинальном репозитории.
Если вы хотите дополнить/исправить перевод, пожалуйста, откройте Pull Request.
Обзор
Это первая часть руководства из двух частей по Ansible. В этой части вы узнаете, что такое Ansible, как его установить и настроить, и как установить локальный кластер Vagrant для его тестирования. Затем вы найдете инвентарь, модули, специальные команды, книги, стратегии запуска, блоки и хранилище.
Что такое Ansible?
Ansible — это инструмент управления конфигурацией и оркестровки. Он работает в том же домене, что и Puppet, Chef и Saltstack. Это означает, что с помощью Ansible вы можете удаленно предоставлять целый парк удаленных серверов, устанавливать и развертывать на них программное обеспечение и отслеживать их удаленно.
Ansible — это проект с открытым исходным кодом, реализованный на Python и имеющий подключаемую архитектуру с модулями, которые могут управлять практически любой операционной системой, облачной средой и инструментом или средой системного администрирования. Вы также можете довольно легко расширить его с помощью своих собственных плагинов, если вы хотите сделать что-то особенное.
Одной из уникальных особенностей Ansible является то, что он не устанавливает никакого программного обеспечения на управляемые машины. Управляет машинами удаленно через SSH. Чтобы управлять удаленным компьютером, вам просто нужно убедиться, что ваш открытый ключ SSH находится в файле авторизованных ключах этого компьютера.
Начало работы с Ansible
Ansible работает на управляющей машине и может управлять серверами под управлением любой операционной системы, но управляющая машина не может быть машиной Windows на данный момент. Я буду использовать Mac OS X в этом руководстве в качестве контрольной машины.
Установка
Ansible требует Python 2.6 или 2.7. Чтобы установить его, введите:
pip install ansible
В Mac OS X рекомендуется увеличить количество дескрипторов файлов:
sudo launchctl limit maxfiles 1024 unlimited
Если вы видите ошибку типа «Слишком много открытых файлов», вам, вероятно, нужно это сделать.
Чтобы проверить правильность установки Ansible, введите ansible --version
. Вы увидите следующее:
1 |
ansible 2.0.0.2 |
2 |
|
3 |
config file =
|
4 |
|
5 |
configured module search path = Default w/o overrides
|
6 |
Конечно, номер версии может быть другим.
Файл конфигурации Ansible
Ansible имеет файл конфигурации, который позволяет вам управлять многими опциями. Порядок поиска:
- ANSIBLE_CONFIG (переменная окружения)
- ansible.cfg (в текущем каталоге)
- .ansible.cfg (в домашнем каталоге)
- /etc/ansible/ansible.cfg
Вы также можете переопределить определенные параметры, используя отдельные переменные среды, которые имеют приоритет над файлом конфигурации.
Проверьте документацию Ansible, чтобы узнать обо всех вариантах.
Настройте Кластер Vagrant
Чтобы по-настоящему понять всю мощь Ansible, вам нужно несколько серверов для управления. В этом руководстве я буду использовать кластер Vagrant из 3 виртуальных машин, но для Ansible это всего лишь несколько хостов, которыми он должен управлять. Чтобы узнать больше о Vagrant, ознакомьтесь с разделом Введение в Vagrant.
Сначала установите VirtualBox и Vagrant. Затем поместите следующее в файл с именем Vagrantfile в рабочем каталоге.
1 |
# -*- mode: ruby -*-
|
2 |
|
3 |
# vi: set ft=ruby :
|
4 |
|
5 |
hosts = { |
6 |
|
7 |
"larry" => "192.168.88.10", |
8 |
|
9 |
"curly" => "192.168.88.11", |
10 |
|
11 |
"moe" => "192.168.88.12" |
12 |
|
13 |
}
|
14 |
|
15 |
Vagrant.configure("2") do |config| |
16 |
|
17 |
config.vm.box = "precise64" |
18 |
|
19 |
config.vm.box_url = "http://files.vagrantup.com/precise64.box" |
20 |
|
21 |
hosts.each do |name, ip| |
22 |
|
23 |
config.vm.define name do |machine| |
24 |
|
25 |
machine.vm.network :private_network, ip: ip |
26 |
|
27 |
machine.vm.provider "virtualbox" do |v| |
28 |
|
29 |
v.name = name |
30 |
|
31 |
end
|
32 |
|
33 |
end
|
34 |
|
35 |
end
|
36 |
|
37 |
end
|
Затем наберите vagrant up
. Vagrant создаст для вас три виртуальные машины, доступные как larry, curly и moe. Чтобы проверить, введите vagrant status
. Вы должны увидеть:
1 |
Current machine states: |
2 |
|
3 |
|
4 |
|
5 |
larry running (virtualbox) |
6 |
|
7 |
curly running (virtualbox) |
8 |
|
9 |
moe running (virtualbox) |
10 |
|
11 |
|
12 |
|
13 |
This environment represents multiple VMs. The VMs are all listed |
14 |
|
15 |
above with their current state. For more information about a specific |
16 |
|
17 |
VM, run `vagrant status NAME`. |
Чтобы убедиться, что вы можете использовать SSH на хостах кластера, введите: vagrant ss >> ~ / .ssh / config
.
Теперь вы можете использовать SSH на любом из ваших виртуальных серверов, используя их имя хоста. Например: ssh curly
. Это позволит Ansible подключаться к хостам вашего кластера через SSH без каких-либо проблем с именами пользователей, паролями или ключами.
Инвентарь
Теперь, когда у нас есть кластер, нам нужно рассказать об этом Ansible. Это делается с помощью инвентарного файла. Файл инвентаризации — это список имен хостов, организованных в группы с использованием формата файла INI. Поместите следующее в файл с именем ‘hosts’ в вашей рабочей директории.
1 |
[funny] |
2 |
|
3 |
larry |
4 |
|
5 |
|
6 |
|
7 |
[funnier] |
8 |
|
9 |
curly |
10 |
|
11 |
moe |
Я поместил «larry» в группу «funny», а остальные хосты в группу «funnier». Эта организация позволит нам выполнять действия в отношении этих групп. Вы также можете выполнять действия на отдельных хостах и на всех хостах.
Модули
Ansible имеет очень модульную и расширяемую архитектуру. Все его возможности организованы в модули. Есть основные модули и дополнительные модули. Каждый модуль представляет команду, и большинство принимает аргументы. Вы можете использовать модули непосредственно в специальных командах или в книгах воспроизведения. Вы можете прочитать обо всех модулях в документации.
Специальные команды
Пришло время взяться за дело. Простейший способ использования Ansible — запуск специальных команд. Специальные команды используют модули. Формат специальной команды:
ansible -i -m [-a , ... ]
Например, чтобы увидеть, все ли хосты в вашем инвентаре работают, вы можете использовать модуль ping (без аргументов):
1 |
ansible all -i hosts -m ping |
2 |
|
3 |
curly | SUCCESS => { |
4 |
|
5 |
"changed": false, |
6 |
|
7 |
"ping": "pong" |
8 |
|
9 |
}
|
10 |
|
11 |
larry | SUCCESS => { |
12 |
|
13 |
"changed": false, |
14 |
|
15 |
"ping": "pong" |
16 |
|
17 |
}
|
18 |
|
19 |
moe | SUCCESS => { |
20 |
|
21 |
"changed": false, |
22 |
|
23 |
"ping": "pong" |
24 |
|
25 |
}
|
Ansible имеет много модулей для всех распространенных задач системного администрирования, таких как управление файлами, управление пользователями и пакетами, а также множество необычных задач. Но если вы не можете найти то, что вам нужно, или просто чувствуете себя более комфортно с простыми командами оболочки, вы можете использовать модуль оболочки напрямую, включая каналы. Следующая команда извлекает внутренние и внешние IP-адреса всех хостов:
1 |
ansible all -i hosts -m shell -a '/sbin/ifconfig | grep inet.*Bcast'" |
2 |
|
3 |
|
4 |
|
5 |
larry | SUCCESS | rc=0 >>
|
6 |
|
7 |
inet addr:10.0.2.15 Bcast:10.0.2.255 Mask:255.255.255.0
|
8 |
|
9 |
inet addr:192.168.88.10 Bcast:192.168.88.255 Mask:255.255.255.0
|
10 |
|
11 |
|
12 |
|
13 |
curly | SUCCESS | rc=0 >>
|
14 |
|
15 |
inet addr:10.0.2.15 Bcast:10.0.2.255 Mask:255.255.255.0
|
16 |
|
17 |
inet addr:192.168.88.11 Bcast:192.168.88.255 Mask:255.255.255.0
|
18 |
|
19 |
|
20 |
|
21 |
moe | SUCCESS | rc=0 >>
|
22 |
|
23 |
inet addr:10.0.2.15 Bcast:10.0.2.255 Mask:255.255.255.0
|
24 |
|
25 |
inet addr:192.168.88.12 Bcast:192.168.88.255 Mask:255.255.255.0
|
Playbooks
Специальные команды хороши, когда вы хотите быстро что-то сделать на нескольких хостах, но настоящая сила Ansible в его Playbooks. Playbooks — это файлы YAML, в которых вы определяете наборы задач для достижения таких целей, как подготовка, настройка, развертывание и управление вашей инфраструктурой.
Пример Playbook
Давайте посмотрим на то, как выглядит типичный playbook, прежде чем мы перейдем к деталям.
1 |
--- |
2 |
|
3 |
- hosts: funnier |
4 |
|
5 |
tasks: |
6 |
|
7 |
- name: Install Nginx |
8 |
|
9 |
apt: pkg=nginx state=installed update_cache=true |
10 |
|
11 |
notify: Start Nginx |
12 |
|
13 |
- name: Install Python 3 |
14 |
|
15 |
apt: pkg=python3-minimal state=installed |
16 |
|
17 |
handlers: |
18 |
|
19 |
- name: Start Nginx |
20 |
|
21 |
service: name=nginx state=started |
В playbook есть раздел hosts, в котором вы указываете хосты из файла инвентаризации. В этом случае название группы «funnier». Затем есть раздел задач с двумя задачами, которые устанавливают Nginx и Python 3. Наконец, есть раздел обработчиков, где Nginx запускается после его установки.
Запуск Playbooks
Вы запускаете playbook с помощью команды ansible-playbook
. Вам все еще нужно предоставить файл инвентаря и книгу воспроизведения, которую вы хотите запустить. Сохраните playbook в файл с именем «playbook.yml» в вашем рабочем каталоге. Давайте попробуем:
1 |
ansible-playbook -i hosts playbook.yml
|
2 |
|
3 |
|
4 |
|
5 |
PLAY ***************************************************************************
|
6 |
|
7 |
|
8 |
|
9 |
TASK [setup] ******************************************************************* |
10 |
|
11 |
ok: [moe]
|
12 |
|
13 |
ok: [curly]
|
14 |
|
15 |
|
16 |
|
17 |
TASK [Install Nginx] *********************************************************** |
18 |
|
19 |
fatal: [moe]: FAILED! => {"changed": false, "failed": true, "msg": "Failed to lock apt for exclusive operation"} |
20 |
|
21 |
fatal: [curly]: FAILED! => {"changed": false, "failed": true, "msg": "Failed to lock apt for exclusive operation"} |
22 |
|
23 |
|
24 |
|
25 |
PLAY RECAP *********************************************************************
|
26 |
|
27 |
curly : ok=1 changed=0 unreachable=0 failed=1 |
28 |
|
29 |
moe : ok=1 changed=0 unreachable=0 failed=1 |
30 |
О нет. Что случилось? Ansible выдает приличное сообщение об ошибке здесь: «Не удалось заблокировать apt для исключительной операции». Многие playbooks требуют привилегий sudo. Этот playbook не является исключением. Чтобы запустить playbook с правами sudo, просто добавьте флаг --sudo
:
1 |
ansible-playbook -i hosts playbook.yml --sudo |
2 |
|
3 |
|
4 |
|
5 |
PLAY ***************************************************************************
|
6 |
|
7 |
|
8 |
|
9 |
TASK [setup] ******************************************************************* |
10 |
|
11 |
ok: [curly]
|
12 |
|
13 |
ok: [moe]
|
14 |
|
15 |
|
16 |
|
17 |
TASK [Install Nginx] *********************************************************** |
18 |
|
19 |
changed: [moe]
|
20 |
|
21 |
changed: [curly]
|
22 |
|
23 |
|
24 |
|
25 |
TASK [Install Python 3] ******************************************************** |
26 |
|
27 |
changed: [moe]
|
28 |
|
29 |
changed: [curly]
|
30 |
|
31 |
|
32 |
|
33 |
RUNNING HANDLER [Start Nginx] ************************************************** |
34 |
|
35 |
changed: [moe]
|
36 |
|
37 |
changed: [curly]
|
38 |
|
39 |
|
40 |
|
41 |
PLAY RECAP *********************************************************************
|
42 |
|
43 |
curly : ok=4 changed=3 unreachable=0 failed=0 |
44 |
|
45 |
moe : ok=4 changed=3 unreachable=0 failed=0 |
46 |
Ansible является идемпотентом, что означает, что если что-то уже находится в желаемом состоянии, то Ansible оставит это в покое. В выводе ansible-playbook
вы можете увидеть, какие задачи были успешными или неудачными, а какие были изменены.
Давайте снова запустим ту же playbook. Ничто не должно быть изменено:
1 |
ansible-playbook -i hosts playbook.yml --sudo |
2 |
|
3 |
|
4 |
|
5 |
PLAY ***************************************************************************
|
6 |
|
7 |
|
8 |
|
9 |
TASK [setup] ******************************************************************* |
10 |
|
11 |
ok: [moe]
|
12 |
|
13 |
ok: [curly]
|
14 |
|
15 |
|
16 |
|
17 |
TASK [Install Nginx] *********************************************************** |
18 |
|
19 |
ok: [curly]
|
20 |
|
21 |
ok: [moe]
|
22 |
|
23 |
|
24 |
|
25 |
TASK [Install Python 3] ******************************************************** |
26 |
|
27 |
ok: [curly]
|
28 |
|
29 |
ok: [moe]
|
30 |
|
31 |
|
32 |
|
33 |
PLAY RECAP *********************************************************************
|
34 |
|
35 |
curly : ok=3 changed=0 unreachable=0 failed=0 |
36 |
|
37 |
moe : ok=3 changed=0 unreachable=0 failed=0 |
Стратегии запуска
До Ansible 2.0 playbook выполнялись линейно, задача за задачей. Все целевые хосты выполнили первое задание. Только когда все узлы были выполнены с первым заданием, они могли начать второе задание.
В Ansible 2.0 добавлена концепция стратегий запуска. В настоящее время существует две стратегии: «линейная» стратегия, которую я описал выше, которая является стратегией по умолчанию, и «свободная» стратегия, при которой хосты могут выполнять задачи в сборнике playbook по-прежнему в порядке, но не в стопах с другими хостами.
Это может быть полезно, если сотни хостов должны загрузить несколько файлов с некоторых FTP-серверов. Первый хост может завершить загрузку первого файла и перейти к следующему, в то время как другие хосты все еще заняты загрузкой первого файла. К тому моменту, когда другие хосты загрузят следующий файл, первый хост уже будет готов, и будет меньше конфликтов.
Свободная стратегия кажется превосходной в большинстве ситуаций. Вы просто добавляете strategy: free
пару ключ-значение в playbook.
1 |
- hosts: all |
2 |
|
3 |
strategy: free |
4 |
|
5 |
tasks: |
6 |
|
7 |
... |
Блоки
Еще одна новая особенность Ansible 2.0 — блоки. Блоки позволяют группировать задачи вместе. Это очень полезно, если у вас есть задачи, которые нужно выполнять только при определенных условиях. Раньше вам приходилось делать это для каждой задачи отдельно.
1 |
--- |
2 |
|
3 |
- hosts: all |
4 |
|
5 |
tasks: |
6 |
|
7 |
- debug: msg='Task 1 here' |
8 |
|
9 |
when: ansible_distribution == 'Ubuntu' |
10 |
|
11 |
|
12 |
|
13 |
- debug: msg='Task 2 here' |
14 |
|
15 |
when: ansible_distribution == 'Ubuntu' |
16 |
|
17 |
|
18 |
|
19 |
- debug: msg='Task 3 here' |
20 |
|
21 |
when: ansible_distribution == 'Ubuntu' |
С блоками вы можете сгруппировать все эти задачи отладки и поставить условие « when» на уровне блока.
1 |
- hosts: all |
2 |
|
3 |
tasks: |
4 |
|
5 |
- block: |
6 |
|
7 |
- debug: msg='Task 1 here' |
8 |
|
9 |
- debug: msg='Task 2 here' |
10 |
|
11 |
- debug: msg='Task 3 here' |
12 |
|
13 |
when: ansible_distribution == 'Ubuntu' |
14 |
Хранилище
Ansible связывается с удаленными компьютерами по SSH, но в плейбуках могут содержаться такие секреты, как имя пользователя, пароли и ключи API. Поскольку вы обычно храните playbooks в системах контроля версий, таких как git, эта информация будет видна всем, кто имеет доступ для чтения.
Ansible помогает с программой ansible-vault, которая позволяет создавать, редактировать и повторно шифровать зашифрованные файлы. Эти файлы могут быть расшифрованы на лету при запуске playbook, указав пароль. Если вы добавите флаг --vault-ask-pass
в ansible-playbook, он запросит пароль хранилища.
Кроме того, вы можете добавить --vault-password-file <файл-пароля>
, и Ansible прочитает пароль из вашего файла. Если вы используете файл паролей, не храните его в системе контроля версий!
Теперь вы можете безопасно хранить зашифрованные файлы в системе контроля версий и не беспокоиться о том, что кто-то найдет ваши секреты. Вам нужно тщательно управлять своим паролем хранилища. Если вы потеряете его, вы не сможете расшифровать файлы в хранилище.
Заключение
Ansible — отличный инструмент. Это легкий. Он может использоваться в интерактивном режиме со специальными командами и очень хорошо масштабируется для больших систем. У него также есть большой импульс и большое сообщество. Если вы управляете или даже просто работаете с удаленными серверами, вам определенно нужен Ansible.
Оставайтесь с нами для второй части.
Ansible для абсолютных новичков — Практика — DevOps Это один из лучших курсов Ansible для начинающих, который шаг за шагом научит вас писать книгу об игре Ansible, создавать файлы инвентаризации Ansible и развертывать программное обеспечение на нескольких хостах.
Простота: как мы видели, Ansible использует очень простой синтаксис, написанный на YAML, известный как playbooks — YAML (еще один язык разметки) — это человекочитаемый язык сериализации данных. Нам не нужны специальные навыки кодирования, чтобы кодировать и понимать плейбуки. Очень легко устанавливать и выполнять задачи по порядку.
Ansible работает, подключаясь к вашим узлам и отправляя на эти узлы небольшие программы, называемые модулями. Модули используются для выполнения задач автоматизации в Ansible. Эти программы написаны как ресурсные модели желаемого состояния системы. Затем Ansible выполняет эти модули и удаляет их по завершении.
Note
Сделать открытый исходный код более инклюзивным
Red Hat стремится заменить проблемный язык в нашем коде, документации и веб-ресурсах. Мы начинаем с этих четырех терминов: главный, подчиненный, черный список и белый список. Мы просим вас открыть вопрос или запрос на вытягивание, если вы столкнетесь с условием, которое мы пропустили. Подробнее см . в сообщении нашего технического директора Криса Райта .
Добро пожаловать в Допустимое руководство пользователя! В этом руководстве рассказывается о том,как работать с Допустимым,в том числе использовать командную строку,работать с инвентаризацией,взаимодействовать с данными,писать задания,пьесы и тетради;выполнять тетради и справочные материалы.На этой странице описаны наиболее распространенные ситуации и вопросы,которые приводят читателей к этому разделу.Если вы предпочитаете традиционное оглавление,вы можете найти его в нижней части страницы.
Getting started
-
Я хотел бы получить обзор того,как работает Ansible.Где я могу найти:
- обзор быстрое видео
- текст введения
- Я готов изучить Ansible. Какие концепции Ansible мне нужно изучить?
- Я хочу использовать Ansible без написания сборника пьес. Как использовать специальные команды ?
Пишу задания,пьесы и тетради.
- Я пишу свою первую пьесу. Что я должен знать, прежде чем начать ?
-
У меня есть конкретный случай использования для задания или игры:
- Выполнение задач с повышенными привилегиями или от имени другого пользователя со статусом
- Повторение задачи один раз для каждого элемента в списке с циклами
- Выполнение задач на другом компьютере с делегированием
- Запуск задач только при выполнении определенных условий с условными выражениями и оценка условий с помощью тестов
- Grouping a set of tasks together with blocks
- Запуск задач только тогда, когда что-то изменилось с обработчиками
- Изменение способа обработки сбоев в Ansible
- Установка значений удаленной среды
- Я хочу использовать возможности повторно используемых артефактов Ansible. Как мне создать повторно используемые файлы и роли ?
- Мне нужно включить один файл или пьесу в другой. В чем разница между включением и импортом ?
- Я хочу запустить выбранные части моей пьесы. Как мне добавлять и использовать теги ?
Работа с инвентаризацией
- У меня есть список серверов и устройств, которые я хочу автоматизировать. Как создать инвентарь для их отслеживания?
- Я использую облачные сервисы, и у меня постоянно запускаются и останавливаются серверы и устройства. Как их отслеживать с помощью динамического инвентаря ?
- Я хочу автоматизировать определенные подмножества своего инвентаря. Как использовать шаблоны ?
Взаимодействие с данными
- Я хочу использовать одну книгу против нескольких систем с разными атрибутами. Как использовать переменные для обработки различий?
- Я хочу получить данные о своих системах. Как получить доступ к фактам об Ansible ?
- Мне нужен доступ к конфиденциальным данным, таким как пароли, с помощью Ansible. Как я могу защитить эти данные с помощью хранилища Ansible ?
- Я хочу изменить имеющиеся у меня данные, чтобы использовать их в задаче. Как использовать фильтры для преобразования моих данных?
- Мне нужно получить данные из внешнего хранилища данных. Как использовать поиск для доступа к базам данных и API?
- Я хочу попросить пользователей playbook предоставить данные. Как получить от пользователя ввод с подсказками ?
- Я часто использую определенные модули. Как мне оптимизировать свой инвентарь и плейбуки, установив значения по умолчанию для параметров модуля ?
Executing playbooks
Как только ваша игровая книга будет готова к запуску,вам,возможно,понадобится использовать эти темы:
- Выполнение «пробных» плейбуков с режимом проверки и сравнения
- Запуск сценариев при устранении неполадок с запуском и шагом
- Исправление задач во время выполнения с помощью отладчика Ansible
- Контроль за выполнением моей инструкции с помощью стратегий и многого другого
- Асинхронное выполнение задач, игр и сборников пьес
Дополнительные функции и ссылка
- Использование расширенного синтаксиса
- Управление сложными данными
- Using plugins
- Использование ключевых слов playbook
- Использование инструментов командной строки
- Отклонение определенных модулей
- Module maintenance
Традиционное содержание
Если вы предпочитаете прочитать все Руководство пользователя,вот список страниц по порядку:
- Допустимое краткое руководство
-
Ansible concepts
- Control node
- Managed nodes
- Inventory
- Collections
- Modules
- Tasks
- Playbooks
-
Getting Started
- Выбор оборудования из инвентаря
- Подключение к удаленным узлам
- Копирование и выполнение модулей
- Resources
- Next steps
-
Введение в специальные команды
- Зачем использовать специальные команды?
- Примеры использования для специальных задач
-
Работа с плейбуками
- Templating (Jinja2)
- Расширенные возможности плейбуков
- Пример из плейбука:Непрерывная поставка и обновление прокатных станов
-
Введение в плейбуки
- Playbook syntax
- Playbook execution
- Ansible-Pull
- Verifying playbooks
-
Советы и хитрости
- General tips
- Playbook tips
- Inventory tips
- Execution tricks
-
Понимание эскалации привилегий:стать
- Using become
- Риски и ограничения становления
- Станьте и сетевая автоматизация
- Стать и Windows
-
Loops
- Сравнивая
loop
иwith_*
- Standard loops
- Регистрация переменных в цикле
- Complex loops
- Ensuring list input for
loop
: usingquery
rather thanlookup
- Добавление элементов управления в контуры
- Миграция из с_X в цикл
- Сравнивая
-
Контроль над тем,где выполняются задачи:делегирование и местные действия.
- Задачи,которые не могут быть делегированы
- Delegating tasks
- Delegating facts
- Local playbooks
-
Conditionals
- Основные условные выражения с
when
- Commonly-used facts
- Основные условные выражения с
-
Tests
- Test syntax
- Testing strings
- Vault
- Testing truthiness
- Comparing versions
- Тесты теории множеств
- Тестирование,содержит ли список значение
- Тестирование того,является ли значение списка Истинным
- Testing paths
- Форматы тестовых форматов
- Результаты тестовых заданий
-
Blocks
- Группировка задач с блоками
- Обработка ошибок блоками
-
Обработчики:выполнение операций по смене
- Handler example
- Управление при работе обработчиков
- Использование переменных с обработчиками
-
Обработка ошибок в плейбуках
- Игнорирование неудачных команд
- игнорирование недоступных ошибок хоста
- Сброс недоступных хостов
- Дескрипторы и отказ
- Defining failure
- Defining “changed”
- Обеспечение успеха для командования и снаряда
- Прерывание игры на всех хозяевах
- Ошибки управления блоками
-
Настройка удаленной среды
- Настройка удаленной среды в задаче
- Работа с менеджерами языковых версий
-
Повторное использование Допустимые артефакты
- Создание многократно используемых файлов и ролей
- Re-using playbooks
- Повторное использование файлов и ролей
- Повторное использование задач в качестве обработчиков
-
Roles
- Структура каталога ролей
- Хранение и поиск ролей
- Using roles
- Проверка ролевых аргументов
- Запуск роли несколько раз в одной пьесе.
- Использование ролевых зависимостей
- Встраиваемые модули и плагины в ролях
- Разделение ролей:Допустимая Галактика
- Включая и импортируя
-
Tags
- Добавление тегов с ключевым словом tags
- Специальные теги:всегда и никогда
- Выбор или пропуск тегов при запуске плейбога.
-
Как создать свой инвентарь
- Основы инвентаризации:форматы,хосты и группы
- Добавление переменных в инвентаризацию
- Присвоение переменной одной машине:переменные хоста
- Присвоение переменной многим машинам:переменные группы
- Организация переменных хоста и группы
- Как происходит объединение переменных
- Использование нескольких источников инвентаризации
- Подключение к хостам:поведенческие параметры инвентаризации
- Инвентаризация примеров настройки
-
Работа с динамической инвентаризацией
- Пример скрипта инвентаризации:Сапожник
- Пример скрипта инвентаризации:OpenStack
- Другие сценарии инвентаризации
- Использование инвентаризационных каталогов и многочисленных источников инвентаризации
- Статические группы динамических групп
-
Образы:ориентация на хозяев и группы
- Using patterns
- Common patterns
- Ограничения моделей
- Дополнительные опции шаблонов
- Шаблоны и флаги из доступных книг игр
-
Методы подключения и детали
- ControlPersist и paramiko
- Установка удаленного пользователя
- Настройка кнопок SSH
- Бежать против местного жителя
- Управление проверкой ключей хоста
- Другие способы подключения
-
Работа с инструментами командной строки
- ansible
- ansible-config
- ansible-console
- ansible-doc
- ansible-galaxy
- ansible-inventory
- ansible-playbook
- ansible-pull
- ansible-vault
-
Using Variables
- Создание имен действительных переменных
- Simple variables
- Когда заключать в кавычки переменные (YAML получено)
- List variables
- Dictionary variables
- Registering variables
- Ссылка на вложенные переменные
- Преобразование переменных с помощью фильтров Jinja2
- Где установить переменные
- Переменный приоритет:Куда поставить переменную?
- Использование расширенного синтаксиса переменных
-
Открытие переменных:факты и магические переменные
- Ansible facts
- Информация о Допустимом:волшебные переменные
-
Шифрование содержимого с помощью допустимого хранилища
- Управление паролями хранилища
- Шифрование содержимого с помощью допустимого хранилища
- Использование зашифрованных переменных и файлов
- Настройка параметров по умолчанию для использования зашифрованного содержимого
- Когда зашифрованные файлы становятся видимыми?
- Ускорение Допустимое хранилище
- Формат файлов,зашифрованных с помощью Ansible Vault
-
Использование фильтров для манипулирования данными
- Обработка неопределенных переменных
- Определение различных значений для true/false/null (тернарный)
- Управление типами данных
- Данные форматирования:YAML и JSON
- Объединение и выбор данных
- Randomizing data
- Управление переменными списка
- Выбор из множеств или списков (теория множеств)
- Расчетные числа (математика)
- Управление сетевыми взаимодействиями
- Шифрование и контрольное суммирование строк и паролей
- Manipulating text
- Manipulating strings
- Managing UUIDs
- Обработка дат и времени
- Получение имен ресурсов Kubernetes
-
Lookups
- Использование поиска в переменных
-
Интерактивный ввод:подсказки
- Шифрование значений, предоставляемых
vars_prompt
- Разрешение специальных символов в значениях
vars_prompt
- Шифрование значений, предоставляемых
-
Module defaults
- Группы по умолчанию модуля
-
Валидационные задания:режим проверки и дифференциальный режим
- Использование режима проверки
- Использование дифференциального режима
-
Выполнение плейбуков для устранения неполадок
- start-at-task
- Step mode
-
Debugging tasks
- Включение отладчика
- Решение ошибок в отладчике
- Доступные команды отладки
- Как отладчик взаимодействует со свободной стратегией.
-
Контроль за выполнением плейбука:стратегии и многое другое
- Выбор стратегии
- Установка количества вил
- Использование ключевых слов для контроля исполнения
-
Асинхронные действия и опрос
- Асинхронные специальные задачи
- Асинхронные игровые задания
-
Advanced Syntax
- Небезопасные или необработанные струны
- YAML-анкеры и псевдонимы:совместное использование значений переменных
-
Data manipulation
- Петли и понимание списков
- Преобразование сложных типов
- Rejecting modules
-
Образец Допустимая настройка
- Пример оформления каталога
- Альтернативная раскладка каталога
- Пример группы и переменных хоста
- Образцы плейбуков,организованные по функциям
- Примеры файлов задач и обработчиков в функциональной роли
- Что позволяет настроить образец
- Организация для развертывания или конфигурирования
- Использование локальных доступных модулей
-
Работа с модулями
- Введение в модули
- Обслуживание и поддержка модулей
- Return Values
-
Работа с плагинами
- Action Plugins
- Become Plugins
- Cache Plugins
- Callback Plugins
- Cliconf Plugins
- Connection Plugins
- Httpapi Plugins
- Inventory Plugins
- Lookup Plugins
- Netconf Plugins
- Shell Plugins
- Strategy Plugins
- Vars Plugins
- Использование фильтров для манипулирования данными
- Tests
- Rejecting modules
-
Playbook Keywords
- Play
- Role
- Block
- Task
-
Допустимо и BSD
- Подключение к узлам BSD
- Bootstrapping BSD
- Установка переводчика Python
- Какие модули доступны?
- Использование BSD в качестве узла управления
- BSD facts
- Усилия и вклад BSD
-
Windows Guides
- Настройка хоста Windows
- удалённое управление Windows
- Используя Допуск и Windows
- Желаемая конфигурация состояния
- Windows performance
- Часто задаваемые вопросы
-
Using collections
- Installing collections
- Downloading collections
- Listing collections
- Verifying collections
- Использование коллекций в Playbook
- Упрощение имен модулей с помощью ключевого слова
collections
- Использование игровой книги из коллекции
Ansible
-
Методы подключения и детали
В этом разделе показано, как расширить и уточнить методы подключения, которые Ansible использует для вашего инвентаря.
-
Пример из плейбука:Непрерывная поставка и обновление прокатных станов
Непрерывная доставка (CD)означает частую доставку обновлений к вашему программному приложению.
-
Введение в специальные команды
Специальная команда Ansible использует инструмент командной строки /usr/bin/ansible для автоматизации отдельной задачи на одном или нескольких управляемых узлах.
-
Допустимо и BSD
Управление BSD-машинами отличается от других Unix-подобных Ansible, которые по умолчанию подключаются к управляемым узлам с помощью OpenSSH.
Ansible – это простой ИТ-движок с открытым исходным кодом, который автоматизирует развертывание приложений, внутрисервисную оркестровку, облачную подготовку и многие другие ИТ-инструменты.
Ansible прост в развертывании, поскольку он не использует агентов или пользовательскую инфраструктуру безопасности.
Ansible использует playbook для описания заданий автоматизации, а playbook использует очень простой язык, то есть YAML (это читаемый человеком язык сериализации данных и обычно используется для файлов конфигурации, но может использоваться во многих приложениях, где хранятся данные), что очень легко для людей, чтобы понять, читать и писать. Следовательно, преимущество заключается в том, что даже ребята из службы поддержки ИТ-инфраструктуры могут читать и понимать игровую книгу и отлаживать ее при необходимости (YAML – она в удобочитаемой форме).
Ansible предназначен для многоуровневого развертывания. Ansible не управляет одной системой одновременно, он моделирует ИТ-инфраструктуру, описывая все ваши системы взаимосвязанными. Ansible полностью без агента, что означает, что Ansible работает, подключая ваши узлы через ssh (по умолчанию). Но если вам нужен другой способ подключения, например Kerberos, Ansible предоставит вам такую возможность.
После подключения к вашим узлам Ansible запускает небольшие программы, называемые «Ansible Modules». Ansible запускает эти модули на ваших узлах и удаляет их по завершении. Ansible управляет вашим инвентарем в простых текстовых файлах (это файл hosts). Ansible использует файл hosts, в котором можно сгруппировать хосты и управлять действиями над определенной группой в книгах воспроизведения.
@DevOPSitsec – бесплатное обучение DevOps в нашем канале.
Образец файла Hosts
Это содержимое файла hosts –
#File name: hosts #Description: Inventory file for your application. Defines machine type abc node to deploy specific artifacts # Defines machine type def node to upload metadata.
[abc-node]
#server1 ansible_host = <target machine for DU deployment> ansible_user = <Ansible user> ansible_connection = ssh server1 ansible_host = <your host name> ansible_user = <your unix user> ansible_connection = ssh
[def-node]
#server2 ansible_host = <target machine for artifact upload> ansible_user = <Ansible user> ansible_connection = ssh server2 ansible_host = <host> ansible_user = <user> ansible_connection = ssh
Что такое управление конфигурацией
Управление конфигурацией в терминах Ansible означает, что оно поддерживает конфигурацию производительности продукта, ведя учет и обновляя подробную информацию, которая описывает аппаратное и программное обеспечение предприятия.
Такая информация обычно включает точные версии и обновления, которые были применены к установленным программным пакетам, а также местоположения и сетевые адреса аппаратных устройств. Например, если вы хотите установить новую версию сервера WebLogic / WebSphere на всех машинах, имеющихся на вашем предприятии, вам не представляется возможным вручную перейти и обновить каждую машину.
Вы можете установить WebLogic / WebSphere за один раз на все свои машины с помощью самых простых книг и инвентаризации Ansible. Все, что вам нужно сделать, это перечислить IP-адреса ваших узлов в инвентаре и написать книгу для установки WebLogic / WebSphere. Запустите playbook со своего компьютера управления, и он будет установлен на всех ваших узлах.
Как работает Ansible?
На рисунке ниже показана работа Ansible.
Ansible работает , подключаясь к вашим узлам и выдвигая к ним небольшие программы, называемые « Ansible modules». Затем Ansible выполняет эти модули (по умолчанию через SSH) и удаляет их после завершения. Ваша библиотека модулей может находиться на любом компьютере, и для нее не требуются серверы, демоны или базы данных.
Узел управления на приведенном выше изображении является управляющим узлом (управляющим узлом), который управляет всем исполнением книги воспроизведения. Это узел, с которого вы запускаете установку. Файл инвентаризации содержит список хостов, на которых необходимо запустить модули Ansible, а узел управления устанавливает соединение SSH, выполняет небольшие модули на хост-машине и устанавливает продукт / программное обеспечение.
Прелесть Ansible в том, что он удаляет модули после того, как они установлены, настолько эффективно, что он подключается к хост-машине, выполняет инструкции и, если он успешно установлен, удаляет код, который был скопирован на хост-машине, которая была выполнена.
Ansible – Настройка среды
В этой главе мы узнаем о настройке среды Ansible.
Процесс установки
В основном, есть два типа машин, когда мы говорим о развертывании –
- Управление машиной – Машина, с которой мы можем управлять другими машинами.
- Дистанционная машина – машины, которые управляются / контролируются управляющей машиной.
Управление машиной – Машина, с которой мы можем управлять другими машинами.
Дистанционная машина – машины, которые управляются / контролируются управляющей машиной.
Может быть несколько удаленных машин, которые обрабатываются одной управляющей машиной. Итак, для управления удаленными машинами мы должны установить Ansible на управляющей машине.
Требования к контрольной машине
Ansible может быть запущен с любой машины с установленным Python 2 (версии 2.6 или 2.7) или Python 3 (версии 3.5 и выше).
Примечание. Windows не поддерживает управление машиной.
По умолчанию Ansible использует ssh для управления удаленным компьютером.
Ansible не добавляет ни одной базы данных. Это не требует каких-либо демонов, чтобы запустить или поддерживать его. При управлении удаленными машинами Ansible не оставляет на них установленного или запущенного программного обеспечения. Следовательно, нет вопроса о том, как обновить его при переходе на новую версию.
Ansible может быть установлен на управляющей машине, которая имеет вышеупомянутые требования по-разному. Вы можете установить последнюю версию через Apt, yum, pkg, pip, OpenCSW, pacman и т. Д.
Установка через Apt на Ubuntu Machine
Для установки Ansible вы должны настроить PPA на вашем компьютере. Для этого вам нужно запустить следующую строку кода –
$ sudo apt-get update $ sudo apt-get install software-properties-common $ sudo apt-add-repository ppa:ansible/ansible $ sudo apt-get update $ sudo apt-get install ansible
Запустив приведенную выше строку кода, вы готовы управлять удаленными машинами через Ansible. Просто запустите Ansible – version, чтобы проверить версию и просто проверить, правильно ли был установлен Ansible.
Ansible – Основы YAML
Ansible использует синтаксис YAML для выражения Ansible playbooks. В этой главе представлен обзор YAML. Ansible использует YAML, потому что людям очень легко понимать, читать и писать по сравнению с другими форматами данных, такими как XML и JSON.
Каждый файл YAML может начинаться с «—» и заканчиваться на «…».
Понимание YAML
В этом разделе мы изучим различные способы представления данных YAML.
пара ключ-значение
YAML использует простую пару ключ-значение для представления данных. Словарь представлен в паре ключ: значение.
Примечание. Между: и значением должен быть пробел.
Пример: запись студента
--- #Optional YAML start syntax james: name: james john rollNo: 34 div: B sex: male … #Optional YAML end syntax
Сокращение
Вы также можете использовать сокращение для представления словарей.
пример
James: {name: james john, rollNo: 34, div: B, sex: male}
Представляющий список
Мы также можем представить список в YAML. Каждый элемент (член) списка должен быть записан в новой строке с таким же отступом, начинающимся с «-» (- и пробел).
пример
--- countries: - America - China - Canada - Iceland …
Сокращение
Вы также можете использовать сокращение для представления списков.
пример
Countries: [‘America’, ‘China’, ‘Canada’, ‘Iceland’]
Список внутри словарей
Мы можем использовать список внутри словарей, т. Е. Значением ключа является список.
пример
--- james: name: james john rollNo: 34 div: B sex: male likes: - maths - physics - english …
Список словарей
Мы также можем составить список словарей.
пример
--- - james: name: james john rollNo: 34 div: B sex: male likes: - maths - physics - english - robert: name: robert richardson rollNo: 53 div: B sex: male likes: - biology - chemistry …
YAML использует «|» для включения новых строк при отображении нескольких строк и «>» для подавления новых строк при отображении нескольких строк. Благодаря этому мы можем читать и редактировать большие строки. В обоих случаях намерения будут игнорироваться.
Мы также можем представлять логические (True / false) значения в YAML. где логические значения могут быть без учета регистра.
пример
--- - james: name: james john rollNo: 34 div: B sex: male likes: - maths - physics - english result: maths: 87 chemistry: 45 biology: 56 physics: 70 english: 80 passed: TRUE messageIncludeNewLines: | Congratulation!! You passed with 79% messageExcludeNewLines: > Congratulation!! You passed with 79%
Некоторые общие слова, связанные с Ansible.
Сервис / Сервер – процесс на компьютере, который предоставляет сервис.
Машина – физический сервер, виртуальная машина или контейнер.
Целевая машина – машина, которую мы собираемся настроить с помощью Ansible.
Задача – действие (запустить, удалить это) и т. Д., Управляемое Ansible.
Playbook – файл yml, в котором записываются команды Ansible и на компьютере выполняется yml.
Сервис / Сервер – процесс на компьютере, который предоставляет сервис.
Машина – физический сервер, виртуальная машина или контейнер.
Целевая машина – машина, которую мы собираемся настроить с помощью Ansible.
Задача – действие (запустить, удалить это) и т. Д., Управляемое Ansible.
Playbook – файл yml, в котором записываются команды Ansible и на компьютере выполняется yml.
Инвентори: ansible_host vs FQDN
В этой части мы хорошо разбираемся с тем, что такое inventory_hostname
, что такое ansible_host
, с понятием транспорта.
При том, что транспорт уже не совсем “инвентори”, к содержимому инвентори он относится наипрямейшим образом, потому что смена транспорта внутри play — это уже экстремальный спорт, на который не распространяется ваша медстраховка.
Что такое “транспорт”? Это результат использования “connection plugin” Ансибла, через который модуль копируется в целевую систему (или, в ряде случаев, не копируется, но получает доступ к целевой системе). Какой-то транспорт используется всегда. Самый популярный транспорт ssh (используется по-умолчанию), но их на самом деле много. Каждый плагин может использовать набор переменных, выделенных для подключения: ansible_host
, ansible_user
, ansible_port
и т. д. А может и не использовать. Например, если транспорт lxc (который выполняет код через lxc-execute
), то зачем ему порт?
Если же ansible_host
не задан, то используется inventory_hostname
. Это — имя хоста в инвентори.
Вот пример:
---
somegroup:
hosts:
somehost:
ansible_host: 254.12.11.10
Вот somehost
тут — это inventory_hostname
. Если нет ansible_host
, то используется inventory_hostname
. И всё было бы понятно, если бы не следующий уровень преобразований, который не имеет никакого отношения к Ансибл, но может попортить много нервов.
Внутри как inventory_hostname
, так и ansible_host
может быть либо адрес, либо имя. С адресом всё понятно, а вот с именем уже интереснее. Оно передаётся “как есть” в нижележащий исполнитель. Интерпретация имени оставляется на усмотрение транспорта. Например, lxc использует его для выбора контейнера. А вот ssh (самый распространённый транспорт, напоминаю) использует кое-что более сложное.
Во-первых, он смотрит в конфиг ~/.ssh/ssh_config
(или другой, заданный через переменные окружения). Если кто пропустил, напоминаю, что конфиг ssh тьюринг-полный и может делать странное через комбинацию регэкспов и сниппетов для исполнения баша. Т.е. переданное имя становится (в общем случае) аргументом к частично-рекурсивной функции, которая (может быть) выдаёт реальные параметры соеднения на выходе. Может быть, соединение пойдёт через цепочку jump-хостов, редиректов портов и прочего ssh-цирка. А может быть, такого хоста не найдётся. Если же из ssh_config
выползает другое имя (или искомого нет в ssh_config
), то ssh делает gethostbyname()
. Это вызов libc, который получает адрес по имени. Который, в свою очередь, руководствуется пачкой конфигурационных файлов (/etc/nsswitch.conf
, /etc/hosts
) и ответами DNS-ресолвера (если конфигурационные файлы это разрешают). Который, в свою очередь, может дописывать к имени домен, смотреть на разные рекурсивные DNS-сервера, которые могут отвечать разное, а могут посмотреть на ресурсную запись CNAME пойти куда сказано… Просто волшебная простыня возможностей того, что может пойти не так.
Из этого вытекает моё, выстраданное, мнение: при работе с SSH, всегда (кроме спецслучаев) использовать ansible_host
внутри которого IP-адрес.
Я пробовал другой путь, и он мне местами аукается до сих пор. Давайте разберём этот вопрос подробно.
Если вы используете любое вне-ансибловое, но host-local определение имени (ssh_config
, /etc/hosts
), то ваши плейбуки перестают быть портабельными между машинами. Вы ссылаетесь на что-то, что существует только у вас в голове и с вами разговаривает только в конфигурации вашего компьютера. Вы не можете перетащить эти плейбуки на CI, на машину коллеги или даже на вторую вашу машину. Точнее, можете, но для этого нужно что-то (что?) прописать в конфигурацию, которой не видно в репозитории. Опечатки трудно отлаживать (у меня всё работает), изменения почти невозможно распространять. НЕ ДЕЛАЙТЕ ТАК.
Хотя, разумеется, есть исключения. Например, моя маленькая уютная оверлейная сеточка для домашних нужд живёт с именами из /etc/hosts и все плейбуки полагаются на эти имена. Но это моё осознанное решение, которое к индустриальному продакшену никакого отношения иметь не должно.
Если вы используете DNS, то вы получаете себе регэксп ещё одну проблему. Когда изменения в DNS дойдут до вашей машины? Негативное/позитивное кеширование, всё такое. А даже если оно дошло до вас, то когда оно дойдёт до резолвера, которым пользуется ваш динамический слейв CI? Слейв-то помер, а DNS-ресолвер — нет. Удачи в отладке. НЕ ДЕЛАЙТЕ ТАК.
Второй момент, куда более тонкий. Надо ли всегда указывать ansible_host
или inventory_hostname
достаточно?
В плейбуках рано или поздно возникает потребность указать “адрес соседа”. В самых трудных случаях этот процесс требует модуля setup
и выполнения головоломного кода:
- name: Ping neighbor
command: ping -c 1 {{ neighbor_ip }} -w 1
changed_when: false
vars:
neighbor_ip: '{{ (hostvars[item].ansible_all_ipv4_addresses|ipaddr(public_network))[0] }}'
with_items: '{{ groups[target_group] }}'
(имея на руках public_network
мы проверяем, что хосты могут общаться со всеми серверами в группе target_group
).
Но, это трудный случай, поскольку у серверов несколько интерфейсов. В 99% случаев вам нужен просто “адрес соседа”. Если вы договорились, что у каждого хоста есть ansible_host
и внутри там обязательно IP-адрес, то вот он. Никакого setup
. Бери и используй. Прелесть ansible_host
с IP-адресом трудно переоценить, потому что, помимо “какого-то IP соседа”, этот адрес ещё неявно (явно!) отвечает вам на вопрос, какой из IP-адресов сервера является его “access address” при наложении всяких файрвольных правил, конфигурации доступов и т.д. Делайте так. Это хорошо и удобно.
… Но тут может возникнуть вопрос: а если у нас сервера появляются на свет динамически, или у нас внешная система оркестрации (а-ля докер) у которой точно есть хороший DNS? Ну, тогда используйте их. А, заодно, страдайте, если вам понадобились IP. Разумеется, к любой общей рекомендации всегда можно найти частные исключения.
Инвентори: ansible_user
Следующая интереснейшая проблема: надо ли в инвентори хранить имя пользователя? Это важный вопрос, но у него нет однозначного ответа. Вот набор моментов, о которых надо подумать перед выбором.
- Есть ли доступ к этому хосту из-под “спецаккаунта” у других пользователей? Если есть, то
ansible_user
в инвентори разумно. - Есть ли доступ к серверу под “своими” аккаунтами у других пользователей? Если есть, то
ansible_user
в инвентори создаёт проблемы. - Если вы не указываете пользователя в инвентори, то опция
-u
уansible-playbook
позволяет пользователя задать, причём так, что его можно переопределить из любого места в инвентори или плейбуке для необычных видов коннектов. Это удобно. Каждый под своим пользователем, CI использует-u
(или тоже под своим пользователем), все счастливы. - Но тогда абстракция протекает. Например, ваш сосед может быть залогинен на своём ноутбуке под именем ‘me’. Это ж его ноутбук. А на сервере он — m.gavriilicheynko. Неудобненько.
- В то же самое время, использование опции
ansible-playbook -e ansible_user=ci
(для CI, например) с одной стороны позволяет использовать правильное имя вне зависимости от содержимого инвентори, с другой стороны ломает все нестандартные подключения (к коммутаторам, например). - Если у вас стоит проблема “первого логина” (плейбука создаёт всех пользователей, но только после первого запуска), то первый запуск можно сделать и с опцией
-u
, и никто не помрёт.
В моей практике (и обстоятельствах, в которых я работаю), мне удобно указывать ansible_user
для “себя” (т.е. инвентори, к которыми работаю только я). Если инвентори используется более одним человеком — ansible_user используется только для специальных случаев (например, доступ к коммутаторам при первом провизе и т.д.), а обычные хосты ansible_user
не используют.
Ansible – специальные команды
Специальные команды – это команды, которые можно запускать индивидуально для выполнения быстрых функций. Эти команды не должны быть выполнены позже.
Например, вам нужно перезагрузить все серверы вашей компании. Для этого вы запустите команды Adhoc из / usr / bin / ansible .
Эти специальные команды не используются для управления конфигурацией и развертывания, потому что эти команды используются один раз.
ansible-playbook используется для управления конфигурацией и развертывания.
Параллелизм и Команды Shell
Перезагрузите сервер своей компании в 12 параллельных вилок одновременно. Для этого нам нужно настроить SSHagent для подключения.
$ ssh-agent bash $ ssh-add ~/.ssh/id_rsa
Чтобы выполнить перезагрузку для всех серверов вашей компании в группе «abc», в 12 параллельных ветвях –
$ Ansible abc -a "/sbin/reboot" -f 12
По умолчанию Ansible запускает указанные выше специальные команды из текущей учетной записи пользователя. Если вы хотите изменить это поведение, вам нужно будет передать имя пользователя в специальных командах следующим образом:
$ Ansible abc -a "/sbin/reboot" -f 12 -u username
Передача файла
Вы можете использовать специальные команды для одновременного выполнения большого количества файлов SCP (Secure Copy Protocol) на нескольких компьютерах.
Передача файла на многие серверы / машины
$ Ansible abc -m copy -a "src = /etc/yum.conf dest = /tmp/yum.conf"
Создание нового каталога
$ Ansible abc -m file -a "dest = /path/user1/new mode = 777 owner = user1 group = user1 state = directory"
Удаление всего каталога и файлов
$ Ansible abc -m file -a "dest = /path/user1/new state = absent"
Управление пакетами
Специальные команды доступны для yum и apt. Ниже приведены некоторые специальные команды, использующие yum.
Следующая команда проверяет, установлен пакет yum или нет, но не обновляет его.
$ Ansible abc -m yum -a "name = demo-tomcat-1 state = present"
Следующая команда проверяет, что пакет не установлен.
$ Ansible abc -m yum -a "name = demo-tomcat-1 state = absent"
Следующая команда проверяет, установлена ли последняя версия пакета.
$ Ansible abc -m yum -a "name = demo-tomcat-1 state = latest"
Сбор фактов
Факты могут быть использованы для реализации условных операторов в playbook. Вы можете найти специальную информацию обо всех ваших фактах с помощью следующей специальной команды –
$ Ansible all -m setup
Ansible – Playbooks
В этой главе мы узнаем о Playbooks в Ansible.
Названия
Главная ошибка пользователя Ansible — это не знать как что называется. Если вы не знаете названий, вы не можете понимать то, что написано в документации. Живой пример: на собеседовании, человек, вроде бы заявлявший, что он много писал на Ансибле, не смог ответить на вопрос “из каких элементов состоит playbook’а?”. А когда я подсказал, что “ожидался ответ, что playbook состоит из play”, то последовал убийственный комментарий “мы этого не используем”. Люди пишут на Ансибле за деньги и не используют play. На самом деле используют, но не знают, что это такое.
Так что начнём с простого: как что называется. Может быть вы это знаете, а может и нет, потому что не обратили внимания, когда читали документацию.
ansible-playbook исполняет playbook. Playbook — это файл с расширением yml/yaml, внутри которого что-то такое:
---
- hosts: group1
roles:
- role1
- hosts: group2,group3
tasks:
- debug:
Мы уже поняли, что весь этот файл — плейбука. Мы можем показать где тут роли (roles), где таски (tasks). Но где тут play? И чем отличается play от role или playbook?
В документации это всё есть. И это пропускают. Начинающие — потому что там слишком много и всё сразу не запомнишь. Опытные — потому что “тривиальные вещи”. Если вы опытный — перечитывайте эти страницы хотя бы раз в полгода, и ваш код станет классом лучше.
Итак, запоминайте: Playbook — это список, состоящий из play и import_playbook
.
Вот это — одна play:
- hosts: group1
roles:
- role1
и вот это тоже ещё одна play:
- hosts: group2,group3
tasks:
- debug:
Что же такое play? Зачем она?
Play — это ключевой элемент для playbook, потому что play и только play связывает список ролей и/или тасок с списком хостов, на которых их надо выполнять. В глубоких недрах документации можно найти упоминание про delegate_to
, локальные lookup-плагины, network-cli-специфичные настройки, jump-хосты и т.д. Они позволяют слегка поменять место исполнения тасок. Но, забудьте про это. У каждой из этих хитрых опций есть очень специальные применения, и они точно не являются универсальными. А мы говорим про базовые вещи, которые должны знать и использовать все.
Если вы хотите “что-то” исполнить “где-то” — вы пишете play. Не роль. Не роль с модулями и делегейтами. Вы берёте и пишете play. В которой, в поле hosts вы перечисляете где исполнять, а в roles/tasks — что исполнять.
Просто же, да? А как может быть иначе?
Одним из характерных моментов, когда у людей возникает желание сделать это не через play, это “роль, которая всё настраивает”. Хочется иметь роль, которая настраивает и сервера первого типа, и сервера второго типа.
Архетипичным примером является мониторинг. Хочется иметь роль monitoring, которая настроит мониторинг. Роль monitoring назначается на хосты мониторинга (в соотв. play). Но, выясняется, что для мониторинга нам надо поставить пакеты на хосты, которые мы мониторим. Почему бы не использовать delegate? А ещё надо настроить iptables. delegate? А ещё надо написать/поправить конфиг для СУБД, чтобы мониторинг пускала. delegate! А если креатив попёр, то можно сделать делегацию include_role
во вложенном цикле по хитрому фильтру на список групп, а внутри include_role
можно ещё делать delegate_to
снова. И понеслось…
Благое пожелание — иметь одну-единственную роль monitoring, которая “всё делает” — ведёт нас в кромешный ад из которого чаще всего один выход: всё переписать с нуля.
Где тут случилась ошибка? В тот момент, когда вы обнаружили, что для выполнения задачи “x” на хосте X вам надо пойти на хост Y и сделать там “y”, вы должны были выполнить простое упражнение: пойти и написать play, которая на хосте Y делает y. Не дописывать что-то в “x”, а написать с нуля. Пусть даже с захардкоженными переменными.
Вроде бы, в абзацах выше всё сказано правильно. Но это же не ваш случай! Потому что вы хотите написать переиспользуемый код, который DRY и похож на библиотеку, и нужно искать метод как это сделать.
Вот тут вот притаилась ещё одна грубая ошибка. Ошибка, которая превратила множество проектов из терпимо написанных (можно лучше, но всё работает и легко дописать) в совершенный ужас, в котором даже автор не может разобраться. Оно работает, но упаси боже что-то поменять.
Эта ошибка звучит так: роль — это библиотечная функция. Эта аналогия сгубила столько хороших начинаний, что просто грустно смотреть. Роль — не библиотечная функция. Она не может делать вычисления и она не может принимать решения уровня play. Напомните мне, какие решения принимает play?
Спасибо, вы правы. Play принимает решение (точнее, содержит в себе информацию) о том, какие таски и роли на каких хостах выполнять.
Если вы делегируете это решение на роль, да ещё и с вычислениями, вы обрекаете себя (и того, кто ваш код будет пытаться разобрать) на жалкое существование. Роль не решает где ей выполняться. Это решение принимает play. Роль делает то, что ей сказали, там, где ей сказали.
Почему заниматься программированием на Ансибле опасно и чем COBOL лучше Ансибла мы поговорим в главе про переменные и jinja. Пока что скажем одно — каждое ваше вычисление оставляет за собой нестираемый след из изменения глобальных переменных, и вы ничего с этим не можете сделать. Как только два “следа” пересеклись — всё пропало.
Замечание для въедливых: роль, безусловно, может влиять на control flow. Есть delegate_to
и у него есть разумные применения. Есть meta: end host/play
. Но! Помните, мы учим основы? Забыли про delegate_to
. Мы говорим про самый простой и самый красивый код на Ансибл. Который легко читать, легко писать, легко отлаживать, легко тестировать и легко дописывать. Так что, ещё раз:
play и только play решает на каких хостах что исполняется.
В этом разделе мы разобрались с противостоянием play и role. Теперь поговорим про отношения tasks vs role.
Playbooks – это файлы, в которых написан код Ansible. Сборники написаны в формате YAML. YAML означает еще один язык разметки. Playbooks являются одной из основных функций Ansible и говорят Ansible, что выполнять. Они похожи на список дел для Ansible, который содержит список задач.
Playbooks содержат шаги, которые пользователь хочет выполнить на определенной машине. Playbooks запускаются последовательно. Playbooks являются строительными блоками для всех случаев использования Ansible.
Структура Playbook
Каждая пьеса представляет собой совокупность одной или нескольких пьес в ней. Playbooks структурированы с использованием Plays. В сборнике пьес может быть несколько пьес.
Функция игры состоит в том, чтобы отобразить набор инструкций, определенных для определенного хоста.
YAML – строго типизированный язык; поэтому при записи файлов YAML необходимо соблюдать особую осторожность. Существуют разные редакторы YAML, но мы предпочитаем использовать простой редактор, такой как notepad ++. Просто откройте notepad ++, скопируйте и вставьте нижеследующий yaml и измените язык на YAML (Язык → YAML).
YAML начинается с — (3 дефиса)
Создать Playbook
Давайте начнем с написания примера файла YAML. Мы пройдемся по каждому разделу, записанному в файле yaml.
--- name: install and configure DB hosts: testServer become: yes vars: oracle_db_port_value : 1521 tasks: -name: Install the Oracle DB yum: <code to install the DB> -name: Ensure the installed service is enabled and running service: name: <your service name>
Выше приведен пример Playbook, где мы пытаемся охватить основной синтаксис playbook. Сохраните вышеуказанный контент в файл как test.yml . Синтаксис YAML должен соответствовать правильному отступу, и нужно быть немного осторожным при написании синтаксиса.
Различные теги YAML
Давайте теперь рассмотрим различные теги YAML. Различные теги описаны ниже –
название
Этот тег определяет название книги воспроизведения Ansible. Как в том, что будет делать этот playbook. Любое логическое имя может быть дано пьесе.
хостов
Этот тег определяет списки хостов или группы хостов, для которых мы хотим запустить задачу. Поле / тег hosts является обязательным. Он сообщает Ansible, на каких хостах запускать перечисленные задачи. Задачи могут быть запущены на той же машине или на удаленной машине. Можно запускать задачи на нескольких машинах, и, следовательно, тег hosts может содержать также запись группы узлов.
вары
Тег Vars позволяет вам определять переменные, которые вы можете использовать в своей книге игр. Использование аналогично переменным в любом языке программирования.
задачи
Все пьесы должны содержать задачи или список задач для выполнения. Задачи – это список действий, которые нужно выполнить. Поле задач содержит название задачи. Это работает как текст справки для пользователя. Это не обязательно, но оказывается полезным при отладке playbook. Каждая задача внутренне связана с частью кода, называемой модулем. Модуль, который должен быть выполнен, и аргументы, необходимые для модуля, который вы хотите выполнить.
Ansible – Роли
Роли обеспечивают основу для полностью независимых или взаимозависимых наборов переменных, задач, файлов, шаблонов и модулей.
В Ansible эта роль является основным механизмом разбиения книги воспроизведения на несколько файлов. Это упрощает написание сложных сборников и облегчает их повторное использование. Взлом playbook позволяет вам логически разбить playbook на компоненты многократного использования.
Каждая роль в основном ограничена определенной функциональностью или желаемым результатом со всеми необходимыми шагами для обеспечения этого результата либо внутри самой роли, либо в других ролях, перечисленных как зависимости.
Роли не являются пьесами. Роли – это небольшая функциональность, которую можно использовать независимо, но ее нужно использовать в книгах. Нет способа напрямую выполнить роль. Роли не имеют явного параметра, для которого будет применяться роль.
Playbook верхнего уровня – это мост, удерживающий хосты из файла инвентаризации для ролей, которые должны применяться к этим хостам.
Создание новой роли
Структура каталогов для ролей необходима для создания новой роли.
Ролевая структура
Роли имеют структурированный макет в файловой системе. Структура по умолчанию может быть изменена, но пока давайте придерживаться значений по умолчанию.
Каждая роль представляет собой дерево каталогов само по себе. Имя роли – это имя каталога в каталоге / role.
$ ansible-galaxy -h
использование
ansible-galaxy [delete|import|info|init|install|list|login|remove|search|setup] [--help] [options] ...
Опции
- -h, –help – показать это справочное сообщение и выйти.
- -v, –verbose – подробный режим (-vvv для большего, -vvvv для включения отладки соединения)
- –version – Показать номер версии программы и выйти.
-h, –help – показать это справочное сообщение и выйти.
-v, –verbose – подробный режим (-vvv для большего, -vvvv для включения отладки соединения)
–version – Показать номер версии программы и выйти.
Создание каталога ролей
Приведенная выше команда создала каталоги ролей.
$ ansible-galaxy init vivekrole ERROR! The API server (https://galaxy.ansible.com/api/) is not responding, please try again later. $ ansible-galaxy init --force --offline vivekrole - vivekrole was created successfully $ tree vivekrole/ vivekrole/ ├── defaults │ └── main.yml ├── files ├── handlers │ └── main.yml ├── meta │ └── main.yml ├── README.md ├── tasks │ └── main.yml ├── templates ├── tests │ ├── inventory │ └── test.yml └── vars └── main.yml 8 directories, 8 files
Не все каталоги будут использоваться в примере, и мы покажем использование некоторых из них в этом примере.
Использование ролей в Playbook
Это код пьесы, которую мы написали для демонстрации. Этот код из сборника пьес vivek_orchestrate.yml. Мы определили хосты: tomcat-node и назвали две роли – install-tomcat и start-tomcat .
Проблема в том, что у нас война, которую мы должны развернуть на машине через Ansible.
--- - hosts: tomcat-node roles: - {role: install-tomcat} - {role: start-tomcat}
Содержимое нашей структуры каталогов, откуда мы запускаем playbook.
$ ls ansible.cfg hosts roles vivek_orchestrate.retry vivek_orchestrate.yml
В каждом каталоге есть каталог задач, в котором содержится файл main.yml. Основным содержимым install-tomcat является:
--- #Install vivek artifacts - block: - name: Install Tomcat artifacts action: > yum name = "demo-tomcat-1" state = present register: Output always: - debug: msg: - "Install Tomcat artifacts task ended with message: {{Output}}" - "Installed Tomcat artifacts - {{Output.changed}}"
Содержимое main.yml начального tomcat –
#Start Tomcat - block: - name: Start Tomcat command: <path of tomcat>/bin/startup.sh" register: output become: true always: - debug: msg: - "Start Tomcat task ended with message: {{output}}" - "Tomcat started - {{output.changed}}"
Преимущество разбиения книги воспроизведения на роли заключается в том, что любой, кто хочет использовать функцию Install tomcat, может вызвать роль Install Tomcat.
Разбивая Playbook на роль
Если не для ролей, содержимое main.yml соответствующей роли может быть скопировано в yml- файл playbook. Но чтобы иметь модульность, роли были созданы.
Любая логическая сущность, которая может быть повторно использована как функция многократного использования, эта сущность может быть перемещена в роль. Пример для этого показан выше
Запустил команду для запуска playbook.
-vvv option for verbose output – verbose output $ cd vivek-playbook/
Это команда для запуска playbook
$ sudo ansible-playbook -i hosts vivek_orchestrate.yml –vvv ----------------------------------------------------------------- -----------------------------------------------------------------------
Выход
Сгенерированный вывод показан на экране –
Использование /users/demo/vivek-playbook/ansible.cfg в качестве файла конфигурации.
PLAYBOOK: vivek_orchestrate.yml ********************************************************* *********************************************************** 1 plays in vivek_orchestrate.yml PLAY [tomcat-node] ********************************************************************** ******** ************************************************* TASK [Gathering Facts] ************************************************* ****************************** ********************************************* Tuesday 21 November 2017 13:02:05 +0530 (0:00:00.056) 0:00:00.056 ****** Using module file /usr/lib/python2.7/sitepackages/ansible/modules/system/setup.py <localhost> ESTABLISH LOCAL CONNECTION FOR USER: root <localhost> EXEC /bin/sh -c 'echo ~ && sleep 0' <localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /root/.ansible/tmp/ansible-tmp-1511249525.88-259535494116870 `" && echo ansible-tmp-1511249525.88-259535494116870="` echo /root/.ansible/tmp/ansibletmp-1511249525.88-259535494116870 `" ) && sleep 0' <localhost> PUT /tmp/tmpPEPrkd TO /root/.ansible/tmp/ansible-tmp-1511249525.88259535494116870/setup.py <localhost> EXEC /bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-tmp1511249525.88-259535494116870/ /root/.ansible/tmp/ansible-tmp-1511249525.88259535494116870/setup.py && sleep 0' <localhost> EXEC /bin/sh -c '/usr/bin/python /root/.ansible/tmp/ansible-tmp1511249525.88-259535494116870/setup.py; rm -rf "/root/.ansible/tmp/ansible-tmp1511249525.88-259535494116870/" > /dev/null 2>&1 && sleep 0' ok: [server1] META: ran handlers TASK [install-tomcat : Install Tomcat artifacts] *********************************** *************************************************************** task path: /users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:5 Tuesday 21 November 2017 13:02:07 +0530 (0:00:01.515) 0:00:01.572 ****** Using module file /usr/lib/python2.7/sitepackages/ansible/modules/packaging/os/yum.py <localhost> ESTABLISH LOCAL CONNECTION FOR USER: root <localhost> EXEC /bin/sh -c 'echo ~ && sleep 0' <localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /root/.ansible/tmp/ansible-tmp-1511249527.34-40247177825302 `" && echo ansibletmp-1511249527.34-40247177825302="` echo /root/.ansible/tmp/ansible-tmp1511249527.34-40247177825302 `" ) && sleep 0' <localhost> PUT /tmp/tmpu83chg TO /root/.ansible/tmp/ansible-tmp-1511249527.3440247177825302/yum.py <localhost> EXEC /bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-tmp1511249527.34-40247177825302/ /root/.ansible/tmp/ansible-tmp-1511249527.3440247177825302/yum.py && sleep 0' <localhost> EXEC /bin/sh -c '/usr/bin/python /root/.ansible/tmp/ansible-tmp1511249527.34-40247177825302/yum.py; rm -rf "/root/.ansible/tmp/ansible-tmp1511249527.34-40247177825302/" > /dev/null 2> &1 && sleep 0' changed: [server1] => { "changed": true, "invocation": { "module_args": { "conf_file": null, "disable_gpg_check": false, "disablerepo": null, "enablerepo": null, "exclude": null, "install_repoquery": true, "installroot": "/", "list": null, "name": ["demo-tomcat-1"], "skip_broken": false, "state": "present", "update_cache": false, "validate_certs": true } }, "msg": "", "rc": 0, "results": [ "Loaded plugins: product-id, search-disabled-repos, subscriptionmanagernThis system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.nResolving Dependenciesn--> Running transaction checkn---> Package demo-tomcat-1.noarch 0:SNAPSHOT-1 will be installedn--> Finished Dependency ResolutionnnDependencies Resolvedn n================================================================================n Package Arch Version Repository Sizen==================================================================nInstalling:n demo-tomcat-1 noarch SNAPSHOT-1 demo-repo1 7.1 MnnTransaction Summaryn==================================================================nInstall 1 PackagennTotal download size: 7.1 MnInstalled size: 7.9 MnDownloading packages:nRunning transaction checknRunning transaction testnTransaction test succeedednRunning transactionn Installing : demotomcat-1-SNAPSHOT-1.noarch 1/1 n Verifying : demo-tomcat-1-SNAPSHOT-1.noarch 1/1 nnInstalled:n demo-tomcat-1.noarch 0:SNAPSHOT-1 nnComplete!n" ] } TASK [install-tomcat : debug] ********************************************************** *************************************************************************** task path: /users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:11 Tuesday 21 November 2017 13:02:13 +0530 (0:00:06.757) 0:00:08.329 ****** ok: [server1] => { "changed": false, "msg": [ "Install Tomcat artifacts task ended with message: { u'msg': u'', u'changed': True, u'results': [u'Loaded plugins: product-id, search-disabledrepos, subscription-manager\nThis system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.\nResolving Dependencies\n--> Running transaction check\n---> Package demo-tomcat-1.noarch 0:SNAPSHOT-1 will be installed\n--> Finished Dependency Resolution\n \nDependencies Resolved\n\n==================================================================\n Package Arch Version Repository Size\n======================================================================== =====\nInstalling:\n demo-tomcat-1 noarch SNAPSHOT-1 demo-repo1 7.1 M\n\nTransaction Summary\n=========================================================\nInstall 1 Package\n\nTotal download size: 7.1 M\nInstalled size: 7.9 M\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n Installing : demo-tomcat-1-SNAPSHOT-1.noarch 1/1 \n Verifying : demo-tomcat-1-SNAPSHOT-1.noarch 1/1 \n\nInstalled:\n demo-tomcat-1.noarch 0:SNAPSHOT-1 \n\nComplete!\n'], u'rc': 0 }", "Installed Tomcat artifacts - True" ] } TASK [install-tomcat : Clean DEMO environment] **************************************** ************************************************************ task path: /users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:19 Tuesday 21 November 2017 13:02:13 +0530 (0:00:00.057) 0:00:08.387 ****** [WARNING]: when statements should not include jinja2 templating delimiters such as {{ }} or {% %}. Found: {{installationOutput.changed}} Using module file /usr/lib/python2.7/sitepackages/ansible/modules/files/file.py <localhost> ESTABLISH LOCAL CONNECTION FOR USER: root <localhost> EXEC /bin/sh -c 'echo ~ && sleep 0' <localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /root/.ansible/tmp/ansible-tmp-1511249534.13-128345805983963 `" && echo ansible-tmp-1511249534.13-128345805983963="` echo /root/.ansible/tmp/ansibletmp-1511249534.13-128345805983963 `" ) && sleep 0' <localhost> PUT /tmp/tmp0aXel7 TO /root/.ansible/tmp/ansible-tmp-1511249534.13128345805983963/file.py <localhost> EXEC /bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-tmp1511249534.13-128345805983963/ /root/.ansible/tmp/ansible-tmp-1511249534.13128345805983963/file.py && sleep 0' <localhost> EXEC /bin/sh -c '/usr/bin/python /root/.ansible/tmp/ansible-tmp1511249534.13-128345805983963/file.py; rm -rf "/root/.ansible/tmp/ansible-tmp1511249534.13-128345805983963/" > /dev/null 2>&1 && sleep 0' changed: [server1] => { "changed": true, "diff": { "after": { "path": "/users/demo/DEMO", "state": "absent" }, "before": { "path": "/users/demo/DEMO", "state": "directory" } }, "invocation": { "module_args": { "attributes": null, "backup": null, "content": null, "delimiter": null, "diff_peek": null, "directory_mode": null, "follow": false, "force": false, "group": null, "mode": null, "original_basename": null, "owner": null, "path": "/users/demo/DEMO", "recurse": false, "regexp": null, "remote_src": null, "selevel": null, "serole": null, "setype": null, "seuser": null, "src": null, "state": "absent", "unsafe_writes": null, "validate": null } }, "path": "/users/demo/DEMO", "state": "absent" } TASK [install-tomcat : debug] ******************************************************** ************************************************************* task path: /users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:29 Tuesday 21 November 2017 13:02:14 +0530 (0:00:00.257) 0:00:08.645 ****** ok: [server1] => { "changed": false, "msg": [ "Clean DEMO environment task ended with message:{u'diff': {u'after': {u'path': u'/users/demo/DEMO', u'state': u'absent'}, u'before': {u'path': u'/users/demo/DEMO', u'state': u'directory'}}, u'state': u'absent', u'changed': True, u'path': u'/users/demo/DEMO'}", "check value :True" ] } TASK [install-tomcat : Copy Tomcat to user home] ************************************* ******************************************************** task path: /users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:37 Tuesday 21 November 2017 13:02:14 +0530 (0:00:00.055) 0:00:08.701 ****** [WARNING]: when statements should not include jinja2 templating delimiters such as {{ }} or {% %}. Found: {{installationOutput.changed}} Using module file /usr/lib/python2.7/sitepackages/ansible/modules/commands/command.py <localhost> ESTABLISH LOCAL CONNECTION FOR USER: root <localhost> EXEC /bin/sh -c 'echo ~ && sleep 0' <localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /root/.ansible/tmp/ansible-tmp-1511249534.43-41077200718443 `" && echo ansibletmp-1511249534.43-41077200718443="` echo /root/.ansible/tmp/ansible-tmp1511249534.43-41077200718443 `" ) && sleep 0' <localhost> PUT /tmp/tmp25deWs TO /root/.ansible/tmp/ansible-tmp-1511249534.4341077200718443/command.py <localhost> EXEC /bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-tmp1511249534.43-41077200718443/ /root/.ansible/tmp/ansible-tmp-1511249534.4341077200718443/command.py && sleep 0' <localhost> EXEC /bin/sh -c '/usr/bin/python /root/.ansible/tmp/ansible-tmp1511249534.43-41077200718443/command.py; rm -rf "/root/.ansible/tmp/ansibletmp-1511249534.43-41077200718443/" > /dev/null 2>&1 && sleep 0' changed: [server1] => { "changed": true, "cmd": [ "cp", "-r", "/opt/ansible/tomcat/demo", "/users/demo/DEMO/" ], "delta": "0:00:00.017923", "end": "2017-11-21 13:02:14.547633", "invocation": { "module_args": { "_raw_params": "cp -r /opt/ansible/tomcat/demo /users/demo/DEMO/", "_uses_shell": false, "chdir": null, "creates": null, "executable": null, "removes": null, "warn": true } }, "rc": 0, "start": "2017-11-21 13:02:14.529710", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": [] } TASK [install-tomcat : debug] ******************************************************** ********************************************************** task path: /users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:47 Tuesday 21 November 2017 13:02:14 +0530 (0:00:00.260) 0:00:08.961 ****** ok: [server1] => { "changed": false, "msg": "Copy Tomcat to user home task ended with message { 'stderr_lines': [], u'changed': True, u'end': u'2017-11-21 13:02:14.547633', u'stdout': u'', u'cmd': [u'cp', u'-r', u'/opt/ansible/tomcat/demo', u'/users/demo/DEMO/'], u'rc': 0, u'start': u'2017-11-21 13:02:14.529710', u'stderr': u'', u'delta': u'0:00:00.017923', 'stdout_lines': []}" } TASK [start-tomcat : Start Tomcat] ************************************************** ********************************************************** task path: /users/demo/vivek-playbook/roles/start-tomcat/tasks/main.yml:5 Tuesday 21 November 2017 13:02:14 +0530 (0:00:00.044) 0:00:09.006 ****** Using module file /usr/lib/python2.7/sitepackages/ansible/modules/commands/command.py <localhost> ESTABLISH LOCAL CONNECTION FOR USER: root <localhost> EXEC /bin/sh -c 'echo ~ && sleep 0' <localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /root/.ansible/tmp/ansible-tmp-1511249534.63-46501211251197 `" && echo ansibletmp-1511249534.63-46501211251197="` echo /root/.ansible/tmp/ansible-tmp1511249534.63-46501211251197 `" ) && sleep 0' <localhost> PUT /tmp/tmp9f06MQ TO /root/.ansible/tmp/ansible-tmp-1511249534.6346501211251197/command.py <localhost> EXEC /bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-tmp1511249534.63-46501211251197/ /root/.ansible/tmp/ansible-tmp-1511249534.6346501211251197/command.py && sleep 0' <localhost> EXEC /bin/sh -c '/usr/bin/python /root/.ansible/tmp/ansible-tmp1511249534.63-46501211251197/command.py; rm -rf "/root/.ansible/tmp/ansibletmp-1511249534.63-46501211251197/" > /dev/null 2>&1 && sleep 0' changed: [server1] => { "changed": true, "cmd": [ "/users/demo/DEMO/bin/startup.sh" ], "delta": "0:00:00.020024", "end": "2017-11-21 13:02:14.741649", "invocation": { "module_args": { "_raw_params": "/users/demo/DEMO/bin/startup.sh", "_uses_shell": false, "chdir": null, "creates": null, "executable": null, "removes": null, "warn": true } }, "rc": 0, "start": "2017-11-21 13:02:14.721625", "stderr": "", "stderr_lines": [], "stdout": "Tomcat started.", "stdout_lines": [ "Tomcat started." ] } TASK [start-tomcat : debug] ************************************************* ********************************************************************** task path: /users/demo/vivek-playbook/roles/start-tomcat/tasks/main.yml:10 Tuesday 21 November 2017 13:02:14 +0530 (0:00:00.150) 0:00:09.156 ****** ok: [server1] => { "changed": false, "msg": [ "Start Tomcat task ended with message: {' stderr_lines': [], u'changed': True, u'end': u'2017-11-21 13:02:14.741649', u'stdout': u'Tomcat started.', u'cmd': [u'/users/demo/DEMO/bin/startup.sh'], u'rc': 0, u'start': u'2017-11-21 13:02:14.721625', u'stderr': u'', u'delta': u'0:00:00.020024', 'stdout_lines': [u'Tomcat started.']}", "Tomcat started - True" ] } META: ran handlers META: ran handlers PLAY RECAP ******************************************************************************* ********************************************************* server1 : ok = 9 changed = 4 unreachable = 0 failed = 0 Tuesday 21 November 2017 13:02:14 +0530 (0:00:00.042) 0:00:09.198 ****** =============================================================================== install-tomcat : Install Tomcat artifacts ------------------------------- 6.76s /users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:5 -------------- Gathering Facts --------------------------------------------------------- 1.52s ------------------------------------------------------------------------------ install-tomcat : Copy Tomcat to user home ------------------------------- 0.26s /users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:37 ------------- install-tomcat : Clean DEMO environment --------------------------------- 0.26s /users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:19 ------------- start-tomcat : Start Tomcat --------------------------------------------- 0.15s /users/demo/vivek-playbook/roles/start-tomcat/tasks/main.yml:5 ---------------- install-tomcat : debug -------------------------------------------------- 0.06s /users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:11 ------------- install-tomcat : debug -------------------------------------------------- 0.06s /users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:29 ------------- install-tomcat : debug -------------------------------------------------- 0.04s /users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:47 ------------- start-tomcat : debug ---------------------------------------------------- 0.04s /users/demo/vivek-playbook/roles/start-tomcat/tasks/main.yml:10 ---------------
Нажмите следующий URL, и вы будете перенаправлены на страницу, показанную ниже – http://10.76.0.134:11677/HelloWorld/HelloWorld
В развернутой войне только есть сервлет, который отображает «Hello World». Подробный вывод показывает время, затрачиваемое каждой задачей из-за записи, добавленной в файл ansible.cfg –
[defaults] callback_whitelist = profile_tasks
Ansible – переменные
Переменные в playbooks очень похожи на использование переменных в любом языке программирования. Это поможет вам использовать и назначить значение переменной и использовать ее в любом месте книги. Можно поставить условия вокруг значения переменных и соответственно использовать их в сборнике игр.
пример
- hosts : <your hosts> vars: tomcat_port : 8080
В вышеприведенном примере мы определили имя переменной tomcat_port и присвоили значение 8080 этой переменной и можем использовать ее в вашей книге воспроизведения, где это необходимо.
Теперь, взяв ссылку из примера, поделился. Следующий код принадлежит одной из ролей (install-tomcat) –
block: - name: Install Tomcat artifacts action: > yum name = "demo-tomcat-1" state = present register: Output always: - debug: msg: - "Install Tomcat artifacts task ended with message: {{Output}}" - "Installed Tomcat artifacts - {{Output.changed}}"
Здесь выводом является используемая переменная.
Давайте пройдемся по всем ключевым словам, использованным в приведенном выше коде –
- block – Доступный синтаксис для выполнения данного блока.
- name – Соответствующее имя блока – это используется при ведении журнала и помогает в отладке того, все блоки которого были успешно выполнены.
- action – код рядом с тегом action – это задача, которая должна быть выполнена. Действие снова является ключевым словом Ansible, используемым в yaml.
- register – Выходные данные действия регистрируются с использованием ключевого слова register, а Output – это имя переменной, которая содержит выходные данные действия.
- always – снова ключевое слово Ansible, оно указывает, что ниже всегда будет выполняться
- msg – отображает сообщение
block – Доступный синтаксис для выполнения данного блока.
name – Соответствующее имя блока – это используется при ведении журнала и помогает в отладке того, все блоки которого были успешно выполнены.
action – код рядом с тегом action – это задача, которая должна быть выполнена. Действие снова является ключевым словом Ansible, используемым в yaml.
register – Выходные данные действия регистрируются с использованием ключевого слова register, а Output – это имя переменной, которая содержит выходные данные действия.
always – снова ключевое слово Ansible, оно указывает, что ниже всегда будет выполняться
msg – отображает сообщение
Использование переменной – {{Output}} ->
Это будет читать значение переменной Output. Кроме того, поскольку он используется на вкладке msg, он напечатает значение выходной переменной.
Кроме того, вы также можете использовать вложенные свойства переменной. Как в случае с проверкой {{Output.changed}}, изменился ли вывод, и, соответственно, использовать его.
Обработка исключений в Playbooks
Обработка исключений в Ansible похожа на обработку исключений в любом языке программирования. Пример обработки исключений в playbook показан ниже.
tasks: - name: Name of the task to be executed block: - debug: msg = 'Just a debug message , relevant for logging' - command: <the command to execute> rescue: - debug: msg = 'There was an exception.. ' - command: <Rescue mechanism for the above exception occurred) always: - debug: msg = "this will execute in all scenarios. Always will get logged"
Ниже приводится синтаксис для обработки исключений.
- спасение и всегда являются ключевыми словами, специфичными для обработки исключений.
- Блок – это место, где написан код (все, что должно быть выполнено на Unix-машине).
- Если команда, записанная внутри функции блока, не выполняется, то выполнение достигает блока спасения, и оно выполняется. В случае отсутствия ошибки в команде в функции блокировки, восстановление не будет выполнено.
- Всегда исполняется во всех случаях.
- Так что если мы сравниваем то же самое с Java, то это похоже на попытку, поймать и, наконец, блокировать.
- Здесь Block аналогичен блоку try, в котором вы пишете код для выполнения, а функция спасения аналогична блоку catch и всегда похожа на finally .
спасение и всегда являются ключевыми словами, специфичными для обработки исключений.
Блок – это место, где написан код (все, что должно быть выполнено на Unix-машине).
Если команда, записанная внутри функции блока, не выполняется, то выполнение достигает блока спасения, и оно выполняется. В случае отсутствия ошибки в команде в функции блокировки, восстановление не будет выполнено.
Всегда исполняется во всех случаях.
Так что если мы сравниваем то же самое с Java, то это похоже на попытку, поймать и, наконец, блокировать.
Здесь Block аналогичен блоку try, в котором вы пишете код для выполнения, а функция спасения аналогична блоку catch и всегда похожа на finally .
Loops
Ниже приведен пример, демонстрирующий использование Loops в Ansible.
Задача состоит в том, чтобы скопировать набор всех файлов war из одного каталога в папку tomcat webapps.
Большинство команд, использованных в приведенном ниже примере, уже рассматривались ранее. Здесь мы сосредоточимся на использовании циклов.
Изначально в команде ‘shell’ мы сделали ls * .war. Итак, он перечислит все военные файлы в каталоге.
Вывод этой команды берется в переменную с именем output.
Для цикла используется синтаксис with_items.
with_items: “{{output.stdout_lines}}” -> output.stdout_lines дает нам построчный вывод, а затем мы зацикливаемся на выходе с помощью команды with_items из Ansible.
Прикрепление выходных данных примера, чтобы понять, как мы использовали stdout_lines в команде with_items.
--- #Tsting - hosts: tomcat-node tasks: - name: Install Apache shell: "ls *.war" register: output args: chdir: /opt/ansible/tomcat/demo/webapps - file: src: '/opt/ansible/tomcat/demo/webapps/{{ item }}' dest: '/users/demo/vivek/{{ item }}' state: link with_items: "{{output.stdout_lines}}"
Блоки
Сборник пьес в целом разбит на блоки. Наименьшая часть шагов для выполнения записана в блоке. Написание конкретной инструкции в блоках помогает разделить функциональность и обрабатывать ее с обработкой исключений, если это необходимо.
Пример блоков описан выше в использовании переменных, обработке исключений и циклах.
Conditionals
Условные выражения используются там, где необходимо выполнить определенный шаг на основе условия.
--- #Tsting - hosts: all vars: test1: "Hello Vivek" tasks: - name: Testing Ansible variable debug: msg: "Equals" when: test1 == "Hello Vivek"
В этом случае Equals будет напечатан, поскольку переменная test1 равна, как указано в условии when. когда можно использовать с логическим ИЛИ и логическим условием И, как во всех языках программирования.
Просто измените значение переменной test1 с Hello Vivek на Hello World и посмотрите результат.
Ansible – Расширенное исполнение
В этой главе мы узнаем, что такое расширенное выполнение с Ansible.
Как ограничить выполнение задач
Это очень важная стратегия исполнения, когда нужно выполнить только одно исполнение, а не всю книгу. Например , предположим, что вы хотите только остановить сервер (в случае возникновения производственной проблемы), а затем опубликовать исправление, которое вы хотели бы только запустить сервер.
Здесь в оригинальной пьесе «Остановка и запуск» были частью разных ролей в одной и той же пьесе, но это можно сделать с помощью тегов. Мы можем предоставить разные теги для разных ролей (которые, в свою очередь, будут иметь задачи), и, следовательно, на основе тегов, предоставленных исполнителем, выполняется только указанная роль / задача. Поэтому для приведенного выше примера мы можем добавить теги, подобные следующим:
- {role: start-tomcat, tags: ['install']}}
Следующая команда помогает в использовании тегов –
ansible-playbook -i hosts <your yaml> --tags "install" -vvv
С помощью приведенной выше команды будет вызываться только роль start-tomcat. Предоставленный тег чувствителен к регистру. Убедитесь, что точное соответствие передается команде.
Как ограничить выполнение хостами
Есть два способа добиться выполнения определенных шагов на определенных хостах. Для конкретной роли определяют хосты – для каких конкретных хостов должна выполняться эта роль.
пример
- hosts: <A> environment: "{{your env}}" pre_tasks: - debug: msg = "Started deployment. Current time is {{ansible_date_time.date}} {{ansible_date_time.time}} " roles: - {role: <your role>, tags: ['<respective tag>']} post_tasks: - debug: msg = "Completed deployment. Current time is {{ansible_date_time.date}} {{ansible_date_time.time}}" - hosts: <B> pre_tasks: - debug: msg = "started.... Current time is {{ansible_date_time.date}} {{ansible_date_time.time}} " roles: - {role: <your role>, tags: ['<respective tag>']} post_tasks: - debug: msg = "Completed the task.. Current time is {{ansible_date_time.date}} {{ansible_date_time.time}}"
Согласно приведенному выше примеру, в зависимости от предоставленных хостов, соответствующие роли будут вызываться только. Теперь мои хосты A и B определены в хостах (файл инвентаря).
Альтернативное решение
Другим решением может быть определение хостов playbook с помощью переменной, а затем передача определенного адреса хоста через –extra-vars –
# file: user.yml (playbook) --- - hosts: '{{ target }}' user: ... playbook contd….
Запуск Playbook
ansible-playbook user.yml --extra-vars "target = "<your host variable>"
Если {{target}} не определен, книга воспроизведения ничего не делает. Группа из файла hosts также может быть пропущена, если это необходимо. Это не вредит, если дополнительные переменные не предоставляются.
Playbook ориентирован на одного хоста
$ ansible-playbook user.yml --extra-vars "target = <your hosts variable>" --listhosts
Ansible – Устранение неполадок
Наиболее распространенные стратегии отладки PlaySbooks Ansible используют модули, приведенные ниже –
Отладка и регистрация
Эти два модуля доступны в Ansible. Для целей отладки нам нужно разумно использовать два модуля. Примеры демонстрируются ниже.
Используйте многословие
С помощью команды Ansible можно обеспечить уровень многословия. Вы можете запускать команды с уровнем детализации один (-v) или два (-vv).
Важные моменты
В этом разделе мы рассмотрим несколько примеров, чтобы понять несколько концепций.
Если вы не цитируете аргумент, который начинается с переменной. Например,
vars: age_path: {{vivek.name}}/demo/ {{vivek.name}}
Это выдаст ошибку.
Решение
vars: age_path: "{{vivek.name}}/demo/" – marked in yellow is the fix. How to use register -> Copy this code into a yml file say test.yml and run it --- #Tsting - hosts: tomcat-node tasks: - shell: /usr/bin/uptime register: myvar - name: Just debugging usage debug: var = myvar
Когда я запускаю этот код с помощью команды Ansible-playbook -i hosts test.yml, я получаю вывод, как показано ниже.
Если вы видите yaml, мы зарегистрировали вывод команды в переменную myvar и просто распечатали вывод.
Текст, помеченный желтым, говорит нам о свойстве переменной –myvar, которое можно использовать для дальнейшего управления потоком. Таким образом, мы можем узнать о свойствах, которые предоставляются конкретной переменной. Следующая команда отладки помогает в этом.
$ ansible-playbook -i hosts test.yml PLAY [tomcat-node] *************************************************************** **************** **************************************************************** *************** ****************************** TASK [Gathering Facts] ***************************************************************** ************** ***************************************************************** ************** ************************** Monday 05 February 2018 17:33:14 +0530 (0:00:00.051) 0:00:00.051 ******* ok: [server1] TASK [command] ****************************************************************** ************* ****************************************************************** ************* ********************************** Monday 05 February 2018 17:33:16 +0530 (0:00:01.697) 0:00:01.748 ******* changed: [server1] TASK [Just debugging usage] ****************************************************************** ************* ****************************************************************** ************* ********************* Monday 05 February 2018 17:33:16 +0530 (0:00:00.226) 0:00:01.974 ******* ok: [server1] => { "myvar": { "changed": true, "cmd": "/usr/bin/uptime", "delta": "0:00:00.011306", "end": "2018-02-05 17:33:16.424647", "rc": 0, "start": "2018-02-05 17:33:16.413341", "stderr": "", "stderr_lines": [], "stdout": " 17:33:16 up 7 days, 35 min, 1 user, load average: 0.18, 0.15, 0.14", "stdout_lines": [ " 17:33:16 up 7 days, 35 min, 1 user, load average: 0.18, 0.15, 0.14" ] } } PLAY RECAP **************************************************************************** ********************************************************************************** ************************************** server1 : ok = 3 changed = 1 unreachable = 0 failed = 0
Общие проблемы Playbook
В этом разделе мы узнаем о нескольких распространенных проблемах Playbook. Проблемы –
- квотирование
- вдавливание
Playbook написан в формате yaml, и две вышеупомянутые проблемы являются наиболее распространенными в yaml / playbook.
Yaml не поддерживает отступы на основе табуляции и поддерживает отступы на основе пробелов, поэтому нужно быть осторожным с этим.
Примечание. Как только вы закончите писать yaml, откройте этот сайт ( https://editor.swagger.io/ ) и скопируйте и вставьте ваш yaml с левой стороны, чтобы обеспечить правильную компиляцию yaml. Это всего лишь совет.
Swagger квалифицирует как ошибки, так и ошибки.
Источник
Просмотры: 889
Что такое Ansible? Это ПО с открытым исходным кодом, которое автоматизирует поставку программного обеспечения, управление конфигурацией и развёртывание приложений. Ansible помогает DevOps-специалистам автоматизировать сложные задачи.
Примечание Вы читаете улучшенную версию некогда выпущенной нами статьи.
-
-
- Ключевые особенности программы Ansible
- Установка и запуск
- Структура Ansible
- Демо «Реальное приложение»
- Дополнительные материалы
-
- Безагентное. В клиенте не установлено программное обеспечение или агент, который общается с сервером.
- Идемпотентное. Независимо от того, сколько раз вы вызываете операцию, результат будет одинаковым.
- Простое и расширяемое. Программа Ansible написанa на Python и использует YAML для написания команд. Оба языка считаются относительно простыми в изучении.
Установка и запуск
# ubuntu
sudo apt-get install ansible
#mac-OS
brew install ansible
Инструкцию по установке на другие ОС можно найти здесь.
Структура Ansible
Модули
Это небольшие программы, выполняющие определённую работу на сервере. Например, вместо запуска этой команды:
sudo apt-get install htop
Мы можем использовать модуль apt и установить htop:
- name: Install htop
apt: name=htop
Использование модуля даст вам возможность узнать, установлен он или нет.
Плагины
Ansible поставляется с несколькими удобными плагинами, и вы можете легко написать свой собственный.
Инвентаризация хостов
Чтобы предоставить перечень хостов, нам нужно обозначить список, находящийся в файле инвентаризации. Он напоминает содержание файла hosts.
В простейшем виде он может содержать одну строку:
35.178.45.231 ansible_ssh_user=ubuntu
Playbooks
Ansible playbooks — это способ отправки команд на удалённые компьютеры с помощью скриптов. Вместо того, чтобы индивидуально использовать команды для удалённой настройки компьютеров из командной строки, вы можете настраивать целые сложные среды, передавая скрипт одной или нескольким системам.
group_vars
Файл содержит набор переменных, например имя пользователя и пароль базы данных.
Роли
Это способ сгруппировать несколько задач в один контейнер, чтобы эффективно автоматизировать работу с помощью понятной структуры каталогов.
Обработчики
Представляют собой списки задач, которые на самом деле не отличаются от обычных задач, на которые ссылается глобально уникальное имя и которые оповещаются уведомителями. Если ничто не уведомляет обработчик, он не будет запускаться. Независимо от того, сколько задач уведомляет обработчик, он запускается только один раз, после того как все задачи завершены.
Теги
Если у вас playbook с большим объёмом, может быть полезно иметь возможность запускать только определённую часть его конфигурации.
Демо «Реальное приложение»
Цель этой демонстрации — установить приложение Laravel в VPS. Для этого используем Lightsail.
Последовательность действий для создания и запуска Laravel APP:
-
- Создайте экземпляр Ubuntu Lightsail.
- Установите зависимости Ansible на ваш VPS.
- Добавьте SSH-ключи в Git.
- Выполните сборку хостов и ansible.cfg.
- Определите роль в Ansible.
- Определите обработчик.
- Установите модули PHP.
- Установите Nginx.
- Добавьте default-конфигурацию Nginx.
- Добавьте переменные для управления учётными данными БД, хоста, URL-адресом источника GitHub и переменными .env.
- Используйте Ansible-Vault.
- Создайте базу данных MySql, имя пользователя и пароль.
- Клонируйте кодовую базу в ваш VPS.
- Сгенерируйте .env.
- Создайте playbook.
Рассмотрим каждый пункт подробнее.
Создание экземпляра Ubuntu Lightsail
Перейдите на панель управления Lightsail и нажмите «Создать экземпляр».
Выберите свою любимую ОС.
Выберите «Добавить скрипт запуска», который запускается после создания вашего экземпляра. Не забудьте получить SSH-ключ.
Установка зависимостей Ansible на нашем VPS
Добавьте эти sh-команды для установки зависимостей:
sudo add-apt-repository ppa:deadsnakes/ppa -y
sudo apt-get update
sudo apt-get install -y python2.7 python3 python-pip
Теперь у нас есть готовый экземпляр, перейдём к построению Ansible Project.
Добавление SSH-ключей в Git
Вы должны добавить свой сервер id_rsa.pub к своим ключам GitHub SSH, войдя в свой сервер.
# Подключитесь к вашему серверу через SSH и запустите
ssh-keygen
sudo chmod -R 644 .ssh/id_rsa
cat .ssh/id_rsa.pub
# Добавьте результат команды в аккаунт Git
# github settings=> SSH keys => Add new Key
# bitbucket settings=> ssh-keys => Add new Key
Сборка хостов и ansible.cfg
hosts.ini
[aws]
# Ваш IP сервера
127.0.0.39
ansible.cfg
[defaults]
hostfile = hosts.ini
# configure log dir
log_path= logs/ansible-log.log
Определение роли в Ansible
Используем модуль Ping, чтобы убедиться, что хост работает, после чего нужно обновить все пакеты и установить два модуля: git и htop.
---
- ping: ~
###
- name: Update apt packages
apt:
update_cache: yes
##
- name: Install GIT VCS
apt:
name: git
state: latest
##
- name: Install htop
apt: name=htop
Определение обработчика
---
- name: Restart PHP-FPM
service:
name: php{{php_version}}-fpm
state: restarted
####
- name: Restart Nginx
service:
name: nginx
state: restarted
Установка модулей PHP
Чтобы вызвать обработчик, мы должны использовать notify: Restart PHP-FPM, имена обработчиков должны быть уникальными.
В этом руководстве мы определили php как тег, поэтому, например, если вы хотите запустить только эту задачу из своего playbook, вам необходимо выполнить её с —tags = ”php”, которая будет исполнять только её.
---
- name: Install PHP {{php_version}} PPA Repo
apt_repository:
repo: 'ppa:ondrej/php'
tags:
- php
##
- name: Install PHP {{php_version}}
apt: name=php{{php_version}} state=latest
##
- name: Install PHP packages
become: true
apt:
name: "{{ item }}"
state: latest
with_items:
- php{{php_version}}-curl
- php{{php_version}}-fpm
- php{{php_version}}-intl
- php{{php_version}}-mysql
- php{{php_version}}-xml
- php{{php_version}}-mbstring
notify: Restart PHP-FPM
tags:
- php
Установка Nginx
- name: Install Nginx web server
apt:
name: nginx
state: latest
notify: Restart Nginx
tags:
- nginx
###
- name: Update nginx config files
become: true
template:
src: templates/nginx.conf
dest: "/etc/nginx/sites-available/default"
tags:
- nginx
notify: Restart Nginx
###
- name: link nginx config
become: true
file:
src: "/etc/nginx/sites-available/default"
dest: "/etc/nginx/sites-enabled/default"
state: link
tags:
- nginx
notify: Restart Nginx
Добавление default-конфигурации Nginx
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
server_name {{ server_name }};
root {{ app_work_dir }}public;
location / {
try_files $uri $uri/ /index.php?$args;
index index.php index.html index.htm;
}
if (!-d $request_filename) {
rewrite ^/(.*)/$ /$1 permanent;
}
location = /favicon.ico {
access_log off;
log_not_found off;
}
location ~ .php$ {
try_files $uri $uri/ /index.php?$args;
index index.php index.html index.htm;
fastcgi_pass unix:/var/run/php/php{{php_version}}-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME {{app_work_dir}}public$fastcgi_script_name;
fastcgi_param APPLICATION_ENV testing;
fastcgi_param PATH /usr/bin:/bin:/usr/sbin:/sbin;
fastcgi_intercept_errors on;
include fastcgi_params;
}
}
vars.yml
---
##@ref https://docs.ansible.com/ansible/latest/user_guide/playbooks_best_practices.html#variables-and-vaults
ansible_ssh_user: "ubuntu"
current_user: "ubuntu"
server_name: "app_name"
repo_git_url: "app_github_url"
ansible_ssh_private_key_file: "ssh_dir"
php_version: 7.2
app_work_dir: /var/www/app_name/
#mysql config
mysql_host: "mysql_host"
mysql_db: app_name
mysql_user: sql_user
mysql_pass: sql_pass
#other config
cache_driver: file
session_driver: file
app_env: production
app_debug: false
app_key: "your_app_key"
app_name: "app_name"
app_url: "your_app_url"
Примечание: Рекомендуется использовать ansible-vault для шифрования и дешифрования переменных.
Как использовать Ansible-Vault
Создайте секретный файл хранилища, содержащий ключ шифрования, который шифрует ваши переменные.
touch .vault_pass.txt
echo 'YOUR_CONFIG_PASS' > .vault_pass.txt
Чтобы зашифровать переменные, используйте:
ansible-vault encrypt group_vars/vars.yml --vault-password-file .vault_pass.txt
Чтобы расшифровать переменные, используйте:
ansible-vault decrypt group_vars/vars.yml --vault-password-file .vault_pass.txt
Создание базы данных MySql, имени пользователя и пароля
- mysql_user:
name: "{{mysql_user}}"
password: "{{mysql_pass}}"
priv: '*.*:ALL'
state: present
tags:
- mysql-db
##
- name: Create APP DB database
mysql_db: name="{{mysql_db}}" state=present login_user="{{mysql_user}}" login_password="{{mysql_pass}}"
mysql_user
и mysql_pass
определены внутри vars.yml.
Клонирование кодовой базы
- name: update repo - pull the latest changes
git:
repo: "{{repo_git_url}}"
dest: "{{app_work_dir}}"
update: yes
version: master
accept_hostkey: yes
key_file: /home/{{current_user}}/.ssh/id_rsa
tags:
- code-deploy
repo_git_url
и app_work_dir
определены внутри vars.yml.
Генерирование .env
Ansible использует шаблонизатор Jinja2 для динамических выражений и доступа к переменным. Создадим файл env.conf.
APP_ENV={{app_env}}
APP_DEBUG={{app_debug}}
APP_KEY={{app_key}}
APP_URL={{app_url}}
APP_NAME={{app_name}}
DB_HOST={{mysql_host}}
DB_DATABASE={{mysql_db}}
DB_USERNAME={{mysql_user}}
DB_PASSWORD={{mysql_pass}}
CACHE_DRIVER={{cache_driver}}
SESSION_DRIVER={{session_driver}}
Определим role
, чтобы переместить этот шаблон в директорию нашего приложения.
---
- name: Copy lara env file
become: true
template:
src: templates/env.conf
dest: "{{app_work_dir}}/.env"
tags:
- env-file
Создание playbook
---
- hosts: aws
#common options between modules
sudo: yes
gather_facts: no
vars_files:
- ./group_vars/vars.yml
roles:
- misc
- php
- mysql
- redis
- nginx
- bootstrap-app
- code-deploy
###
handlers:
- include: handlers/main.yml
Как видно, мы определили aws как хост для этого playbook, и sudo yes даёт нам возможность выполнять команду как пользователю sudo. У нас есть vars_files, где мы храним наши vars. Мы установили roles, каждая role выполняет определённую задачу. И, наконец, у нас есть handlers, которые содержат все обработчики проекта.
Запуск playbook
#ansible-playbook playbookName
ansible-playbook code-deploy.yml
# Запуск с конкретными тегами
ansible-playbook playbook.yml --tags="env-files,php"
# Если вы используете ansible-vault
ansible-playbook code-deploy.yml --vault-password-file .vault_pass.txt
Полная структура проекта
├── ansible.cfg
├── code-deploy.yml
├── files
│ └── dump.sql
├── group_vars
│ └── vars.yml
├── handlers
│ └── main.yml
├── hosts.ini
├── logs
│ └── ansible-log.log
├── roles
│ ├── bootstrap-app
│ │ └── tasks
│ │ └── main.yml
│ ├── code-deploy
│ │ ├── tasks
│ │ │ ├── config-files.yml
│ │ │ └── main.yml
│ │ └── templates
│ │ └── env.conf
│ ├── misc
│ │ └── tasks
│ │ └── main.yml
│ ├── mysql
│ │ └── tasks
│ │ ├── config.yml
│ │ └── main.yml
│ ├── nginx
│ │ ├── tasks
│ │ │ └── main.yml
│ │ └── templates
│ │ └── nginx.conf
│ ├── php
│ │ └── tasks
│ │ └── main.yml
│ └── redis
│ └── tasks
│ └── main.yml
├── scripts
│ ├── install_composer.sh
│ └── startup.sh
└── site.yml
Дополнительные материалы для начинающих изучать Ansible
- Репозиторий на GitHub, который содержит полный исходный код.
- Этот сайт запущен и работает с использованием этой кодовой базы.
- Советы по использованию Ansible playbooks.
- Описание архитектуры программы Ansible.
- Статья «How to Use Ansible to Automate Initial Server Setup on Ubuntu».
- О других инструментах сисадмина и DevOps читайте в нашей подборке.
Вадим Сычёв
Перевод статьи «Ansible In Action»