Pembaruan: Pada Ansible 2.0, sekarang ada modul generik & abstrakpackage
Contoh Penggunaan:
Sekarang ketika nama paket sama di berbagai keluarga OS, itu sesederhana:
---
- name: Install foo
package: name=foo state=latest
Ketika nama paket berbeda di seluruh keluarga OS, Anda dapat mengatasinya dengan distribusi atau file vars khusus keluarga 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
Kemudian, untuk setiap OS yang harus Anda tangani secara berbeda ... buat file 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: Karena Michael DeHaan (pencipta Ansible) telah memilih untuk tidak mencabut modul manajer paket seperti yang dilakukan Chef ,
Jika Anda masih menggunakan versi Ansible yang lebih lama (Ansible <2.0) , sayangnya Anda harus menangani hal ini di semua buku pedoman dan peran Anda. IMHO ini mendorong banyak pekerjaan berulang yang tidak perlu ke playbook & penulis peran ... tapi begitulah adanya. Perhatikan bahwa saya tidak mengatakan kita harus mencoba untuk mengabstraksikan manajer paket pergi sambil tetap mencoba untuk mendukung semua opsi dan perintah khusus mereka, tetapi hanya memiliki cara mudah untuk menginstal paket yang agnostik paket manajer. Saya juga tidak mengatakan bahwa kita semua harus menggunakan Smart Package Managerikut-ikutan, tetapi semacam lapisan abstraksi instalasi paket di alat manajemen konfigurasi Anda sangat berguna untuk menyederhanakan buku pedoman / buku resep lintas platform. Proyek Smart terlihat menarik, tetapi cukup ambisius untuk menyatukan manajemen paket di seluruh distro dan platform tanpa banyak adopsi ... itu akan menarik untuk melihat apakah itu berhasil. Masalah sebenarnya adalah hanya bahwa nama paket kadang-kadang cenderung berbeda di seluruh distro, jadi kita masih harus melakukan pernyataan kasus atau when:
pernyataan untuk menangani perbedaan.
Cara saya menghadapinya adalah dengan mengikuti tasks
struktur direktori ini di buku pedoman atau peran:
roles/foo
└── tasks
├── apt_package.yml
├── foo.yml
├── homebrew_package.yml
├── main.yml
└── yum_package.yml
Dan kemudian memilikinya di main.yml
:
---
# foo: entry point for tasks
# Generally only include other file(s) and add tags here.
- include: foo.yml tags=foo
Ini dalam foo.yml
(untuk paket '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'
Kemudian untuk manajer paket yang berbeda:
Tepat:
---
# 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
Perhatikan bahwa ini sangat berulang dan bukan KERING , dan meskipun beberapa hal mungkin berbeda pada platform yang berbeda dan harus ditangani, secara umum saya pikir ini verbose dan berat jika dibandingkan dengan 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
Dan ya, ada argumen bahwa beberapa nama paket berbeda di seluruh distro. Dan meskipun saat ini ada kekurangan data yang mudah diakses , saya berani menebak bahwa sebagian besar nama paket populer adalah umum di seluruh distro dan dapat diinstal melalui modul manajer paket abstrak. Kasus-kasus khusus perlu ditangani, dan sudah membutuhkan kerja ekstra membuat segalanya kurang KERING. Jika ragu, periksa pkgs.org .