Frage Wie vereinheitlichen Sie Paketinstallationsaufgaben in ansible?


Ich beginne mit ansible und wird es unter anderem verwenden, um Pakete auf mehreren Linux-Distributionen zu installieren.

Ich sehe in den Dokumenten, dass die yum und apt Befehle sind getrennt - was wäre der einfachste Weg, sie zu vereinheitlichen und so etwas zu verwenden:

- name: install the latest version of Apache
  unified_install: name=httpd state=latest

anstatt

- name: install the latest version of Apache on CentOS
  yum: name=httpd state=latest
  when: ansible_os_family == "RedHat"

- name: install the latest version of Apache on Debian
  apt: pkg=httpd state=latest 
  when: ansible_os_family == "Debian"

Ich verstehe, dass die beiden Paketmanager unterschiedlich sind, aber sie haben immer noch eine Reihe gemeinsamer Grundnutzungen. Andere Orchester (Salz zum Beispiel) haben Sie einen einzigen Installationsbefehl.


61
2018-04-09 11:45


Ursprung


Sie könnten drei Rezepte haben: eines, das über eine gemeinsame Liste iteriert, und dann jeweils eines für OS-spezifische Listen. Was ich gerade herausfinden möchte, ist, wie man einen Handler mit einem Betriebssystem-spezifischen Dienstnamen benachrichtigen kann, nachdem ein allgemeines Konfigurationselement gesetzt wurde. Viel Glück! - dannyman
mögliches Duplikat von Parametric Ansible Befehl basierend auf Fakten, wie es geht? - xddsg


Antworten:


Update: Ab Ansible 2.0 gibt es jetzt einen generischen & abstrahierten package Modul

Anwendungsbeispiele:

Wenn nun der Paketname in verschiedenen Betriebssystemfamilien gleich ist, ist dies so einfach wie:

---
- name: Install foo
  package: name=foo state=latest

Wenn der Paketname für die verschiedenen Betriebssystemfamilien unterschiedlich ist, können Sie ihn mit vars-Dateien für die Verteilung oder OS-Familie behandeln:

---
# 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

Dann müssen Sie für jedes Betriebssystem, mit dem Sie anders umgehen müssen, eine vars-Datei erstellen:

---
# 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



BEARBEITEN:  Seit Michael DeHaan (Schöpfer von Ansible) hat sich entschieden, die Paketmanager-Module nicht zu abstrahieren mögen Koch tut, 

Wenn Sie noch eine ältere Version von Ansible verwenden (Ansible <2.0)Leider musst du damit umgehen alles deiner Spielbücher und Rollen. meiner bescheidenen Meinung nach Dies führt zu einer Menge unnötiger, sich wiederholender Arbeit bei Rollenspiel- und Rollenautoren ... aber so ist es derzeit. Beachten Sie, dass ich nicht sage, dass wir versuchen sollten, Paketmanager wegzuspalten, während wir immer noch versuchen, alle ihre spezifischen Optionen und Befehle zu unterstützen, aber einfach eine Möglichkeit haben, ein Paket zu installieren, das Agnostiker ist. Ich sage auch nicht, dass wir alle auf die springen sollten Intelligenter Paketmanager Allerdings ist eine Art Paketinstallations-Abstraktionsschicht in Ihrem Konfigurationsmanagement-Tool sehr nützlich, um plattformübergreifende Spielbücher / Kochbücher zu vereinfachen. Das Smart-Projekt sieht interessant aus, aber es ist ziemlich ambitioniert, die Paketverwaltung über Distributionen und Plattformen hinweg zu vereinheitlichen, ohne dass es viel Akzeptanz gibt ... es wird interessant sein zu sehen, ob es erfolgreich ist. Das wirkliche Problem ist nur, dass Paketnamen manchmal in Distributionen unterschiedlich sind, so dass wir immer noch Case Statements oder when: Anweisungen, um die Unterschiede zu behandeln.

Die Art, wie ich damit umgegangen bin, ist, dem zu folgen tasks Verzeichnisstruktur in einem Playbook oder einer Rolle:

roles/foo
└── tasks
    ├── apt_package.yml
    ├── foo.yml
    ├── homebrew_package.yml
    ├── main.yml
    └── yum_package.yml

Und dann habe ich das in meinem main.yml:

---
# foo: entry point for tasks
#                 Generally only include other file(s) and add tags here.

- include: foo.yml tags=foo

