Community
3
HostiServer
2026-11-09 11:20

Ansible: архітектура, встановлення, inventory, ad-hoc команди

⏱️ Час читання: ~13 хвилин | 📅 Опубліковано: листопад 2026

Ansible: архітектура, встановлення, inventory та перші ad-hoc команди

У серії про Docker на VPS ми встановлювали Docker, налаштовували Compose, піднімали Nginx із SSL і навіть зібрали кластер Docker Swarm з кількох нод. Кожен із цих кроків ми виконували вручну: зайти по SSH, ввести команди, перевірити результат. Для одного сервера це нормально. Для трьох уже відчутно нудно. Для тридцяти це вже окрема робота: тридцять терміналів, тридцять разів однакові команди, і гарантія, що на якомусь сервері щось піде не так, а ви дізнаєтесь про це лише згодом.

Ansible вирішує саме цю задачу. Ви один раз описуєте бажаний стан серверів (які пакети встановлені, які сервіси працюють, які файли лежать на місці), а Ansible сам приводить до цього стану будь-яку кількість машин і за потреби повторює це щоразу однаково. Це перша стаття серії з десяти: ми розберемо, як Ansible влаштований, як його встановити, як описати свої сервери та як виконувати перші команди без жодного playbook. Далі серія пройде шлях від простих playbook до ролей, секретів, великих інфраструктур і автоматичного деплою з CI/CD.

1.1 Задача: десятки чи сотні серверів без ручної роботи

Адміністрування кількох серверів руками має три хронічні проблеми. По-перше, швидкість: кожна зміна множиться на кількість машин. По-друге, дрейф: сервери, налаштовані у різний час різними людьми, поступово стають різними, і ніхто вже не пам'ятає чому. По-третє, відтворюваність: коли потрібен ще один такий самий сервер, інструкція існує лише в чиїйсь голові чи в застарілому текстовому файлі.

Автоматизація конфігурації замінює ручні кроки описом, який можна зберегти в git, перевірити, переглянути й повторити.

1.2 Скрипти, Ansible чи Chef/Puppet/Salt

Є три типові підходи до цієї задачі, і вони відрізняються моделлю роботи, а не лише синтаксисом.

Підхід Як працює Агент на серверах Де виграє, де програє
Bash-скрипти Послідовність команд: «зроби це, потім це» Не потрібен Швидкий старт. Але повторний запуск часто ламає стан, а обробку помилок і різниці між дистрибутивами доводиться писати самому
Ansible Опис бажаного стану в YAML; модулі самі перевіряють, чи потрібна зміна Не потрібен: працює через SSH Низький поріг входу, нічого не треба встановлювати на сервери. Для дуже великих парків потрібне налаштування продуктивності (частина 8 серії)
Chef / Puppet / Salt Центральний сервер, на нодах працює агент, який сам регулярно звіряє стан Зазвичай потрібен (у Salt є і режим salt-ssh) Постійна самоперевірка стану і масштаб. Але своя мова чи DSL, окрема інфраструктура керування й агенти, які самі треба підтримувати

Для більшості команд із десятками серверів, VPS чи виділених машин, саме Ansible дає найкращий баланс між зусиллями на старті й користю від автоматизації.

1.3 Чотири ключові властивості

  • Agentless. На керованих серверах не потрібно нічого встановлювати: ні агента, ні демона. Достатньо SSH та Python.
  • Звичайний SSH як транспорт. Ansible використовує те, що вже є на кожному Linux-сервері. Для Windows-машин як керованих вузлів використовується WinRM (або SSH).
  • Ідемпотентність. Повторне виконання тієї самої задачі не ламає стан. Модуль перевіряє поточний стан, і якщо він уже відповідає бажаному, нічого не змінює й повідомляє «ok» замість «changed».
  • YAML як мова. Опис автоматизації читається без спеціальних знань, а отже його може прочитати й перевірити колега, який Ansible не писав.

Ідемпотентність варто розібрати на прикладі, бо саме вона відрізняє Ansible від скриптів. Команда echo "line" >> /etc/file у скрипті додасть рядок при кожному запуску, і після п'яти запусків файл матиме п'ять однакових рядків. Модуль Ansible, що описує «цей рядок має бути в цьому файлі», перевірить наявність рядка і додасть його лише один раз. Те саме з пакетами: state=present означає «має бути встановлений», а не «встановити ще раз».

⚠️ Ідемпотентність не безумовна. Вона є властивістю модулів, а не самого Ansible. Модулі command і shell виконують довільну команду і не можуть знати, чи змінила вона щось, тому щоразу звітують «changed». Для таких задач у Ansible є параметри creates і removes. Докладніше про вибір модулів поговоримо в частині 2.

