
---
## Зочем?
:::info
Для управления состоянием ОС и ПО
:::
(in stateful operating systems)
(unlike NixOS)
---
* Автоматическая настройка хост-машин
* Декларативное описание состояния (конфиги, пакеты, сервисы, и т.д.)
* Или императивное выполнение рутинных действий (бэкапирование, обновление, и т.д.)
* Внесение изменений на группе хостов одной командой.
* Всё, что вы делаете вручную по SSH/WinRM, можно автоматизировать через Ansible.
---
## Зачем управлять состоянием хост-машин, если есть контейнеры?
---
* Что-то всё равно придётся делать на хосте (оркестратор, реверс-прокси, обновления пакетов, и т.д.)
* С помощью Ansible можно установить и настроить podman/docker!
* Можно и контейнеры деплоить (нечто среднее между оркестратором и ручным деплойментом)
* Первоначальная настройка новых хостов (linux юзеры, ssh-ключи, CA, и т.д.)
---
## Как это работает
```graphviz
digraph {
rankdir=LR
splines=ortho
inventory
playbook
cli [shape=parallelogram]
"ansible-playbook" [shape=box]
inventory -> "ansible-playbook"
playbook -> "ansible-playbook"
cli -> "ansible-playbook"
"target-host-1" [shape=box3d]
python1 [shape=box label=python]
"ansible-playbook" -> "target-host-1" [label="ssh user@target-host-1"]
"target-host-1" -> "python1"
"target-host-2" [shape=box3d]
python2 [shape=box label=python]
"ansible-playbook" -> "target-host-2" [label="ssh user@target-host-2"]
"target-host-2" -> "python2"
"target-host-N" [shape=box3d]
pythonN [shape=box label=python]
"ansible-playbook" -> "target-host-N" [label="ssh user@target-host-N"]
"target-host-N" -> "pythonN"
}
```
:::info
`python` используется исключительно под капотом
и ~~почти~~ не торчит в юзерспейс
:::
(ну не на /bin/sh же такую сложную систему писать)
---
## Live Coding
- SSH into; install `cowsay` manually; remove
- Prepare [inventory](https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html): `inventory.yml`
- Display [facts](https://docs.ansible.com/ansible/latest/user_guide/playbooks_vars_facts.html):
- `ansible -i inventory.yml example -m setup`
- Prepare [playbook](https://docs.ansible.com/ansible/latest/user_guide/playbooks_intro.html#playbooks-intro) `web_cow.yml`
- Install `cowsay` with [ansible.builtin.apt](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/apt_module.html)
- rerun
---
## Playbooks and plays
```graphviz
graph playbooks {
node [shape=box]
subgraph cluster {
label="playbook"
subgraph cluster_1 {
label=play1
play1_task2 [label=task2]
play1_task1 [label=task1]
play1_hosts [label=hosts shape=box3d]
}
}
}
```
> play решает
> что исполняется
> на каких хостах
---
## Почему нельзя вписать hostname сразу в play?
(без инвентаря)
---
По аналогии с MVC, Ansible проводит чёткую грань между **хостами** и **действиями**.
* В `inventory` лежат:
* Сетевые адреса хостов и хост-специфичные переменные
* Группы хостов (по интересам)
* В `play` описано:
* Что делать
* Где делать (имена и/или группы из инвентаря)
---
Ansible заточен на работу с группами однотипных хостов. Инвентарь должно быть всегда возможно подменить на другой без потерь.
:::info
Хосты -- это скот, а не домашние животные.
:::
---
- В `tasks` можно использовать `vars`, `files`, `templates`, `handlers`, etc.
- Это всё стоило бы хранить в отдельных файлах. Во имя чистоты `play`
- Очень легко превратить репозиторий с помойку
:::danger
#### Проблема
Нужно больше структуризации
(помимо разделения на хосты и действия)
:::
---
## Решение:
## Roles and directory layout
---
```graphviz
graph playbooks {
node [shape=box]
subgraph cluster {
label="playbook"
subgraph cluster_3 {
label=play2
play1_task2 [label=task2]
play1_task1 [label=task1]
play1_hosts [label=hosts shape=box3d]
}
subgraph cluster_4 {
label=play1
play2_hosts [label=hosts shape=box3d]
subgraph cluster_2 {
label=role2
role2_task2 [label=task2]
role2_task1 [label=task1]
}
subgraph cluster_1 {
label=role1
role1_task1 [label=task1]
}
}
}
}
```
[Roles](https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html) let you automatically load related `vars_files`, `tasks`, `handlers`, and other Ansible artifacts based on a known file structure.
Once you group your content in **roles**, you can easily reuse them and share them with other users.
---
[Гайдлайны по организации репозитория с плэйбуками](https://docs.ansible.com/ansible/2.8/user_guide/playbooks_best_practices.html#directory-layout) позволяют не превратить его в помйку.
---
[](https://viewer.diagrams.net/?highlight=0000ff&edit=https%3A%2F%2Fapp.diagrams.net%2F%23G18Sxolh6zfxO5UFIeZp0Bvr4j4R8fCcEV&nav=1&title=ansible.drawio#Uhttps%3A%2F%2Fdrive.google.com%2Fuc%3Fid%3D18Sxolh6zfxO5UFIeZp0Bvr4j4R8fCcEV%26export%3Ddownload)
---
## Live Coding
---
## Live Coding
- systemd service example (manual)
- `cowsay` already installed
- create `/opt/web_cow.py`
- create `/etc/systemd/system/web_cow.service`
- `# systemctl daemon-reload && systemctl enable web_cow && service web_cow start`
---
## Live Coding
- systemd service example (ansible)
- apply directory layout
- create `/opt/web_cow.py`
- create `/etc/systemd/system/web_cow.service`
- `# systemctl daemon-reload && systemctl enable web_cow && service web_cow start`
- `web_cow.service.j2` (add parameter)
- restart on config change (signal)
---
Update the service
---
## AWX
А сomputer with `ansible-playbook` and Web GUI.
---
## Ansible Galaxy
Community roles repository.
Менеджер пакетов для Ansible-ролей.
Если нужно развернуть на bare-metal нечто популярное, скорее всего, для этого уже есть готовая роль в galaxy.
Главный минус: Роли из galaxy обычно довольно сложные, поддерживают кучу всего и плохо поддаются ревью.
---
## [Хорошая статья](https://habr.com/ru/post/508762/)
<style>
div.graphviz {
background-color: transparent;
}
div.graphviz svg {
filter: invert(90%);
}
p > code {
background-color: rgba(230, 230, 230, 0.36);
border-radius: 3px;
padding: 0 0.2em;
}
</style>
{"title":"Ansible","slideOptions":"{\"transition\":\"slide\",\"width\":\"85%\"}","description":"Uploading file…_1qnbe05lz","contributors":"[{\"id\":\"5874e258-71fc-40da-8cad-f926475fd9c8\",\"add\":7958,\"del\":1216,\"latestUpdatedAt\":1762096029754}]"}