Mise à jour : Depuis Ansible 2.0, il y a maintenant une version générique et abstraite de l'article. package
module
Exemples d'utilisation :
Maintenant, lorsque le nom du paquet est le même dans différentes familles d'OS, c'est aussi simple que cela :
---
- name: Install foo
package: name=foo state=latest
Lorsque le nom du paquet diffère d'une famille d'OS à l'autre, vous pouvez le gérer avec des fichiers vars spécifiques à la distribution ou à la famille d'OS :
---
# 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
Ensuite, pour chaque OS que vous devez gérer différemment... créez un fichier 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: Depuis Michael DeHaan (créateur d'Ansible) a choisi de ne pas abstraire les modules du gestionnaire de paquets. comme Chef fait,
Si vous utilisez toujours une ancienne version d'Ansible (Ansible < 2.0) malheureusement, vous devrez vous occuper de cette opération dans tous de vos playbooks et rôles. IMHO cela impose un travail répétitif et inutile aux auteurs de livre de jeu et de rôle... mais c'est ainsi que cela se passe actuellement. Notez que je ne dis pas que nous devrions essayer d'abstraire les gestionnaires de paquets tout en essayant de supporter toutes leurs options et commandes spécifiques, mais simplement avoir un moyen facile d'installer un paquet qui est agnostique au gestionnaire de paquets. Je ne suis pas non plus en train de dire que nous devrions tous sauter sur le bouton Gestionnaire de paquets intelligent mais qu'une sorte de couche d'abstraction pour l'installation de paquets dans votre outil de gestion de la configuration est très utile pour simplifier les livres de jeux et les livres de cuisine multiplateformes. Le projet Smart a l'air intéressant, mais il est assez ambitieux pour unifier la gestion des paquets à travers les distros et les plateformes, sans avoir été adopté pour le moment... il sera intéressant de voir s'il réussit. Le vrai problème est que les noms des paquets ont parfois tendance à être différents d'une distro à l'autre, ce qui nous oblige à utiliser des instructions de type case ou when:
pour gérer les différences.
La façon dont je m'en sors est de suivre ce qui suit . tasks
structure de répertoire dans un playbook ou un rôle :
roles/foo
tasks
apt_package.yml
foo.yml
homebrew_package.yml
main.yml
yum_package.yml
Et puis j'ai ça dans mon main.yml
:
---
# foo: entry point for tasks
# Generally only include other file(s) and add tags here.
- include: foo.yml tags=foo
Ce dans foo.yml
(pour le paquet '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'
Puis pour les différents gestionnaires de paquets :
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
Miam :
---
# 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
Homebrew :
---
- name: Tap homebrew foobar/foo
homebrew_tap: >
name=foobar/foo
state=present
- homebrew: >
name=foo
state=latest
Notez que c'est terriblement répétitif et non pas D.R.Y. et bien que certaines choses pourrait sera différente sur les différentes plateformes et devra être gérée, en général je pense que c'est verbeux et peu maniable comparé à celle de Chef :
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
Et oui, il y a l'argument selon lequel un peu de Les noms des paquets sont différents selon les distros. Et bien qu'il existe actuellement un le manque de données facilement accessibles je me risquerais à dire que le plus Les noms de paquets populaires sont communs à toutes les distributions et peuvent être installés via un module abstrait de gestion des paquets. S pkgs.org .