ℹ️ Звідки ми прийшли: якщо ви ще не проходили серію про контейнери, її початок описаний у статті «Docker на VPS: встановлення і перший контейнер». Для Ansible вона не обов'язкова, але саме на її прикладі добре видно, скільки однакових ручних кроків накопичується, коли серверів кілька.

2. Архітектура: як це працює

2.1 Три компоненти

  • Control node. Машина, з якої ви запускаєте Ansible: ноутбук, CI-сервер або bastion host. Тут установлений Ansible, лежать inventory, playbook і SSH-ключі. Control node працює на Linux чи macOS; Windows підтримується лише через WSL.
  • Managed nodes. Цільові сервери, якими ви керуєте. На них потрібні тільки Python і доступ по SSH до звичайної POSIX-оболонки.
  • Inventory. Список і опис managed nodes: які в них імена та адреси, як до них підключатись і як вони згруповані.
Архітектура Ansible: control node підключається по SSH до managed nodes, згрупованих у webservers і databases

2.2 Що відбувається під час виконання

Кожне завдання проходить однаковий цикл:

  1. Control node підключається до сервера по SSH.
  2. Копіює на нього невеликий Python-модуль з потрібною логікою (у тимчасову директорію).
  3. Виконує модуль і збирає результат у JSON.
  4. Прибирає тимчасові файли.
  5. Повертає результат на control node, де Ansible показує вам статус: ok, changed чи failed.

Звідси випливає цікавий наслідок: оскільки модуль щоразу доставляється на сервер заново, на управлінні версіями жодних проблем не виникає. На самих серверах немає нічого, що довелося б оновлювати.

2.3 Чого на керованих серверах не потрібно

Ні агента, ні постійно працюючого демона, ні відкритого порту, окрім SSH. Це і спрощує підтримку (нічого оновлювати), і зменшує поверхню атаки (немає ще одного слухача на мережевому порту).

2.4 Зворотний бік: control node треба захищати

Control node тримає ключі від усього парку серверів, тож це критичний вузол. Практичні правила: використовуйте окремий SSH-ключ для автоматизації, захищайте його паролем (passphrase) чи тримайте в ssh-agent, обмежте, хто може входити на control node, і не зберігайте його приватний ключ на спільних машинах. Про управління секретами пізніше окремо поговоримо в частині 7 серії (Ansible Vault).

2.5 Вимоги до Python на керованих серверах

Модулі Ansible виконуються на сервері, тому потрібен Python. На більшості серверних образів Debian, Ubuntu, AlmaLinux чи Rocky він є з коробки. У мінімальних образах (контейнерах, деяких хмарних образах) його може не бути, і тоді доведеться поставити його до першого запуску. Виняток становлять мережеві модулі (вони працюють на боці control node, без Python на пристрої) та модуль raw, який виконує команду без Python і саме тому часто використовується для початкового встановлення Python.

3. Встановлення Ansible на control node

3.1 Два пакети: ansible і ansible-core

Перш ніж ставити, варто знати, що існує два пакети. ansible-core — мінімальний: сама мова, середовище виконання й вбудовані модулі. ansible — повніший пакет «з батарейками»: те саме плюс набір колекцій, відібраних спільнотою. Колекціям присвячена окрема частина серії (Ansible Galaxy та Collections, частина 6), а для початку підійде будь-який із двох; повний пакет зручніший, бо одразу містить більшість потрібних модулів.

3.2 Способи встановлення

Система Спосіб Примітки
Будь-який Linux, macOS (для CI-сервера та VPS: основний варіант) pipx install --include-deps ansible Ізольоване середовище, просте оновлення, не чіпає системний Python
Ubuntu Офіційний PPA ppa:ansible/ansible Містить новіші версії, ніж стандартні репозиторії
Debian Пакет ansible зі стандартного репозиторію або з Ubuntu PPA Версія зі стандартного репозиторію може бути застарілою
AlmaLinux / Rocky / CentOS Stream dnf після підключення EPEL Перевірте, яку версію надає EPEL, перед використанням у проєкті
Fedora dnf install ansible чи ansible-core Доступні обидва пакети
macOS brew install ansible Або через pipx, як і на Linux
Windows Лише в WSL Нативно як control node не підтримується

3.3 Рекомендація: pipx

