Aggiornamento: A partire da Ansible 2.0, ora esiste un modulo generico e astrattopackage
Esempi di utilizzo:
Ora, quando il nome del pacchetto è lo stesso in diverse famiglie di sistemi operativi, è semplice come:
---
- name: Install foo
package: name=foo state=latest
Quando il nome del pacchetto differisce tra le famiglie di sistemi operativi, è possibile gestirlo con file di distribuzione specifici o specifici della famiglia di sistemi operativi:
---
# 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
Quindi, per ciascun sistema operativo che devi gestire in modo diverso ... crea un file VAR:
---
# 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: poiché Michael DeHaan (creatore di Ansible) ha scelto di non sottrarre i moduli del gestore pacchetti come fa Chef ,
Se stai ancora utilizzando una versione precedente di Ansible (Ansible <2.0) , sfortunatamente dovrai gestirlo in tutti i tuoi libri di gioco e ruoli. IMHO questo spinge un sacco di lavoro ripetitivo non necessario su playbook e autori di ruoli ... ma è così com'è attualmente. Si noti che non sto dicendo che dovremmo provare a sottrarre gestori di pacchetti mentre proviamo ancora a supportare tutte le loro opzioni e comandi specifici, ma ho solo un modo semplice per installare un pacchetto che è gestore di pacchetti agnostico. Inoltre non sto dicendo che dovremmo saltare tutti su Smart Package Managercarrozzone, ma che una sorta di livello di astrazione dell'installazione del pacchetto nel tuo strumento di gestione della configurazione è molto utile per semplificare i playbook / i libri di cucina multipiattaforma. Il progetto Smart sembra interessante, ma è abbastanza ambizioso unificare la gestione dei pacchetti tra distro e piattaforme senza molta adozione ... sarà interessante vedere se avrà successo. Il vero problema è solo che i nomi dei pacchetti a volte tendono ad essere diversi tra le distribuzioni, quindi dobbiamo ancora fare dichiarazioni di casi o when:
dichiarazioni per gestire le differenze.
Il modo in cui ho avuto a che fare è seguire questa tasks
struttura di directory in un playbook o in un ruolo:
roles/foo
└── tasks
├── apt_package.yml
├── foo.yml
├── homebrew_package.yml
├── main.yml
└── yum_package.yml
E poi ho questo nel mio main.yml
:
---
# foo: entry point for tasks
# Generally only include other file(s) and add tags here.
- include: foo.yml tags=foo
Questo in foo.yml
(per il pacchetto 'pippo'):
---
# 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'
Quindi per i diversi gestori di pacchetti:
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
homebrew:
---
- name: Tap homebrew foobar/foo
homebrew_tap: >
name=foobar/foo
state=present
- homebrew: >
name=foo
state=latest
Si noti che questo è terribilmente ripetitivo e non ASCIUTTO , e anche se alcune cose potrebbero essere diverse sulle diverse piattaforme e dovranno essere gestite, generalmente penso che questo sia dettagliato e ingombrante rispetto a quello di 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
E sì, c'è l'argomento che alcuni nomi di pacchetti sono diversi tra le distribuzioni. E anche se al momento mancano dati facilmente accessibili , mi permetto di indovinare che i nomi dei pacchetti più popolari sono comuni in tutte le distribuzioni e potrebbero essere installati tramite un modulo di gestione pacchetti astratto. Casi speciali dovrebbero essere comunque gestiti, e richiederebbero già un lavoro extra per rendere le cose meno ASCIUTTE In caso di dubbi, controllare pkgs.org .