Что такое условия (conditionals) в Ansible playbook?

Ответ

Условия в Ansible — это механизм, позволяющий выполнять задачи, плейбуки, роли или включать файлы только при соблюдении определённых критериев. Это основа для создания адаптивных и идемпотентных конфигураций, работающих в разных окружениях.

Основной директивой является when.

Пример 1: Зависимость от фактов об ОС

- name: Install Apache on CentOS/RHEL
  yum:
    name: httpd
    state: present
  when: ansible_facts['os_family'] == "RedHat"

- name: Install Apache on Ubuntu/Debian
  apt:
    name: apache2
    state: present
  when: ansible_facts['os_family'] == "Debian"

Пример 2: Проверка результата предыдущей задачи (использование registered variables)

- name: Check if a service is running
  command: systemctl is-active nginx
  register: nginx_status
  ignore_errors: yes
  changed_when: false

- name: Restart Nginx if it was active
  systemd:
    name: nginx
    state: restarted
  when: nginx_status.rc == 0

Пример 3: Комбинирование условий и проверка переменных

- name: Deploy configuration only for production servers in the EU region
  template:
    src: app_config.j2
    dest: /etc/app/config.conf
  when:
    - env == "production"
    - region == "eu-west-1"
    - deploy_config | bool  # Проверка, что переменная истинна

Важные моменты:

  • Условия when оцениваются для каждого хоста в инвентаре отдельно.
  • Можно использовать выражения Jinja2, логические операторы (and, or, not), тесты (is defined, match).
  • Условия также применяются к директивам include_*, import_* и блокам block.

Ответ 18+ 🔞

Э, слушай, смотри, как оно работает. Условия в Ansible — это такая хитрая жопа, которая решает, выполнять тебе задачу или нет. Ну, типа, если звезды сошлись, окружение правильное и переменная не обосралась — тогда давай, работай. А если нет — сиди, не рыпайся. Основа всего — эта директива when. Запомни её, как своё имя.

Пример 1: Когда система — не просто система, а конкретная мартышлюшка Ты же не будешь на Debian через yum ставить? Правильно, ёпта. Вот и Ансибл тоже не дурак. Сначала смотрит, кто перед ним.

- name: Install Apache on CentOS/RHEL
  yum:
    name: httpd
    state: present
  when: ansible_facts['os_family'] == "RedHat" # Только для рыжих, бля

- name: Install Apache on Ubuntu/Debian
  apt:
    name: apache2
    state: present
  when: ansible_facts['os_family'] == "Debian" # А тут уже для дебианщиков

Пример 2: Проверка по результату — доверия ебать ноль Сначала сходил, пощупал, зарегистрировал результат, а потом уже думаешь, что делать. Как в жизни: сначала проверь, не горит ли уже, а потом беги за огнетушителем.

- name: Check if a service is running
  command: systemctl is-active nginx
  register: nginx_status # Записал, что увидел
  ignore_errors: yes # Если команда сдохла — да похуй, идём дальше
  changed_when: false # Эта задача никогда не считается "изменившей" что-то

- name: Restart Nginx if it was active
  systemd:
    name: nginx
    state: restarted
  when: nginx_status.rc == 0 # Перезапускаем только если он ДЕЙСТВИТЕЛЬНО работал

Пример 3: Комбинация всего и сразу — подозрение ебать чувствую Тут уже всё серьёзно. Чтобы задача выполнилась, должно совпасть овердохуища условий. Как будто ты пытаешься попасть в закрытый клуб.

- name: Deploy configuration only for production servers in the EU region
  template:
    src: app_config.j2
    dest: /etc/app/config.conf
  when:
    - env == "production" # Окружение продакшн
    - region == "eu-west-1" # Регион — Европа
    - deploy_config | bool  # И эта галочка должна быть явно True, а не какая-то хуйня

Важные моменты, которые надо вбить себе в башку:

  • Условия when работают для каждого сервера по отдельности. На одном может сработать, на другом — нет. Ничего личного, просто логика.
  • Можно использовать всю мощь Jinja2, склеивать условия через and, or, проверять, определена ли переменная (is defined). В общем, полная свобода, лишь бы выражение в итоге было True или False.
  • Эту же плюху можно прикрутить не только к задачам, но и к целым блокам (block), или когда подключаешь другие файлы через include_* и import_*. Универсальная штука, бля.