Для CI-сервера та VPS ми радимо pipx. Це практичний вибір: Ansible ставиться в окреме віртуальне середовище, не конфліктує із системним Python і оновлюється однією командою. Офіційна документація називає основним способом pip, а pipx — поширеною альтернативою для випадків, коли pip недоступний через політику ОС. А на сучасних Debian та Ubuntu якраз так і буває: системний Python позначений як «externally managed», і pip install без додаткових прапорців там відмовляється працювати. Тому pipx тут природний вибір.

# Ubuntu / Debian
sudo apt update
sudo apt install -y pipx
pipx ensurepath

# AlmaLinux / Rocky (після підключення EPEL)
sudo dnf install -y pipx
pipx ensurepath

# Власне встановлення
pipx install --include-deps ansible

Після pipx ensurepath відкрийте новий термінал, щоб оновився PATH. Оновлення пізніше:

pipx upgrade --include-injected ansible

3.4 Установка з Ubuntu PPA

sudo apt update
sudo apt install -y software-properties-common
sudo add-apt-repository --yes --update ppa:ansible/ansible
sudo apt install -y ansible

Для Debian новіша версія ставиться з того самого PPA, але через ручне підключення репозиторію з ключем у /usr/share/keyrings/; точні кроки з відповідністю кодових імен Debian і Ubuntu є на офіційній сторінці установки для окремих ОС.

3.5 Перевірка

ansible --version
python3 --version

Команда ansible --version показує версію ansible-core, шлях до конфігураційного файлу, шлях до модулів і версію Python, під якою вона працює. Версію повного пакета ansible показує окрема команда ansible-community --version.

3.6 Версії та вимоги до Python

Станом на листопад 2026 поточна гілка повного пакета — ansible 14.x, що працює на ansible-core 2.21. Для цієї версії на control node потрібен Python 3.12–3.14, а на керованих серверах — Python 3.9–3.14. З цього випливають дві практичні речі:

  • Старий Python на control node. У деяких поширених дистрибутивах системний Python старший за 3.12 (наприклад, Ubuntu 22.04 чи Debian 12). Тоді варто встановити окремий новіший Python і вказати його pipx (pipx install --python python3.12 --include-deps ansible) або взяти старішу гілку ansible-core.
  • Дуже старі керовані сервери. Якщо на цільовій системі Python старший за 3.9, поточна версія ansible-core не зможе з нею працювати, і для таких машин потрібна старіша версія ansible-core.

Версії змінюються кілька разів на рік, тож перед установкою варто звірити таблицю підтримки на сторінці релізів офіційної документації Ansible.

⚠️ Не змішуйте способи встановлення. Якщо Ansible встановлений і через apt, і через pipx, у вас буде дві копії, і команда ansible запускатиме ту, що першою трапилась у PATH. Це типове джерело дивних помилок («у документації є цей параметр, а в мене немає»). Обирайте один спосіб і перевіряйте ansible --version після зміни.

4. SSH-ключі: безпарольний доступ

4.1 Чому паролі не працюють у масштабі

Ansible виконує дії на багатьох серверах одночасно, і запитувати пароль для кожного з'єднання неможливо. До того ж паролі для SSH гірші за ключі й з погляду безпеки: їх можна підібрати, вони потрапляють у історію команд і їх складно змінювати централізовано. Тому стандартний підхід — SSH-ключі.

4.2 Генерація ключової пари

Якщо окремого ключа для автоматизації ще немає, створіть його на control node:

ssh-keygen -t ed25519 -C "ansible-control" -f ~/.ssh/ansible_ed25519

Тип ed25519 — сучасний, короткий і швидкий. Утиліта запропонує задати passphrase. Для ключа, який керує всім парком серверів, passphrase бажаний: щоб не вводити його щоразу, додайте ключ в ssh-agent (ssh-add ~/.ssh/ansible_ed25519). На CI-сервері, де ключ використовується без участі людини, його зазвичай зберігають у секретах платформи, про що йтиметься в частині 10.

4.3 Розповсюдження публічного ключа

ssh-copy-id -i ~/.ssh/ansible_ed25519.pub admin@192.0.2.11

Цю команду треба виконати для кожного керованого сервера. Для початку підійде будь-який існуючий обліковий запис із правами sudo (у прикладі admin). Пізніше, у частині 4, ми створимо окремого користувача для автоматизації самим Ansible, а зараз головне — налаштувати доступ.

4.4 Перевірка вручну перед першим запуском

ssh -i ~/.ssh/ansible_ed25519 admin@192.0.2.11 "hostname && sudo -n true && echo sudo-ok"