Das in foo.yml (für 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'

Dann für die verschiedenen Paketmanager:

Geeignet:

---
# 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

Beachten Sie, dass dies schrecklich wiederholend ist und nicht TROCKEN.und obwohl einige Dinge könnte auf den verschiedenen Plattformen anders sein und müssen gehandhabt werden, im Allgemeinen denke ich, dass dies im Vergleich zu Chef's ausführlich und unhandlich ist:

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

Und ja, da ist das Argument, dass etwas Paketnamen sind in den Distributionen unterschiedlich. Und obwohl es derzeit ein Mangel an leicht zugänglichen DatenIch würde es wagen, das zu erraten die meisten Beliebte Paketnamen sind in Distributionen üblich und können über ein abstrahiertes Paketmanager-Modul installiert werden. Sonderfälle müssten sowieso behandelt werden und würden bereits zusätzliche Arbeit erfordern, die Dinge weniger D.R.Y. Im Zweifelsfall überprüfen pkgs.org.


60
2017-12-05 03:14



Mit Ansible 2 können Sie das Paketmodul verwenden, um all dies zu abstrahieren docs.ansible.com/ansible/package_module.html - Guido
@ GuidoGarcía: Sehr nett! Hinzufügen einer Notiz zu Ansible 2.0 - TrinitronX


Sie können Paketmanager über Fakten abstrahieren

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

Alles, was Sie brauchen, ist eine Logik, die setzt ansible_pkg_mgr zu apt oder yum usw.

Ansible arbeiten auch daran, das zu tun, was Sie in einem zukünftigen Modul wollen.


13
2018-06-09 18:08



Ansible Sätze ansible_pkg_mgr für jeden Packer, den es kennt. Du musst nichts tun. Ich benutze dieses besondere Konstrukt überall. - Michael Hampton♦
Die Syntax ist immer noch sehr nützlich für diejenigen, die den Lauf ihrer Spielbücher optimieren wollen. Das generische Paketmodul bietet noch keine Optimierung für with_items Das ist viel langsamer, wenn mehrere Pakete gleichzeitig installiert werden. - Daniel V.
@DanielV. Beachten Sie, dass das github-Problem eine Abhilfe dafür bietet. - Michael Hampton♦


Ab Ansible 2.0 gibt es das neue Package-Modul.

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

Sie können es dann wie Ihren Vorschlag verwenden:

- name: install the latest version of Apache
  package: name=httpd state=latest

Sie müssen immer noch Namensunterschiede berücksichtigen.


6
2017-11-15 11:52





Sehen Sie sich die Dokumentation von Ansible an Bedingte Importe.

Eine Aufgabe, um sicherzustellen, dass Apache ausgeführt wird, auch wenn die Dienstnamen für jedes Betriebssystem unterschiedlich sind.

---
- hosts: all
  remote_user: root
  vars_files:
    - "vars/common.yml"
    - [ "vars/{{ ansible_os_family }}.yml", "vars/os_defaults.yml" ]
  tasks:
  - name: make sure apache is running
    service: name={{ apache }} state=running

3
2018-03-17 16:19





Dies möchten Sie nicht tun, da sich bestimmte Paketnamen zwischen den Distributionen unterscheiden. Zum Beispiel wird auf RHEL-bezogenen Distributionen das populäre Web-Server-Paket benannt httpd, wo es wie bei Debian-verwandten Distributionen heißt apache2. Ähnlich mit einer riesigen Liste anderer System- und unterstützender Bibliotheken.

Es könnte eine Reihe von allgemeinen Grundparametern geben, aber dann gibt es auch eine Reihe von fortgeschritteneren Parametern, die sich zwischen Paketmanagern unterscheiden. Und Sie möchten nicht in einer mehrdeutigen Situation sein, in der Sie für einige Befehle eine Syntax und für andere Befehle eine andere Syntax verwenden.


2
2018-04-10 12:00



Das ist mehr oder weniger was ich erwartet habe (leider :)) also frage ich mich wie salt schafft es, beide Paketmanager zu vereinheitlichen. Wie auch immer, ich werde dann auf eine doppelte Konfiguration zurückgreifen. - WoJ
Oder führe keinen Distro-Zoo ;-) migriere zu einer Single-Distro-Infrastruktur und lebe ein glücklicheres Leben. - Mxx
Der Zoo ist zum Glück nur zwei Tiere groß, aber das ist die niedrigste Anzahl, die ich gehen kann :) - WoJ
@Mxx, das ist eine gute Logik für einen Systemadministrator, aber was ist mit einem Softwareanbieter oder Berater, der mehrere Plattformen unterstützt? - David H. Bennett
@David, dann muss dies mit Distro-Anbietern aufgegriffen werden, damit sie einheitliche Paketnamen und Installationstools haben. Es gibt wirklich keine Möglichkeit, dass Ansible eine einheitliche Zuordnung aller Pakete von allen unterstützten Distributionen aller Versionen haben kann. - Mxx