Vraag Hoe pakketinstallatie-taken te verenigen in een mogelijkheid?


Ik begin met Ansible en zal het onder andere gebruiken om pakketten op verschillende Linux-distributies te installeren.

Ik zie in de documenten dat het yum en apt commando's zijn gescheiden - wat zou de eenvoudigste manier zijn om ze te verenigen en zoiets te gebruiken:

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

in plaats van

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

Ik begrijp dat de twee pakketbeheerders verschillend zijn, maar ze hebben nog steeds een reeks gemeenschappelijke basisgebruiken. Andere orkesten (zout bijvoorbeeld) hebben een enkele installatieopdracht.


61
2018-04-09 11:45


oorsprong


U zou drie recepten kunnen hebben: een die itereert over een gemeenschappelijke lijst en vervolgens telkens één voor OS-specifieke lijsten. Wat ik nu probeer uit te zoeken is hoe een handler op de hoogte te stellen met een OS-specifieke servicenaam nadat een gemeenschappelijk configuratie-item is ingesteld. succes! - dannyman
mogelijk duplicaat van Parametrische ansible-opdracht op basis van feiten, hoe moet dit worden gedaan? - xddsg


antwoorden:


Update: Vanaf Ansible 2.0 is er nu een generiek & geabstraheerd package module

Gebruiksvoorbeelden:

Wanneer de naam van het pakket hetzelfde is voor verschillende OS-families, is het zo simpel als:

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

Als de naam van het pakket verschilt tussen OS-families, kunt u dit doen met distributie- of besturingssysteemfamiliespecifieke vars-bestanden:

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

Vervolgens moet u voor elk besturingssysteem dat u anders moet verwerken ... een vars-bestand maken:

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



BEWERK:  Sinds Michael DeHaan (maker van Ansible) heeft ervoor gekozen om de pakketbeheermodule niet uit te sluiten net zoals Chef doet, 

Als u nog steeds een oudere versie van Ansible gebruikt (Ansible <2.0), helaas moet je dit doen in allemaal van je playbooks en rollen. naar mijn bescheiden mening dit duwt veel onnodig repetitief werk op playbook en rolauteurs ... maar het is zoals het er nu uitziet. Merk op dat ik niet zeg dat we moeten proberen om pakketbeheerders weg te halen, terwijl we toch proberen al hun specifieke opties en opdrachten te ondersteunen, maar gewoon een eenvoudige manier hebben om een ​​pakket te installeren dat agnostisch is voor pakketbeheer. Ik zeg ook niet dat we allemaal op de Smart Package Manager bandwagon, maar dat een soort van abstractielaag voor pakketinstallaties in je configuratiebeheertool erg handig is om playbooks / cookbooks over verschillende platformen te vereenvoudigen. Het Smart-project ziet er interessant uit, maar het is vrij ambitieus om pakketbeheer over distributies en platforms te verenigen zonder al te veel adoptie ... het zal interessant zijn om te zien of het succesvol is. Het echte probleem is alleen dat pakketnamen soms verschillend zijn in verschillende distributies, dus we moeten nog steeds case-statements doen of when: verklaringen om de verschillen op te lossen.

De manier waarop ik het heb aangepakt is om dit te volgen tasks mappenstructuur in een playbook of rol:

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

En dan heb ik dit in mijn main.yml:

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

- include: foo.yml tags=foo

Dit in foo.yml (voor pakket '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'

Dan voor de verschillende pakketbeheerders:

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

Merk op dat dit erg repetitief is en niet DROOG., en hoewel sommige dingen macht anders zijn op de verschillende platforms en moeten worden afgehandeld, over het algemeen vind ik dit uitgebreid en onhandig in vergelijking met Chef's:

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

En ja, daar is het argument voor sommige pakketnamen zijn verschillend voor verschillende distributies. En hoewel er momenteel een is gebrek aan gemakkelijk toegankelijke gegevens, Dat zou ik durven raden meest populaire pakketnamen komen vaak voor in verschillende distributies en kunnen worden geïnstalleerd via een geabstraheerde pakketbeheermodule. Speciale gevallen zouden hoe dan ook moeten worden afgehandeld, en zou al extra werk vereisen om dingen minder te maken D.R.Y. Controleer bij twijfel pkgs.org.


60
2017-12-05 03:14



Met Ansible 2 kun je de pakketmodule gebruiken om dit allemaal te abstraheren docs.ansible.com/ansible/package_module.html - Guido
@ GuidoGarcía: Heel leuk! Hierover een opmerking toevoegen voor Ansible 2.0 - TrinitronX


U kunt pakketmanagers abstraheren via feiten

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

Het enige wat je nodig hebt is een logica die instelt ansible_pkg_mgr naar apt of yum enz.

Ansible zijn ook bezig met doen wat je wilt in een toekomstige module.


13
2018-06-09 18:08



Ansible wordt ingeschakeld ansible_pkg_mgr zelf voor elke packager die het kent. Het is niet nodig dat je iets doet. Ik gebruik deze specifieke constructie overal. - Michael Hampton♦
De syntaxis is nog steeds erg handig voor degenen die de run van hun playbooks willen optimaliseren. De generieke pakketmodule biedt nog geen optimalisatie voor with_items dus het is veel langzamer als het wordt gebruikt om meerdere pakketten tegelijk te installeren. - Daniel V.
@DanielV. Merk op dat de github-kwestie hiervoor een oplossing biedt. - Michael Hampton♦


Van Ansible 2.0 is er het nieuwe Package-modul.

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

U kunt het dan gebruiken als uw voorstel:

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

Je moet nog steeds rekening houden met verschillen in naam.


6
2017-11-15 11:52





Bekijk de documentatie van Ansible op Voorwaardelijke invoer.

Eén taak om ervoor te zorgen dat apache wordt uitgevoerd, zelfs als de servicenamen in elk besturingssysteem verschillend zijn.

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





U wilt dat niet doen omdat bepaalde pakketnamen verschillen tussen distributies. Bijvoorbeeld op RHEL-gerelateerde distributies wordt het populaire webserverpakket genoemd httpd, waar als op Debian-gerelateerde distro's het is genoemd apache2. Evenzo met een enorme lijst van andere systeem- en ondersteunende bibliotheken.

Er is mogelijk een aantal algemene basisparameters, maar er zijn ook een aantal meer geavanceerde parameters die verschillen tussen pakketbeheerders. En je wilt niet in een meerduidige situatie zitten waarin je voor sommige opdrachten één syntax gebruikt en voor andere opdrachten gebruik je een andere syntaxis.


2
2018-04-10 12:00



Dit is min of meer wat ik verwachtte (helaas :)) dus ik vraag me af hoe salt slaagt erin beide pakketbeheerders te verenigen. Hoe dan ook, ik zal dan een dubbele configuratie gebruiken. - WoJ
Of beheer geen distro-dierentuin ;-) migreer naar een single-distro-infrastructuur en leef een gelukkiger leven. - Mxx
De dierentuin is gelukkig maar twee dieren groot, maar dit is het laagste aantal dat ik kan gaan :) - WoJ
@Mxx dat is prima logica voor een sysadmin, maar hoe zit het met een softwareleverancier of consultant die meerdere platforms ondersteunt? - David H. Bennett
@David, dan moet dit worden opgepakt met distro-leveranciers, zodat ze uniforme pakketnamen en installatiehulpmiddelen hebben. Er is op realistische wijze geen manier dat Ansible een uniforme toewijzing van ALLE pakketten van alle ondersteunde distributies van alle versies kan hebben. - Mxx