Ця команда відповідає на три запитання одразу: чи працює вхід за ключем без пароля, чи правильне ім'я хоста і чи може користувач виконувати sudo без запиту пароля. Прапор -n змушує sudo завершитись помилкою замість запиту. Якщо вручну все працює, Ansible також запрацює. Якщо ні, проблему треба вирішувати зараз, а не посеред виконання завдання.

4.5 Привілеї: sudo без пароля чи з паролем

Більшість адміністративних задач потребують root-прав, які Ansible отримує через sudo (параметр become). Є два підходи:

  • Запитувати пароль sudo щоразу: додавайте до команд --ask-become-pass (-K). Безпечніше, але незручно для автоматизації.
  • Дозволити sudo без пароля для автоматизаційного користувача: зручно для CI і автоматичного деплою, але зменшує захист: хто отримає ключ, отримає й root.
echo 'admin ALL=(ALL) NOPASSWD:ALL' | sudo tee /etc/sudoers.d/ansible
sudo chmod 440 /etc/sudoers.d/ansible
sudo visudo -cf /etc/sudoers.d/ansible

Остання команда перевіряє синтаксис файлу: помилка в sudoers здатна заблокувати доступ до sudo, тому перевіряти варто завжди. Тримайте сесію з правами root відкритою, доки не переконаєтесь, що нове правило працює.

⚠️ Не використовуйте для Ansible прямий вхід під root. Звичайний обліковий запис із sudo залишає слід у журналах (видно, хто саме і що виконав) і дозволяє заборонити вхід root по SSH. Ця заборона — одне із завдань, які ми автоматизуємо в частині 4.

4.6 Параметри підключення

Якщо імена користувачів, порти чи ключі відрізняються між серверами, це описується параметрами хоста: ansible_user (хто підключається), ansible_port (нестандартний порт SSH), ansible_ssh_private_key_file (який ключ використати). Їх задають у inventory або в конфігурації, і про це йдеться далі.

4.7 Перше підключення і known_hosts

При першому підключенні SSH питає, чи довіряєте ви відбитку ключа сервера. В автоматизації це питання зупиняє виконання. Правильний вихід — додати відбитки заздалегідь:

ssh-keyscan -H 192.0.2.11 192.0.2.12 198.51.100.21 >> ~/.ssh/known_hosts

Зверніть увагу: ssh-keyscan довіряє тому, що відповів сервер у момент запиту. Для чутливих систем звірте відбитки (ssh-keygen -lf) з тими, що показує панель провайдера чи консоль сервера. Вимикати перевірку ключів хоста замість цього не варто, чому саме, розглянемо в розділі про ansible.cfg.

5. Inventory: описуємо інфраструктуру

Inventory — це «карта» вашого парку: які сервери є, як вони називаються, як до них підключитись і як вони згруповані. Ansible не вгадує, куди підключатись: він працює лише з тими вузлами, які описані в inventory.

5.1 Два формати: INI і YAML

Ansible підтримує обидва формати «з коробки». INI простіший і коротший, YAML краще масштабується й зручніший, коли в хостів багато змінних. Один і той самий парк в INI:

[webservers]
web1 ansible_host=192.0.2.11
web2 ansible_host=192.0.2.12

[databases]
db1 ansible_host=198.51.100.21 ansible_port=2222

[production:children]
webservers
databases

[all:vars]
ansible_user=admin
ansible_python_interpreter=/usr/bin/python3

І в YAML:

all:
  vars:
    ansible_user: admin
    ansible_python_interpreter: /usr/bin/python3
  children:
    webservers:
      hosts:
        web1:
          ansible_host: 192.0.2.11
        web2:
          ansible_host: 192.0.2.12
    databases:
      hosts:
        db1:
          ansible_host: 198.51.100.21
          ansible_port: 2222
    production:
      children:
        webservers:
        databases:

Адреси в прикладах — із діапазонів, зарезервованих для документації (192.0.2.0/24 і 198.51.100.0/24), підставте свої.

5.2 Групи нод

Групи — головний інструмент inventory: вони дозволяють звертатись до багатьох серверів однією назвою. Дві групи є завжди без жодного опису: all (усі хости) і ungrouped (хости, які не входять до жодної іншої групи). Кожен хост належить принаймні до однієї з них.

5.3 Вкладені групи

В INI вкладеність задається суфіксом :children у заголовку групи (як у прикладі [production:children]), у YAML — ключем children. Хост із дочірньої групи автоматично належить і батьківській: web1 входить і до webservers, і до production. Це зручно для того, щоб описувати окремі середовища: наприклад, групи staging і production, кожна зі своїми webservers. Циклічні зв'язки між групами заборонені.

5.4 Змінні рівня inventory

