Оновлення: Станом на Ansible 2.0, тепер існує загальний модуль та абстрагуванняpackage
Приклади використання:
Тепер, коли назва пакету однакова в різних сімействах ОС, це так само просто, як:
---
- name: Install foo
package: name=foo state=latest
Коли назва пакета відрізняється у сімействах ОС, ви можете обробити його за допомогою файлів vars для розповсюдження або специфічних для сім'ї ОС:
---
# roles/apache/apache.yml: Tasks entry point for 'apache' role. Called by main.yml
# Load a variable file based on the OS type, or a default if not found.
- include_vars: "{{ item }}"
with_first_found:
- "../vars/{{ ansible_distribution }}-{{ ansible_distribution_major_version | int}}.yml"
- "../vars/{{ ansible_distribution }}.yml"
- "../vars/{{ ansible_os_family }}.yml"
- "../vars/default.yml"
when: apache_package_name is not defined or apache_service_name is not defined
- name: Install Apache
package: >
name={{ apache_package_name }}
state=latest
- name: Enable apache service
service: >
name={{ apache_service_name }}
state=started
enabled=yes
tags: packages
Потім для кожної ОС, з якою ви маєте працювати по-різному ... створіть файл vars:
---
# roles/apache/vars/default.yml
apache_package_name: apache2
apache_service_name: apache2
---
# roles/apache/vars/RedHat.yml
apache_package_name: httpd
apache_service_name: httpd
---
# roles/apache/vars/SLES.yml
apache_package_name: apache2
apache_service_name: apache2
---
# roles/apache/vars/Debian.yml
apache_package_name: apache2
apache_service_name: apache2
---
# roles/apache/vars/Archlinux.yml
apache_package_name: apache
apache_service_name: httpd
EDIT: Оскільки Майкл ДеХаан (творець Ansible) вирішив не абстрагувати модулі менеджера пакунків, як Chef ,
Якщо ви все ще використовуєте старішу версію Ansible (Ansible <2.0) , на жаль, вам потрібно буде впоратися з цим у всіх своїх іграх і ролях. IMHO це підштовхує багато непотрібних робіт, що повторюються, на авторів ігор та ролей ... але це так, як це є зараз. Зауважте, що я не кажу, що ми повинні намагатися абстрагувати менеджерів пакунків подалі, намагаючись підтримувати всі їх конкретні параметри та команди, а просто мати простий спосіб встановити пакет, який є агностиком менеджера пакунків. Я також не кажу, що всі ми повинні стрибати на Smart Package Managerпростір, але якийсь шар абстракції від встановлення пакету у вашому інструменті управління конфігурацією дуже корисний для спрощення міжплатформних ігор / кулінарних книг. Проект Smart виглядає цікаво, але досить амбітним є уніфікація управління пакунками у різних дистрибутивах та платформах без особливого прийняття… Буде цікаво побачити, чи успішний він. Справжня проблема полягає лише в тому, що назви пакетів іноді мають різницю у різних дистрибутивах, тому нам доводиться робити заяви справи або when:
заяви, щоб вирішити відмінності.
Те, як я маю справу з цим, - це слідувати цій tasks
структурі каталогів у книзі чи ролі:
roles/foo
└── tasks
├── apt_package.yml
├── foo.yml
├── homebrew_package.yml
├── main.yml
└── yum_package.yml
І тоді майте це в моєму main.yml
:
---
# foo: entry point for tasks
# Generally only include other file(s) and add tags here.
- include: foo.yml tags=foo
Це в foo.yml
(для пакета 'foo'):
---
# foo: Tasks entry point. Called by main.yml
- include: apt_package.yml
when: ansible_pkg_mgr == 'apt'
- include: yum_package.yml
when: ansible_pkg_mgr == 'yum'
- include: homebrew_package.yml
when: ansible_os_family == 'Darwin'
- name: Enable foo service
service: >
name=foo
state=started
enabled=yes
tags: packages
when: ansible_os_family != 'Darwin'
Тоді для різних менеджерів пакетів:
Apt:
---
# tasks file for installing foo on apt based distros
- name: Install foo package via apt
apt: >
name=foo{% if foo_version is defined %}={{ foo_version }}{% endif %}
state={% if foo_install_latest is defined and foo_version is not defined %}latest{% else %}present{% endif %}
tags: packages
Yum:
---
# tasks file for installing foo on yum based distros
- name: Install EPEL 6.8 repos (...because it's RedHat and foo is in EPEL for example purposes...)
yum: >
name={{ docker_yum_repo_url }}
state=present
tags: packages
when: ansible_os_family == "RedHat" and ansible_distribution_major_version|int == 6
- name: Install foo package via yum
yum: >
name=foo{% if foo_version is defined %}-{{ foo_version }}{% endif %}
state={% if foo_install_latest is defined and foo_version is not defined %}latest{% else %}present{% endif %}
tags: packages
- name: Install RedHat/yum-based distro specific stuff...
yum: >
name=some-other-custom-dependency-on-redhat
state=latest
when: ansible_os_family == "RedHat"
tags: packages
Домашня мова:
---
- name: Tap homebrew foobar/foo
homebrew_tap: >
name=foobar/foo
state=present
- homebrew: >
name=foo
state=latest
Зауважте, що це жахливо повторюється, і це НЕ СУХО , і хоча деякі речі можуть бути різними на різних платформах, і їх потрібно буде вирішити, як правило, я вважаю, що це багатослівно і громіздко порівняно з шеф-кухарями:
package 'foo' do
version node['foo']['version']
end
case node["platform"]
when "debian", "ubuntu"
# do debian/ubuntu things
when "redhat", "centos", "fedora"
# do redhat/centos/fedora things
end
І так, є аргумент, що назви деяких пакетів різняться по дистрибутивам. І хоча в даний час є відсутність легкодоступних даних , я б ризикнув припустити , що найбільш популярні імена пакетів є загальними для всіх дистрибутивів і можуть бути встановлені з допомогою відведеного модуля менеджера пакетів. У будь-якому випадку потрібно вирішувати особливі випадки, і це вже потребує додаткової роботи, що робить речі менше ДУХИми, якщо сумніваєтесь, перевірте pkgs.org .