
estoy empezando conansibley lo usará, entre otros, para instalar paquetes en varias distribuciones de Linux.
Veo en los documentos que los comandos yum
y apt
están separados; cuál sería la forma más fácil de unificarlos y usar algo como esto:
- name: install the latest version of Apache
unified_install: name=httpd state=latest
en lugar de
- 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"
Entiendo que los dos administradores de paquetes son diferentes, pero aún tienen un conjunto de usos básicos comunes. Otros orquestadores (sal por ejemplo) tienen un único comando de instalación.
Respuesta1
Actualización: a partir de Ansible 2.0, ahora hay una versión genérica y abstractapackage
módulo
Ejemplos de uso:
Ahora, cuando el nombre del paquete es el mismo en diferentes familias de sistemas operativos, es tan simple como:
---
- name: Install foo
package: name=foo state=latest
Cuando el nombre del paquete difiere entre las familias de sistemas operativos, puede manejarlo con archivos vars específicos de la familia de sistemas operativos o de distribución:
---
# 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
Luego, para cada sistema operativo que debas manejar de manera diferente... crea un archivo 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
EDITAR: Desde Michael DeHaan (creador de Ansible)ha optado por no abstraer los módulos del administrador de paquetescomoCocinerohace,
Si todavía utiliza una versión anterior de Ansible (Ansible < 2.0), desafortunadamente tendrás que encargarte de hacer esto entodode sus manuales y roles. En mi humilde opiniónesto impone una gran cantidad de trabajo repetitivo innecesario a los autores de libros de jugadas y roles... pero así es actualmente. Tenga en cuenta que no estoy diciendo que debamos intentar abstraer los administradores de paquetes y al mismo tiempo intentar admitir todas sus opciones y comandos específicos, sino simplemente tener una manera fácil de instalar un paquete que sea independiente del administrador de paquetes. Tampoco estoy diciendo que todos debamos lanzarnos alAdministrador de paquetes inteligentevagon, pero que algún tipo de capa de abstracción de instalación de paquetes en su herramienta de administración de configuración es muy útil para simplificar los libros de estrategias y recetas multiplataforma. El proyecto Smart parece interesante, pero es bastante ambicioso para unificar la gestión de paquetes entre distribuciones y plataformas sin mucha adopción todavía... será interesante ver si tiene éxito. El verdadero problema es que los nombres de los paquetes a veces tienden a ser diferentes entre las distribuciones, por lo que todavía tenemos que hacer declaraciones de casos o when:
declaraciones para manejar las diferencias.
La forma en que lo he estado abordando es seguir esta tasks
estructura de directorio en un manual o rol:
roles/foo
└── tasks
├── apt_package.yml
├── foo.yml
├── homebrew_package.yml
├── main.yml
└── yum_package.yml
Y luego tengo esto en mi main.yml
:
---
# foo: entry point for tasks
# Generally only include other file(s) and add tags here.
- include: foo.yml tags=foo
Esto en foo.yml
(para el paquete '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'
Luego para los diferentes administradores de paquetes:
Apto:
---
# 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
Mmmm:
---
# 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
Elaboración casera:
---
- name: Tap homebrew foobar/foo
homebrew_tap: >
name=foobar/foo
state=present
- homebrew: >
name=foo
state=latest
Tenga en cuenta que esto es terriblemente repetitivo y noSECO, y aunque algunas cosaspodríaser diferente en las diferentes plataformas y tendrá que ser manejado, en general creo que esto es detallado y difícil de manejar en comparación con 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
Y sí, existe el argumento de quealgunoLos nombres de los paquetes son diferentes entre las distribuciones. Y aunque actualmente existe unafalta de datos fácilmente accesibles, me atrevería a suponer quemayoríaLos nombres de paquetes populares son comunes en todas las distribuciones y se pueden instalar a través de un módulo de administrador de paquetes abstracto. Los casos especiales tendrían que ser manejados de todos modos, y ya requerirían trabajo adicional para hacer las cosas menos SECAS. En caso de duda, verifiquepkgs.org.
Respuesta2
Puede abstraer los administradores de paquetes a través de hechos
- name: Install packages
with_items: package_list
action: "{{ ansible_pkg_mgr }} state=installed name={{ item }}"
Todo lo que necesitas es algo de lógica que ansible_pkg_mgr
establezca apt
o yum
etc.
ansibleTambién estamos trabajando para hacer lo que quieras en un módulo futuro..
Respuesta3
De Ansible 2.0 existe el nuevo Package
-modul.
http://docs.ansible.com/ansible/package_module.html
Luego puedes usarlo como tu propuesta:
- name: install the latest version of Apache
package: name=httpd state=latest
Aún debes considerar las diferencias de nombres.
Respuesta4
No desea hacer eso porque ciertos nombres de paquetes difieren entre distribuciones. Por ejemplo, en las distribuciones relacionadas con RHEL, el popular paquete de servidor web se denomina httpd
, mientras que en las distribuciones relacionadas con Debian se denomina apache2
. Lo mismo ocurre con una lista enorme de otros sistemas y bibliotecas de soporte.
Puede haber un conjunto de parámetros básicos comunes, pero también hay una serie de parámetros más avanzados que son diferentes entre los administradores de paquetes. Y no querrás estar en una situación ambigua en la que para algunos comandos uses una sintaxis y para otros comandos uses otra sintaxis.