Параметри, що визначають, як підключатись:

  • ansible_host — реальна адреса чи DNS-ім'я, якщо воно відрізняється від імені хоста в inventory (у прикладі web1 — це просто зручна назва);
  • ansible_port — порт SSH, якщо він не 22;
  • ansible_user — користувач для підключення;
  • ansible_python_interpreter — шлях до Python на сервері. Явне значення прибирає попередження про автоматично знайдений інтерпретатор і запобігає помилкам на системах із кількома версіями Python.

Змінні, оголошені в секції [all:vars], діють для всіх хостів; змінні групи (наприклад, [webservers:vars]) — лише для її членів; змінні в рядку хоста мають найвищий пріоритет серед цих трьох. Повну систему пріоритетів змінних ми розберемо в частині 3.

5.5 Діапазони хостів

Для однотипних серверів не треба перелічувати кожен: запис web[01:50].example.com створить п'ятдесят хостів від web01 до web50. Крок задається третім числом (web[01:50:2] дасть лише непарні), підтримуються й літерні діапазони (db-[a:f].example.com).

5.6 Де зберігати inventory

  • Один файл — достатньо для невеликого парку. Просто, видно все й одразу.
  • Директорія (наприклад, inventory/ з кількома файлами): Ansible читає всі файли в ній за алфавітом. Зручно, коли парк росте або коли частина inventory генерується автоматично (до цього ми дійдемо в частині 9 про динамічний inventory). Якщо одна змінна визначена у кількох файлах, виграє остання за алфавітним порядком, тому порядок файлів можна контролювати префіксами (01-, 02-).

У будь-якому випадку зберігайте inventory в git разом з іншим кодом автоматизації, але без паролів і ключів у відкритому вигляді.

5.7 Перевірка inventory

ansible-inventory -i inventory/hosts.ini --list
ansible-inventory -i inventory/hosts.ini --graph

Перша команда виводить усе, що Ansible «розуміє» про ваші хости, у форматі JSON, включно зі змінними. Друга показує дерево груп. Для прикладу вище воно виглядатиме приблизно так:

@all:
  |--@production:
  |  |--@databases:
  |  |  |--db1
  |  |--@webservers:
  |  |  |--web1
  |  |  |--web2
  |--@ungrouped:

Звикайте виконувати цю перевірку після кожної зміни inventory: вона одразу показує помилки в групах і змінних, до того як вони обернуться «чужою» поведінкою на серверах.

6. ansible.cfg: базова конфігурація

6.1 Де Ansible шукає конфіг

Ansible перебирає чотири місця в такому порядку й використовує перший знайдений файл. Інші файли ігноруються, їх вміст не зливається:

  1. Файл, вказаний у змінній середовища ANSIBLE_CONFIG, якщо вона задана;
  2. ansible.cfg у поточній директорії (проєктний конфіг);
  3. ~/.ansible.cfg у домашній директорії;
  4. /etc/ansible/ansible.cfg (загальносистемний).

Для проєктів майже завжди найкращий варіант — другий: ansible.cfg лежить у корені репозиторію разом з inventory і playbook, і всі, хто працює з репозиторієм, отримують однакові налаштування. Яку саме конфігурацію Ansible зараз використовує, показує рядок config file у виводі ansible --version.

⚠️ Конфіг із каталогу, доступного всім на запис, ігнорується. Ansible не завантажує ansible.cfg з поточної директорії, якщо вона world-writable: інакше інший користувач системи міг би підкласти свій файл і керувати вашими запусками. Якщо ваш конфіг «не підхоплюється», перевірте права на каталог (ls -ld .).

6.2 Ключові параметри

[defaults]
inventory = ./inventory/hosts.ini
remote_user = admin
private_key_file = ~/.ssh/ansible_ed25519
host_key_checking = True
  • inventory — шлях до inventory за замовчуванням, щоб не вказувати -i у кожній команді;
  • remote_user — користувач для підключення, якщо він не вказаний у inventory;
  • private_key_file — ключ за замовчуванням;
  • host_key_checking — перевірка відбитків ключів хостів (за замовчуванням увімкнена).

Перевірити, які параметри ви змінили відносно значень за замовчуванням, можна командою ansible-config dump --only-changed.

6.3 Чому host_key_checking = False тільки для тестів

Багато інструкцій радять вимкнути перевірку ключів хостів, щоб прибрати питання про довіру при першому підключенні. Це працює, але повністю знімає захист від підміни сервера (man-in-the-middle): Ansible погодиться підключитись до будь-кого, хто відповість за потрібною адресою, і передасть йому все, що ви надсилаєте на сервер, включно з файлами й змінними. Для експериментів на тимчасових віртуальних машинах це прийнятно. Для production правильний шлях — розділ 4.7: заздалегідь додати відбитки у known_hosts і залишити перевірку ввімкненою.

