← Ansible
12 мин · средне · Урок 4 из 12

Запуск без Python на хосте

Managed node обычно требует python. Модуль raw, gather_facts: no, bootstrap python и модуль script.

Почему Ansible требует Python на хосте

Большинство модулей Ansible — это Python-код. Когда ты запускаешь задачу, Ansible копирует маленький Python-скрипт на managed node и выполняет его там. Цепочка такая:

  1. Control node формирует Python-модуль с аргументами.
  2. Копирует его на хост через SCP/SFTP.
  3. Запускает /usr/bin/python3 /tmp/.ansible/...module.py.
  4. Получает JSON-ответ обратно.

Если на хосте нет Python, шаг 3 падает сразу. Это классическая проблема при работе со свежими minimal-образами, сетевым железом или контейнерами без Python.

control node ansible обычный модуль копирует .py module.py нет python3 task failed! raw SSH напрямую bash / sh python не нужен модуль raw

Модуль raw

raw выполняет команду прямо через SSH, без каких-либо Python-модулей на той стороне. Это прямой SSH-вызов команды.

ansible all -m raw -a "uptime"
ansible all -m raw -a "cat /etc/os-release"

Когда нужен raw:

raw понимает все обычные флаги инвентаря и параметры подключения.

gather_facts: no

Перед запуском задач Ansible собирает факты о хосте: запускает модуль setup, который узнаёт ОС, IP-адреса, дисковое пространство и т.д. Этому модулю тоже нужен Python.

На хосте без Python сборка фактов падает с ошибкой ещё до первой задачи. Лечение:

- name: bootstrap host without Python
  hosts: newservers
  gather_facts: no    # <-- отключаем, пока Python не поставлен
  tasks:
    - name: check connectivity
      raw: uptime

После того как Python установлен, можно запустить gather_facts явно через модуль setup, или просто перестать отключать его.

Bootstrap Python через raw

Классический приём — первым шагом поставить Python через raw, а потом работать обычными модулями:

- name: bootstrap Python3 on Debian/Ubuntu
  hosts: newservers
  gather_facts: no
  become: yes
  tasks:
    - name: install python3
      raw: apt-get update -y && apt-get install -y python3
      changed_when: false   # raw не умеет определять changed сам

    - name: gather facts
      setup:

    - name: install nginx
      apt:
        name: nginx
        state: present

После setup становятся доступны все переменные ansible_facts.* и обычные модули работают штатно.

На RHEL/Rocky/AlmaLinux замени apt-get на dnf install -y python3.

Модуль script

script — ещё один способ работать без Python. Он копирует локальный скрипт на хост и выполняет его через интерпретатор (по умолчанию /bin/sh; можно задать другой через shebang или executable). Python на той стороне не нужен.

- name: run init script
  script: files/bootstrap.sh
  args:
    creates: /etc/myapp/.bootstrapped   # не запускать повторно если файл есть

Отличия от raw:

Отличия от command и shell:

Честно про raw и script

raw и script — инструменты для крайних случаев. Они не возвращают нормальный changed/ok/failed статус в том смысле, в котором это делают обычные модули. При успехе (rc 0) raw всегда возвращает changed, даже если ничего не изменилось (а при ненулевом коде возврата — failed). Поэтому приходится ставить changed_when: false вручную.

Именно поэтому их используют точечно: поставить Python, инициализировать хост, сделать то, для чего нет нормального модуля. Дальше переходим на нормальные модули, которые умеют проверять текущее состояние.

Что важно запомнить

Ansible-модули — это Python-код; нет Python на хосте — нет нормальных модулей.

raw выполняет команду через SSH без Python. gather_facts: no отключает сбор фактов, который тоже требует Python.

Bootstrap через raw: сначала ставим python3, потом запускаем setup, потом работаем обычными модулями.

script копирует локальный sh-скрипт и запускает его без Python на хосте. raw и script не идемпотентны, поэтому используй их точечно для bootstrap, а не как замену нормальным модулям.

В следующем уроке — идемпотентность и почему bashible — плохо.

Дрилл · вопросы как на собесе

Проверь себя без подсказок

Сформулируй ответ вслух или письменно, потом раскрой и честно отметь: знал или нет.

01

Что такое Ansible facts, как их собирать и отключать (`gather_facts: false`)?

ANS-009
02

`gather_facts` занимает 40% времени playbook. Что делать, кроме `gather_facts: false`?

ANS-032

Прошли материал до конца? Отметьте урок пройденным.