Назад | Перейти на главную страницу

Параметрическая команда ansible, основанная на фактах, как это сделать?

Я обновляю некоторые из моих доступных playbooks для работы в последней версии Fedora, которая теперь использует dnf по умолчанию.

Поскольку большинство моих сценариев также должны работать на CentOS, Я бы хотел, чтобы мой скрипт запускал доступный yum при работе с машиной CentOS и запустите dnf команда (новая в Ansible 1.9) при работе с Fedora, но используя остальную роль как есть.

Другими словами, я хотел бы написать одну операцию, которая может разумно выбрать команду righ (что-то вроде):

- name: Install zsh
  sudo: yes
  yum|dnf: name=zsh state=latest

... вместо того, чтобы дважды копировать одну и ту же команду, заменяя yum с участием dnf в одной из двух, а затем реализуем некоторую логику, которая говорит, какую из двух различных ролей следует выполнять:

- name: Install zsh (yum version)
  sudo: yes
  yum: name=zsh state=latest

- name: Install zsh (dnf version)
  sudo: yes
  dnf: name=zsh state=latest

Прежде чем кто-нибудь к нему бросится: я знаю это yum под псевдонимом dnf на последней версии Fedora, и что я мог бы просто оставить playbook как есть... у меня вопрос не о написании совместимых с CentOS / Fedora плейбуков, мой вопрос о выбор другой команды для тех же параметров в зависимости от целевой среды

В Ansible 2 теперь есть общий менеджер пакетов:

http://docs.ansible.com/ansible/package_module.html

Для более старых версий вы можете связать менеджеров пакетов с помощью фактов

- name: Install packages
  with_items: package_list
  action: "{{ ansible_pkg_mgr }} state=installed name={{ item }}"

Теперь все, что вам нужно, это логика, которая устанавливает ansible_pkg_mgr к apt или yum и т. д. и все when логика уходит.

Похоже на Ansible также работают над тем, что вы хотите, в будущем модуле.

Насколько я могу судить, это одна из самых запутанных частей Ansible. Я всегда думал, что у него должен быть способ самостоятельно определить, какой менеджер пакетов используется, без необходимости указывать его.

А пока у меня много ролей с такими задачами:

- name: Update OpenSSH on CentOS
  yum: name=openssh state=latest enablerepo=cr
  when: ansible_distribution == 'CentOS' and ansible_distribution_major_version|int == 7
  notify: restart sshd

- name: Update OpenSSH on RHEL
  yum: name=openssh state=latest
  when: ansible_distribution == 'RedHat' and ansible_distribution_major_version|int == 7
  notify: restart sshd

- name: Update OpenSSH on Fedora
  yum: name=openssh state=latest
  when: ansible_distribution == 'Fedora' andansible_distribution_major_version|int <= 21
  notify: restart sshd

- name: Update OpenSSH on Fedora
  dnf: name=openssh state=latest
  when: ansible_distribution == 'Fedora' andansible_distribution_major_version|int >= 22
  notify: restart sshd

- name: Update OpenSSH on Debian/Ubuntu
  apt: name=openssh-server state=latest
  when: ansible_os_family == 'Debian'
  notify: restart ssh

Это становится немного громоздко. Однако в этом есть свои преимущества. Если вы внимательно изучите это, вы заметите, что версия CentOS отличается; он включает репозиторий при установке пакета.

Конечно, для этого есть причина. В разных системах у вас может быть даже другой пакет имена, так что вам все равно придется ставить перед ними другие задачи. Но это то, что вы можете вставить в переменную, зависящую от ОС, а затем сделать что-то вроде:

- include_vars: common_os_{{ansible_distribution}}_{{ansible_distribution_major_version}}.yml

- name: Install minimum system administration packages
  yum: name={{item}} state=present
  with_items: common_packages_admin
  when: ansible_os_family == 'RedHat'

- name: Install minimum system administration packages
  apt: name={{item}} state=present
  with_items: common_packages_admin
  when: ansible_os_family == 'Debian'

Но продлить это на dnf потребуется куча дополнительных when: логика, которая требует много работы для абсолютно нулевого выигрыша, поскольку совместимость dnf с yum позаботится об этом. Вот место, где был бы полезен этот гипотетический модуль «автоматически определить, какой менеджер пакетов использовать».

Но даже если он у вас есть, вам все равно иногда придется использовать отдельные менеджеры пакетов, потому что у некоторых из них есть ... особенности.

- name: Install salt-minion
  yum: name=salt-minion state=latest
  when: ansible_os_family == 'RedHat'

- name: Install salt-minion
  apt: name=salt-minion state=latest update_cache=yes
  when: ansible_os_family == 'Debian'

Итак, лучший совет, который я могу вам дать: подождите, пока у Ansible не появится лучший способ работы с менеджерами пакетов. Или напишите одну ...