7. Ad-hoc команди: Ansible без playbook

Ad-hoc команда — це одна дія, виконана на одному чи кількох серверах прямо з командного рядка, без написання playbook. Для разових операцій це найшвидший спосіб.

7.1 Синтаксис

ansible <pattern> -m <module> -a "<аргументи>"

Три частини: pattern (до кого застосувати), модуль (що зробити) і аргументи модуля. Якщо модуль не вказано, використовується ansible.builtin.command.

7.2 Pattern: на які хости діяти

Pattern Що означає
all Усі хости з inventory
webservers Усі хости групи
web1 Один конкретний хост
web* Wildcard: усі, чиї імена починаються з «web»
webservers:databases Об'єднання груп (або одна, або інша)
production:&webservers Перетин: хости, що входять в обидві групи
webservers:!web2 Виключення: усі з групи, крім web2

Для виключення в оболонці bash символ ! зазвичай треба брати в одинарні лапки: ansible 'webservers:!web2' -m ping, інакше оболонка спробує розкрити його як посилання на історію команд. Додатково будь-який pattern можна звузити опцією --limit (-l), наприклад -l web1.

7.3 Корисні модулі для щоденних задач

Модуль Призначення Приклад аргументів
ping Перевірка, що Ansible може підключитись і виконати Python на сервері без аргументів
command Виконати команду без оболонки (без каналів і перенаправлень) -a "uptime"
shell Виконати команду через оболонку (дозволені |, >, змінні) -a "df -h | head -5"
copy Скопіювати файл із control node на сервер -a "src=./motd dest=/etc/motd mode=0644"
fetch Забрати файл із сервера на control node -a "src=/etc/os-release dest=./fetched/"
service Керувати сервісами -a "name=nginx state=restarted"
apt / dnf Керувати пакетами на Debian/Ubuntu або RHEL-подібних -a "name=nginx state=present"

Модуль ping не має нічого спільного з ICMP-пінгом: він справді входить на сервер по SSH, запускає невеликий Python-код і повертає «pong». Тому вдала відповідь означає, що працюють і SSH-доступ, і Python, і права, і це набагато більше, ніж «сервер відповідає на мережу».

7.4 Приклади

# Чи доступні всі сервери
ansible all -m ping

# Аптайм усіх вебсерверів (command за замовчуванням)
ansible webservers -a "uptime"

# Вільне місце, пайп потребує shell
ansible all -m ansible.builtin.shell -a "df -h / | tail -1"

# Перезапуск Nginx з правами root
ansible webservers -b -m ansible.builtin.service -a "name=nginx state=restarted"

# Факти про систему (фільтр за назвою)
ansible web1 -m ansible.builtin.setup -a "filter=ansible_distribution*"

Опція -b (--become) вмикає підвищення привілеїв через sudo. Додатково знадобляться -u (підключитись іншим користувачем), -i (вказати inventory, якщо його немає в конфігурації) та -K (запитати пароль sudo).

7.5 Режим перевірки: --check

Прапор --check (-C) запускає «репетицію»: Ansible показує, що зробив би, але нічого на серверах не змінює. Він добре працює з модулями, які вміють передбачати результат (apt, copy, service та інші). Але command і shell у режимі перевірки зазвичай пропускаються, бо Ansible не може знати, що зробить довільна команда. Тому репетиція не є універсальною гарантією безпеки, її корисно застосовувати разом із перевіркою на одному сервері.

7.6 Паралелізм: forks

За замовчуванням Ansible працює з п'ятьма серверами одночасно (параметр forks). Для парку з сотні машин це означає двадцять послідовних «хвиль». Збільшити паралелізм для окремого запуску можна опцією -f:

ansible all -f 20 -m ping

Більше — не завжди краще: кожен fork споживає пам'ять і з'єднання на control node, а надто агресивне значення може впертись в ліміти SSH чи в мережу. Тонке налаштування продуктивності (forks, pipelining, SSH multiplexing) ми розберемо в частині 8.

8. Перший реальний сценарій

Зведемо розібране в один практичний сценарій: перевірити парк, подивитись стан і безпечно оновити пакети на вебсерверах.

8.1 Крок 1: чи все доступне

ansible all -m ping

Успішна відповідь виглядає так:

web1 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

Поки ping не проходить на всіх вузлах, далі йти немає сенсу.

8.2 Крок 2: перевірка uptime на всіх нодах

ansible all -a "uptime"
web1 | CHANGED | rc=0 >>
 12:41:03 up 12 days, 3:07, 1 user, load average: 0.08, 0.03, 0.01

Зверніть увагу на слово CHANGED, хоча команда uptime нічого не змінила. Це та сама властивість модуля command із розділу 1: він не знає, чи змінила команда стан, тому завжди звітує «changed». Це не помилка, а нагадування, що для справді ідемпотентних дій потрібні профільні модулі, а не command.

8.3 Крок 3: оновлення пакетів на вебсерверах

Спершу репетиція на одному сервері, потім реальний запуск на ньому ж, і лише після цього на всіх:

# Debian / Ubuntu: репетиція на одному хості
ansible webservers -l web1 -b -m ansible.builtin.apt -a "update_cache=yes upgrade=dist" --check

# Реальний запуск на одному хості
ansible webservers -l web1 -b -m ansible.builtin.apt -a "update_cache=yes upgrade=dist"

# Після перевірки: на всіх вебсерверах
ansible webservers -b -m ansible.builtin.apt -a "update_cache=yes upgrade=dist"

# Для RHEL-подібних систем
ansible webservers -b -m ansible.builtin.dnf -a "name='*' state=latest"

Така послідовність («canary»: спочатку один, потім усі) — звичка, яка рятує від ситуації, коли проблемне оновлення одночасно кладе весь парк. Для production-серверів у частині 8 ми розберемо директиву serial, що автоматизує поступове оновлення групами.

8.4 Як читати вивід

Статус Що означає Що робити
SUCCESS (ok) Завдання виконане, стан уже відповідав бажаному, змін немає Нічого
CHANGED Завдання виконане і щось змінило (або модуль не може цього визначити) Переконатись, що це змінення очікуване
UNREACHABLE Не вдалось підключитись до сервера Перевірити мережу, порт, ключ, користувача, відбиток у known_hosts; спробувати той самий ssh вручну
FAILED Підключення є, але завдання завершилось помилкою Прочитати поле msg: типові причини — відсутній -b для задач, які потребують root, не встановлений Python, помилка в аргументах модуля

Найчастіша плутанина в початківців: UNREACHABLE означає проблему з доступом (SSH), а FAILED — проблему з виконанням (модуль, права, Python). Це різні класи несправностей, і діагностика починається з різних місць.

9. Обмеження ad-hoc і що далі

9.1 Де ad-hoc закінчується

Ad-hoc команди ідеальні для разових операцій: перевірити доступність, подивитись версію, перезапустити сервіс, зібрати факти. Але вони не підходять для повторюваних сценаріїв: послідовність дій не зберігається, логіка («якщо сталась зміна, перезапусти сервіс») не виражається, а результат неможливо перевірити чи переглянути в git. Як тільки ви ловите себе на тому, що вводите ту саму довгу команду втретє, настав час для playbook.

9.2 Що ми зробили в цій статті

  • Зрозуміли, як влаштований Ansible: control node, managed nodes, inventory, виконання через SSH без агента.
  • Встановили його на control node і розібрались у версіях та вимогах до Python.
  • Налаштували безпарольний доступ за ключами та підготували сервери до автоматизації.
  • Описали парк серверів в inventory з групами і змінними.
  • Налаштували ansible.cfg, не вимикаючи перевірку ключів хостів.
  • Виконали перші ad-hoc команди і навчились читати їхній вивід.

9.3 Що далі в серії

Наступна стаття присвячена playbook: файлам, які описують послідовність завдань, дозволяють використовувати handlers (перезапуск сервісу лише після зміни конфігурації), цикли й теги. Саме там з'явиться справжня ідемпотентна автоматизація. Далі серія піде від змінних і шаблонів Jinja2 до практичного налаштування реального VPS (частина 4: nginx, firewall, SSH-ключі, користувачі), ролей, Ansible Galaxy, Vault для секретів, масштабування до сотень вузлів, динамічного inventory й, нарешті, автоматичного деплою через Forgejo чи GitHub Actions. Для тих, хто захоче заздалегідь познайомитись із CI/CD, початок цієї теми розібраний у статті «Що таке CI/CD: від ручного deploy до автоматизованих pipelines».

📚 Навігація серії:
Ви читаєте частину 1 з 10 «Ansible: архітектура, встановлення, inventory та перші ad-hoc команди».
Далі: Частина 2. Ansible playbooks: tasks, modules, handlers, loops і теги →

🚀 Сервери для вашого Ansible-парку

Для старту з Ansible потрібні лише дві речі: невеликий сервер під control node і одна-дві машини, якими він керуватиме. Hostiserver дає ресурси, на яких можна безпечно експериментувати і з яких пізніше виростає повноцінна інфраструктура.

🖥️ Виділені Сервери

  • Від $90/міс, повний контроль над залізом для важких навантажень
  • Без сусідів по ресурсах: передбачувана продуктивність для баз даних і build-вузлів
  • 24/7 підтримка: допоможемо з мережею та SSH-доступом між вашими серверами

💻 Cloud (VPS) Хостинг

  • Від $19.95/міс, KVM-ізоляція, виділені vCPU і RAM
  • Повний root-доступ: Ansible отримує потрібні права без обхідних шляхів
  • Однакові тарифи на кілька VPS: зручно створювати тестовий парк з однотипних нод
  • Легко масштабувати: додали ще один сервер у inventory, і він під керуванням

💬 Не впевнені, який варіант потрібен?
💬 Напишіть нам — допоможемо з вибором!

Часті запитання

Чим Ansible кращий за звичайні bash-скрипти?

Скрипт описує послідовність дій, а Ansible — бажаний стан. Модуль Ansible спершу перевіряє, чи потрібна зміна, тому повторний запуск не ламає систему й не дублює результат (ідемпотентність). Крім того, один і той самий опис працює на різних дистрибутивах: модулі самі враховують відмінності, які в скрипті довелося б обробляти вручну. Скрипти лишаються доречними для дуже простих разових задач.

Чи потрібно щось встановлювати на керованих серверах?

Ні агента, ні демона. Потрібні лише SSH-доступ і Python (для більшості модулів). На стандартних серверних образах Debian, Ubuntu, AlmaLinux чи Rocky Python вже є. Якщо його немає, початкове встановлення можна виконати модулем raw, який працює без Python: ansible all -m raw -a "apt install -y python3" -b. Мережеві модулі виконуються на боці control node й Python на самому пристрої не потребують.

Чи можна запускати Ansible з Windows?

Нативно Windows як control node не підтримується. Варіант — WSL (Windows Subsystem for Linux), у якому Ansible працює як на звичайному Linux. Керувати Windows-серверами як managed nodes можна, але для них використовується WinRM (або SSH), і це окрема тема, яку в цій серії ми не розглядаємо.

Ansible повертає UNREACHABLE. З чого почати діагностику?

Спробуйте те саме підключення вручну: ssh -i ключ користувач@адреса. Якщо вручну не працює, проблема в мережі, порту, ключі чи користувачі, і Ansible тут нічого не вирішить. Якщо вручну працює, а в Ansible ні, перевірте ansible_user, ansible_port і ansible_host у inventory (команда ansible-inventory --list покаже, що Ansible «бачить»), а також наявність відбитка хоста в known_hosts. Для детальної діагностики додайте до команди прапор -vvv.

Pipx, apt чи pip: як краще встановити Ansible?

Для CI-сервера і VPS ми радимо pipx: ізольоване середовище, просте оновлення, жодних конфліктів із системним Python (на сучасних Debian і Ubuntu pip install без додаткових прапорців там блокується). Пакет із PPA чи репозиторію ОС теж допустимий, особливо якщо ви хочете оновлення разом з іншими пакетами системи. Головне правило: обрати один спосіб і не змішувати, інакше у вас опиниться дві копії Ansible.

Чи безпечно давати користувачу sudo без пароля для Ansible?

Це компроміс. Sudo без пароля потрібне для автоматичного запуску без участі людини (CI/CD), але той, хто отримає SSH-ключ цього користувача, отримує й root. Зменшують ризик так: окремий ключ лише для автоматизації, захист ключа passphrase чи сховищем секретів, обмеження доступу до control node, доступ по SSH тільки з потрібних адрес. Для ручних запусків можна обійтись паролем: опція --ask-become-pass (-K).

Чи потрібен окремий сервер під control node?

Ні, на початку підійде ваш ноутбук чи будь-яка Linux-машина з доступом до серверів. Окремий сервер (bastion чи CI-вузол) має сенс, коли з Ansible працює кілька людей або запуски відбуваються автоматично. Тоді він стає єдиною точкою, де зберігаються ключі та inventory, і її легше захистити й контролювати. Невеликий VPS для цього зазвичай достатньо.

Contents

Поділіться цією статтею

VPS з підтримкою від

$19 95 / міс

Виділені сервери від

$80 / міс

CDN починаючи від

$0 / міс

 

Користуючись цим сайтом, ви погоджуєтеся на використання файлів cookies відповідно до нашої Політики Конфіденційності.