Ansible: group_vars separados que se sobrescriben al implementar en el mismo host

Creado en 19 sept. 2014  ·  71Comentarios  ·  Fuente: ansible/ansible

Tipo de problema:

Informe de error

Versión Ansible:

ansible 1.6.1

Medio ambiente:

Mac OS X

Resumen:

Si tenemos un archivo de hosts:

[service1]
www.host1.com

[service2]
www.host1.com

y tenemos estos group_vars:

group_vars/service1:
    database_host: "www.database.com"
    database_port:  3306

group_vars/service2:
    database_host: "www.differentdatabase.com"
    database_port:  3306

y estamos ejecutando este libro de jugadas:

- hosts: service1
  remote_user: root

las variables de group_vars / service1 y group_vars / service2 se sobrescriben entre sí si estamos implementando en el mismo servidor. Esto significa que service1 obtendrá las variables de los grupos service2 y obtendrá el host y el puerto de la base de datos incorrectos.

para evitarlos, hemos agregado entradas de DNS (alias a www.host1-service.com) para que nuestro host se vea así:

[service1]
www.host1-service1.com

[service2]
www.host1-service2.com

pero esto es muy propenso a errores y no es ideal. ¿Cuáles son algunos métodos diferentes para solucionar este problema? (o malentendido de group_vars)

La forma en que estoy haciendo implementaciones de entornos múltiples es así:

inventory/stage/hosts
inventory/stage/group_vars/
inventory/stage/group_vars/service1
inventory/stage/group_vars/service2

inventory/live/hosts
inventory/live/group_vars/
inventory/live/group_vars/service1
inventory/live/group_vars/service2
Pasos para reproducir:

El resumen describe cómo reproducir esto.

Resultados previstos:

group_vars no debe ser sobrescrito por otro grupo cuando se comparte el mismo host

Resultados actuales:

group_vars son sobrescritos por otro grupo cuando se comparte el mismo host

bug

Comentario más útil

Esto es tan estupido. Pasé muchas horas tratando de depurar un problema variable, solo para descubrir que se debía a una filosofía de diseño estúpida (esto). Al menos, debería haber una advertencia cuando se cargan varios archivos group_var para el mismo host.

Todos 71 comentarios

También tengo este problema, parece que las vars se analizan y se adjuntan al host en lugar de quedarse con el grupo.

Pasos para reproducir:

Archivo de hosts:

[aaa]
host1
host2

[bbb]
host2
host3

[aaa:vars]
foo=aaa

[bbb:vars]
foo=bbb

Ejecute un comando en cada grupo:

$ ansible -i hosts aaa -m shell -a "echo {{ foo }}"
host1 | success | rc=0 >>
aaa

host2 | success | rc=0 >>
bbb

$ ansible -i hosts bbb -m shell -a "echo {{ foo }}"
host2 | success | rc=0 >>
bbb

host3 | success | rc=0 >>
bbb

Resultados previstos:

La variable foo=aaa se asigna al grupo aaa y debe aparecer cuando se ejecutan comandos contra el grupo aaa

Resultados actuales:

host2 genera la variable del grupo bbb

Tiene el mismo problema.

Ejemplo:

./group_vars/group1:

---
name: group1

./group_vars/group2

---
name: group2-default

archivo hosts:

[group1]
host1

[group2]
host1

Entonces, cuando intento ejecutar el libro de jugadas solo para el grupo1 ,
La variable " nombre " tiene un valor " grupo2-predeterminado " pero se espera que tenga un valor " grupo1 ".

¿Existe alguna solución para esto?

Las variables de inventario se fusionan incluso si no está usando ese grupo, último grupo
victorias fusionadas

Brian Coca

@bcoca ¿Por qué funciona de esa manera? ¿Es este comportamiento esperado o un error real?

Podría tener archivos vars / service (1,2,3, ...)

Y pase service = 1 como vars adicionales

Luego, para los hosts su orientación en el libro de jugadas, use la variable de servicio,
así como qué archivo vars está importando

Hacemos algo similar para importar vars basadas en un entorno extra var
El 26 de noviembre de 2014 a las 15:12, "arianitu" [email protected] escribió:

@bcoca https://github.com/bcoca ¿Por qué funciona de esa manera? Es esto
comportamiento esperado o un error real?

-
Responda a este correo electrónico directamente o véalo en GitHub
https://github.com/ansible/ansible/issues/9065#issuecomment -64718173.

Tengo el mismo problema en 1.8.4 hoy.
Eventualmente, ¿es este un comportamiento correcto o no?
¿Alguien conoce el progreso?

Hmm. Parece que las etiquetas 'bug_report' están incorrectas aquí. Esto no es un error, sino una característica :-)
Entonces sí, es un comportamiento correcto.

Como dijo @hashnz , "las vars se analizan y se adjuntan al host en lugar de quedarse con el grupo", lo cual es totalmente correcto.

Las variables en diferentes grupos donde los mismos hosts son miembros, solo tienen sentido cuando esos grupos están en una relación padre-hijo, el hijo gana y sus variables se aplican. Si los grupos están al mismo nivel, no hay realmente una forma determinista de cuál va a ganar.

En el momento del libro de jugadas, apuntar a un grupo en realidad solo determina qué hosts están en ejecución, no cambia nada a nivel variable.

La forma ansible aquí sería establecer el puerto y el host de la base de datos en una lista, y repetirlo en las tareas.

@bcoca @ jimi-c Creo que este problema se puede cerrar.

@srvg ¡ Muchas gracias! Lo tengo. Lo intentaré sin usar group_vars.

cerrando, ya que esto no es un error, pero por diseño, las variables de grupo se aplanan por host y no varían debido a cómo se selecciona el host

¿Alguien tiene una solución para esto?

no podemos usar variables estáticas en el libro de jugadas, ya que necesitamos diferenciar entre diferentes entornos (manejados por diferentes archivos de inventario) y necesitamos ejecutar con diferentes variables, dependiendo de la ejecución del grupo, incluso aunque se ejecuten en el mismo host otro grupo

Utilice un CNAME para el mismo nombre de host o una dirección IP. Este es el único
solución que encontré. El problema aparece cuando está utilizando Ansible Tower,
porque está desperdiciando una licencia con tales CNAME. Ansible no quiero
corregir este error llamándolo una "función", pero de hecho es un error real que debe
ser arreglado.
28 de abril de 2015 г. 17:16 пользователь "SkaveRat" [email protected]
написал:

¿Alguien tiene una solución para esto?

no podemos usar vars estáticas en el libro de jugadas, ya que necesitamos diferenciar
entre diferentes entornos (manejados por diferentes archivos de inventario) y
necesita ejecutar con diferentes variables, dependiendo de la ejecución del grupo, incluso
difícil, se ejecutan en el mismo host que otro grupo

-
Responda a este correo electrónico directamente o véalo en GitHub
https://github.com/ansible/ansible/issues/9065#issuecomment -97077453.

Ha sido arreglado pero rechazado. https://github.com/ansible/ansible/pull/6666

Lo molesto es que la guía ansible sí recomienda agruparlos por roles

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

Se sugiere que defina grupos según el propósito del host (roles) y también la ubicación geográfica o del centro de datos (si corresponde)

Pero si el mismo host tiene múltiples roles con las mismas variables, no puede usar las variables de grupo porque no sabe cuál se usará.

Todavía no entiendo cómo vincular una variable a un host específico para un libro de jugadas específico. Quiero poder usar la misma plantilla, pero con diferentes valores de configuración según el entorno en el que estoy implementando.

Ya estamos siguiendo http://docs.ansible.com/ansible/playbooks_best_practices.html#staging -vs-production, haciendo diferentes inventarios para nuestros diferentes entornos.

¿Por qué esto parece tan difícil con Ansible? ¿Ansible es simplemente malo para realizar implementaciones basadas en el entorno?

Proporcione un ejemplo completo, porque "La forma ansible aquí sería establecer el puerto y el host de la base de datos en una lista, y repetirlo en las tareas". no tiene ningún sentido para mí. ¿Dónde se especifica el entorno aquí?

Por ejemplo, tengo un servicio de autenticación que tiene una variable llamada authentication_db_host: 127.0.0.1 para etapa y authentication_db_host: 192.168.2.4 para vivo. ¿Quieres que tenga 2 variables?

authentication_db_host_stage: 127.0.0.1
authentication_db_host_live: 192.168.2.4

Ahora es difícil para mí alimentar eso a un archivo de plantilla común. Necesito agregar si más verificaciones en todo mi archivo j2 (y seguimos ese camino, pero era demasiada duplicación y nos deshicimos de él).

No he encontrado ninguna documentación que maneje este caso, y parece algo que no debería ser difícil de hacer.

Así es como lo hacemos:

Instancia de AWS etiquetada como:

someapi: prod

libro de jugadas someapi.yml

  • hosts: tag_someapi _ {{env}}
    reunir_factos: verdadero
    usuario: ec2-user
    vars_files:

    • vars / aws _ {{env}}

    Tareas:

    • fail: msg = "Env debe definirse"
      cuando: env no está definido
      roles:
    • someapi
      ...

Ejecución con vars extra

ansible-playbook -vv someapi.yml -e "env = prod"

roles / someapi / tasks / main.yml

  • name: incluye vars específicas solo para someapi.
    include_vars: someapi _ {{env}}. yml
  • nombre: configuración de lugar
    plantilla: src = config.j2
    dest = {{someapi_install_directory}} / configuration.properties
    ...

roles / someapi / vars / someapi_prod.yml

authentication_db_host: 192.168.2.4

roles / someapi / vars / someapi_stag.yml

authentication_db_host: 127.0.0.1
...

roles / someapi / templates / config.j2

authentication_db_host = {{authentication_db_host}}
...

HTH,

Iain Wright

Este mensaje de correo electrónico es confidencial y está destinado únicamente a los destinatarios.
mencionado anteriormente y puede contener información privilegiada, exenta de
divulgación según la ley aplicable. Si no es el destinatario previsto,
No divulgar ni difundir el mensaje a nadie excepto a los previstos.
recipiente. Si ha recibido este mensaje por error o no es el nombre
destinatario (s), notifique inmediatamente al remitente mediante un correo electrónico de retorno, y
eliminar todas las copias de este mensaje.

El viernes 16 de octubre de 2015 a las 12:42 p.m., arianitu [email protected] escribió:

Todavía no entiendo cómo vincular una variable a un host específico para un
libro de jugadas específico. Quiero poder usar la misma plantilla, pero con
diferentes valores de configuración según el entorno que estoy implementando
a.

Ya estamos siguiendo
http://docs.ansible.com/ansible/playbooks_best_practices.html#staging -vs-production,
haciendo diferentes inventarios para nuestros diferentes entornos

¿Por qué esto parece tan difícil con Ansible? ¿Ansible es malo haciendo
implementaciones basadas en el entorno?

Proporcione un ejemplo completo, porque "La forma ansible aquí sería
establezca el puerto y el host de la base de datos en una lista, y luego repita las tareas ".
no tiene ningún sentido para mí. ¿Dónde se especifica el entorno aquí?

Por ejemplo, tengo un servicio de autenticación que tiene una variable llamada authentication_db_host:
127.0.0.1 para Stage, y authentication_db_host: 192.168.2.4 para live. Hacer
quieres que tenga 2 variables?

authentication_db_host_stage: 127.0.0.1
authentication_db_host_live: 192.168.2.4

Ahora es difícil para mí alimentar eso a un archivo de plantilla común. Necesito
para agregar si más verifica en todo mi archivo j2 (y seguimos ese camino,
pero era demasiada duplicación y nos deshicimos de ella).

No he encontrado ninguna documentación que maneje este caso, y parece
como algo que no debería ser difícil de hacer.

-
Responda a este correo electrónico directamente o véalo en GitHub
https://github.com/ansible/ansible/issues/9065#issuecomment -148816278.

Las variables en diferentes grupos donde los mismos hosts son miembros, solo tienen sentido cuando esos grupos están en una relación padre-hijo, el hijo gana y sus variables se aplican. Si los grupos están al mismo nivel, no hay realmente una forma determinista de cuál va a ganar.

¿Ansible puede detectar estos casos y hacer una advertencia con una posible pista de solución?

Si entiendo correctamente cómo funciona, para futuros lectores como yo que luchan por entender:

  1. Los grupos de hosts en los archivos de inventario definen grupos de hosts. Las variables de grupo definen qué variables deben establecerse para los hosts de este grupo.
  2. Cuando especifico un grupo que se usará para reproducir un libro de jugadas, esto significa tomar todos los hosts que pertenecen a ese grupo.
  3. Cada juego se juega por separado para cada anfitrión; no hay contexto en el que se esté desplegando el grupo. Los grupos se utilizan para agrupar hosts y agrupar vars, para establecer variables comunes para esos hosts.
  4. Entonces, si un host se menciona en varios grupos y estos grupos tienen la misma variable con diferentes valores, se le dice al host que, debido a que pertenece al primer grupo, la variable para él se establece en el valor del grupo; entonces, debido a que el host pertenece a otro grupo, la misma variable con un valor diferente se establece sombreando el valor anterior.

El principal problema es que ansible fusiona variables incluso de grupos que no
quiero jugar ahora mismo. No necesito verificar las variables del grupo que no soy
jugando en este momento. Tal vez, la semi solución es verificar las variables
solo esos grupos, que estaba programado para ejecutar el libro de jugadas.

вс, 17 Янв 2016, 20:00, Victor Varvaryuk [email protected] :

Si entiendo correctamente cómo funciona, para futuros lectores como yo
que luchan por entender:

  1. Los grupos de hosts en los archivos de inventario definen grupos de hosts. Grupo
    Las variables definen qué variables deben establecerse para los hosts en este
    grupo.
  2. Cuando especifico un grupo que se usará para jugar un libro de jugadas, esto significa
    tomar todos los hosts que pertenecen a ese grupo.
  3. Cada juego se juega por separado para cada anfitrión, no hay contexto
    qué grupo se está desplegando. Los grupos se utilizan para agrupar hosts y agrupar
    vars: para establecer variables comunes para esos hosts.
  4. Entonces, si un anfitrión se menciona en varios grupos y estos grupos tienen
    la misma variable con diferentes valores, se le dice al anfitrión que debido a que
    pertenece al primer grupo: la variable correspondiente se establece en el grupo
    valor; entonces porque el anfitrión pertenece a otro grupo la misma variable
    con un valor diferente se establece sombreando el valor anterior.

-
Responda a este correo electrónico directamente o véalo en GitHub
https://github.com/ansible/ansible/issues/9065#issuecomment -172353019.

Esto parece muy contrario a la intuición.

Tengo un inventario que solo tiene mi caja Vagrant en cada grupo para propósitos de prueba.

Pero incluso cuando ejecuto un libro de jugadas que solo hace referencia a un solo grupo, Ansible también está obteniendo variables de los otros grupos, lo que está rompiendo mis pruebas.

El 28 de abril de 2016 a las 17:55, Philip Wigg [email protected] escribió:

Esto parece muy contrario a la intuición.

Esto se debe a que el modelo mental que utiliza para observar el inventario no es el
correcto.

Tengo un inventario que solo tiene mi caja Vagrant en cada grupo para
fines de prueba.

Pero incluso cuando ejecuto un libro de jugadas que solo hace referencia a un solo grupo,
Ansible también está extrayendo variables de los otros grupos, lo que está rompiendo
mis pruebas.

No mire el inventario tan estrechamente acoplado con los libros de jugadas. Inventario
es prácticamente una cosa separada, donde

  • Los hosts pueden ser miembros de varios grupos y, como tales, ser objetivo de
    ansible (ad-hoc) o ansible-playbook (playbooks) apuntando a uno de los
    grupos de los que es miembro el anfitrión.
  • La resolución de variables se realiza en todo el inventario, ya sea que se oriente a un
    grupo específico, o el todopoderoso grupo incorporado 'todos', no cambia eso
    las variables son heredadas, resueltas y calculadas observando todas
    definiciones de grupo y todas las variables de grupo que existen en el inventario.

HTH,

Sarga

Yo también me estoy topando con esto. En mi caso, tengo un rol que instala vhosts. Configuré los detalles para los múltiples vhosts como una matriz en mi inventario para los grupos de servidores, en otras palabras, cada grupo puede tener múltiples vhosts. Esto funciona bien, defino los vhosts para cada grupo y todo parece limpio y ordenado. El problema surge cuando el host está en más de un grupo, en ese caso, la matriz vhost en el inventario se sobrescribe y el último grupo gana, por lo que solo la mitad de mis vhosts terminan siendo aprovisionados.

Una alternativa sería colocar los vhosts en los hosts en lugar de en el grupo, pero eso no parece limpio porque tendré que duplicar para todos los servidores que están en el mismo grupo.

¿Alguien puede indicarme una mejor manera de hacer esto o de solucionarlo? Siento que estoy abusando del concepto de roles o inventario al hacer que mi rol de "vhosts" acepte una variedad de vhosts (un vhost no es exactamente un "rol" en el sentido de que no le digas a un servidor "tú eres un vhost "). ¿Alguien puede ofrecer una mejor manera de hacerlo o compartir sus pensamientos?

Por cierto, @srvg , gracias por tomarse el tiempo para responderme, fue muy apreciado y ha aclarado mi comprensión.

Mi solución es.

[servicio1]
host1 ansible_ssh_user = host1.com

[servicio2]
host2 ansible_ssh_user = host1.com

Esto es tan estupido. Pasé muchas horas tratando de depurar un problema variable, solo para descubrir que se debía a una filosofía de diseño estúpida (esto). Al menos, debería haber una advertencia cuando se cargan varios archivos group_var para el mismo host.

Es muy molesto tener group_vars cargados al azar. Hace imposible tener herencia en tal caso all> datacenter> environment (integ, devel, prod)> application> host

Es muy fácil de hacer con puppet hiera pero con ansible es una molestia y, cuando tienes> 100 libros de jugadas / roles para mantener, cargar variables explícitamente no es imprescindible porque debes mantener un archivo vars_file + un archivo group_vars para la misma función .
Tal vez tener una etiqueta en el archivo (vars_priority) o usar el nombre del archivo para arreglar el orden de carga podría ser bueno (como Apache, por ejemplo), ejemplo

  • all.yml
  • 10_datacenter_a.yml
  • 10_datacenter_b.yml
  • 20_env_production.yml
  • 40_app_gitlab.yml

luego gitlab load group vars por nombre, aquí los centros de datos, después del env, y por último la aplicación.

¡Estoy muy feliz de ver que no estoy solo en esta tontería! Las variables de grupos deben aplicarse a SU grupo de anfitriones. ¿Cómo diablos debería explicarse la directiva --limit? La forma natural de pensar es: ok, "limito" este libro de jugadas para alojar en ESE grupo, ¡¡¡¡así que ESE grupo de vars se levanta !! Ninguna variable definida en otros grupos para ese mismo host, ¡eso no tiene ningún sentido!

Espero que esto se solucione y, mientras tanto, utilizo varias entradas de DNS para el mismo host.

Pasé varias horas golpeándome la cabeza contra la mesa tratando de solucionar este problema. Con la cantidad de charlas que genera este problema, estoy realmente sorprendido de que Ansible (o Red Hat) permita que esto continúe.

¿Por qué confiar en la abstracción group_vars para fusionar vars y determinar qué es
necesario en primer lugar?

No puedo pensar en una buena razón para no definir e incluir explícitamente vars
(el ejemplo más simple se incluye arriba en el hilo)

Iain Wright

Este mensaje de correo electrónico es confidencial y está destinado únicamente a los destinatarios.
mencionado anteriormente y puede contener información privilegiada, exenta de
divulgación según la ley aplicable. Si no es el destinatario previsto,
No divulgar ni difundir el mensaje a nadie excepto a los previstos.
recipiente. Si ha recibido este mensaje por error o no es el nombre
destinatario (s), notifique inmediatamente al remitente mediante un correo electrónico de retorno, y
eliminar todas las copias de este mensaje.

El martes 27 de septiembre de 2016 a las 11:53 a. M., Jason Hane [email protected]
escribió:

Pasé varias horas golpeándome la cabeza contra la mesa tratando de moverme
este problema. Con la cantidad de charlas que genera este problema, estoy realmente
sorprendido Ansible (o Red Hat) está permitiendo que esto continúe.

-
Estás recibiendo esto porque comentaste.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/ansible/ansible/issues/9065#issuecomment -249961581,
o silenciar el hilo
https://github.com/notifications/unsubscribe-auth/AATjccSt7D7FJfzdA8r86kb1GQvxLBnaks5quWY4gaJpZM4Cjyd4
.

Parte del problema es que no está claro de inmediato así es como Ansible analiza las variables. Uno pensaría (como lo demuestra la cantidad de personas que tienen este problema) que asignar un host a un grupo y ejecutar solo ese grupo, heredaría las variables solo para ese grupo y no para todos los grupos en los que se encuentra el host.

Ejecutar todos los hosts es una historia diferente, pero al menos entonces debería ser una suposición clara de que Ansible tomaría todas las variables para todos los grupos en los que se encuentra el host. Ansible debería hacer un mejor trabajo aclarando esas suposiciones o proporcionar una bandera que permita este comportamiento .

¿Por qué confiar en la abstracción group_vars para fusionar vars y determinar qué es
necesario en primer lugar?

¡Ese es EXACTAMENTE el punto de una abstracción! Si la herramienta me permite abstraer mi entorno en diferentes grupos y luego, aplicando reglas claras de inferencia, deducir qué variables deben usarse, ¿por qué no usarla? Así que aquí hay dos problemas: las reglas no son claras o la abstracción no funciona. De lo contrario, explíqueme el propósito de groups_vars si necesito definir e incluir explícitamente vars.

Debo decir que la documentación no menciona este caso específico de que el mismo host se haya incluido en varios group_vars. Pero este caso es muy real en el host donde existen múltiples instancias de servicio (por ejemplo, apache). Realmente espero que este problema se resuelva pronto.

Hemos encontrado una manera de resolver nuestro problema de aplicación / env con la herencia de variables mediante la definición cruzada de variables entre grupos usando un prefijo.
por ejemplo

app_collectd.yml
collectd_host: "{{env_collectd_host}}"

env_production.yml
env_collectd_host: 1.1.1.1

entonces ahora no es un problema, tenemos una aplicación clara de variables + variables env usando variables de llamada cruzada

Vengo de Puppet-land, donde hacer abstracción y reutilización de código es simple y claro. Tal vez no entiendo correctamente cómo Ansible se acerca a esto, así que si hay una manera mejor que no involucre group_vars, soy todo oídos. Lo que no quiero tener que hacer es mantener otro conjunto de variables para cada host o grupo para especificar dónde debería obtener sus variables. Para mí, eso debería ser responsabilidad del marco. Esta es la belleza de Hiera en Puppet.

@hyojinbae

Mi solución es.

[servicio1]
host1 ansible_ssh_user = host1.com

[servicio2]
host2 ansible_ssh_user = host1.com

¿puedes explicarlo en detalle?

Lo pruebo así, no igual que el tuyo, ¡pero funciona!

[service1]
host1 ansible_host=192.168.0.10

[service2]
host2 ansible_host=192.168.0.10

Una víctima más aquí.

¿Alguien ha encontrado una buena solución para el siguiente escenario?

Digamos que tengo una lista de aplicaciones web (app-a, app-b, app-c). Y hay 4 hosts en 2 DC para DR / equilibrio de carga. Quiero usar ansible para simplificar la implementación.

Mi primer instinto es usar vars grupales, obviamente fallé, pero ¿qué alternativa ofrece Ansible?

inventario

[dc1]
host1
host2

[dc2]
host3
host4

[cluster:children]
dc1
dc2

[app-a:children]
cluster

[app-b:children]
cluster

[app-c:children]
cluster

group_vars
aplicación-a

http_port: 8081

aplicación-b

http_port: 8082

aplicación-c

http_port: 8083

El libro de jugadas básicamente espera que los hosts pasen a través de la línea de comandos:

- host: {{app-name}}
- tasks: 
  # deploy application with given {{http_port}}....

Esto es lo que hago para evitarlo

- hosts: "{{ app-name }}"

vars_files:
    - "vars/{{ app-name }}.yml"

@hanej Gracias, eso ciertamente apunta a una dirección que no conocía.
Sin embargo, ahora estoy más inclinado a usar roles para la reutilización de código y declarar variables directamente en el libro de jugadas. Aunque eso significa que tendré un libro de jugadas por aplicación, pero al declarar la variable justo al lado del rol que la usará, haré que toda la configuración sea mucho más fácil de entender.

@hanej Gracias, esta solución es brillante. Me salvaste.

@hanej Genius!

Estoy tan sorprendido de que esto sea un problema. Me lo estoy encontrando porque tengo una única función que uso con varios grupos de inventario que tienen archivos group_var asociados. En QA / Prod, esto no es un problema, porque cada grupo de inventario tiene diferentes servidores. Pero para los entornos de nivel de integración, tendemos a aplastar todo en servidores únicos (por eso veo este problema).

Siguiendo el consejo de hanej, modifiqué mi libro de jugadas yml para cargar explícitamente el archivo group_var:

hosts: publish
vars_files:
  - group_vars/publish.yml

"Esto es tan estúpido. Pasé muchas horas tratando de depurar un problema de variable, solo para descubrir que era debido a una filosofía de diseño estúpida (esto). Al menos, debería haber una advertencia cuando se cargan varios archivos group_var para el mismo anfitrión ".

Solo para actualizar este "PROBLEMA" / "LIMITACIÓN"
Bien, podemos usar una solución para eliminar el conflicto (con host ansible o de otra manera)
pero la mejor manera debería ser la variable de propósito en ansible.cfg para definir:
"encierre group_vars" o "fusionar group_vars"

No puedo usar group_vars solo por esta razón. Tenemos hosts en varios grupos (DC, entorno, aplicación, etc.) y no tenemos control sobre cómo se leen las variables. Viniendo de Puppet usando Hiera, esto es un gran problema. En mi opinión, Ansible debería adoptar algo como Hiera usando el patrón de "roles y perfiles" donde puede especificar el orden de cómo se consumen las variables en función de hechos o grupos. Hago esto ahora usando el enfoque anterior.

Por ejemplo, si tiene un host en un rol llamado "/ Hosts Linux / Aplicaciones / Java / Sitio web", debería poder heredar variables de Hosts Linux (variables de nivel global como sysctl, DNS, NTP, etc.), Aplicaciones (global variables de nivel de aplicación), Java (variables específicas de Java como la versión JDK, JAVA_HOME, etc.) y Sitio web (variables relacionadas específicamente con la aplicación del sitio web). Cuanto más baja en el árbol, más específicas se vuelven las variables, lo que puede anular las variables que están más arriba.

Usar Ansible para ejecuciones ad hoc o controladas por eventos es genial y funciona muy bien, sin embargo, encuentro que usar Ansible para la administración de la configuración no es tan limpio o fácil de usar como Puppet y Hiera principalmente por esta razón.

2 años después, sigo recibiendo un flujo constante de correos electrónicos sobre este tema (también es uno de los temas más comentados en este github). ¿Los mantenedores de Ansible todavía sienten que el comportamiento actual es correcto, aunque es muy poco intuitivo?

Ustedes necesitan documentar seriamente cómo hacer la administración de la configuración con Ansible porque cualquiera que intente implementar una aplicación con este proyecto lo está pasando fatal.

Hemos decidido dejar de usar Ansible por completo. Apesta en la gestión de la configuración, punto.

Buena suerte con el proyecto.

Sí, me encontré con el mismo problema al configurar el proceso de implementación para archivos de configuración para diferentes entornos, mientras probaba en el mismo host. Voy a adoptar todo el método {{app-name}} - {{env}}. Yml propuesto por @hanej , pero me encantaría que el comportamiento de group_vars al menos sea configurable.

Feliz de haber encontrado este problema después de golpearme la cabeza contra la pared durante incontables horas ... Y estoy extremadamente sorprendido de la actitud desdeñosa de los mantenedores con respecto a este error al llamarlo una "característica", es una estupidez más allá del reconocimiento.

Estoy intentando configurar un libro de jugadas / rol de implementación genérico usando un inventario dinámico. La salida del inventario se ve así:

{
  "resource-service_ci": {
    "vars": {
      "nginxpool": "resource_pool",
      "httpport": "8800"
    },
    "hosts": ["host1.example.com", "host2.example.com"]
  },
  "example-service_ci": {
    "vars": {
      "nginxpool": "example_pool",
      "httpport": "8100"
    },
    "hosts": ["host1.example.com","host3.example.com"
    ]
  }
}

Desafortunadamente, puede haber varias aplicaciones en un solo host. Todo el punto al usar un inventario dinámico se evapora si las variables de grupo se mezclan y devuelven 'aleatoriamente' en lugar de heredar las variables solo para ese grupo que estoy ejecutando --limitar con

Probé la solución de

_ "hosts": ["host1 ansible_host = host1.example.com", "host2 ansible_host = host2.example.com"] _

pero Ansible claramente no entiende que intentar ssh a host1 ansible_host = host1.example.com

¿Alguien más enfrenta el mismo problema y, si es así, tiene una posible solución?

Podría pasar las variables de puerto y agrupación en la línea de comando ya que tienen prioridad, pero luego tengo que hacer una búsqueda fea antes.

Lo estaba pasando muy bien con Ansible hasta que me encontré con este error.

Tenía una abstracción perfecta que permitiría la configuración de las mismas aplicaciones en un entorno de varios niveles y también en un entorno de prueba todo en uno; por desgracia, estaba equivocado.

Lo que parecía una de las características más poderosas de Ansible no funciona como todos esperarían.

Por favor, arreglemos esto.

Pasé horas golpeándome la cabeza contra la mesa tratando de solucionar este problema. Solucione este problema.

Esta "característica" desperdició la mayor parte de mi día. No divertido.

@hanej Gracias por la elegante solución. Ahora estamos configurando una variable env en nuestros archivos environment/group_vars/all al nombre del entorno.

En nuestros libros de jugadas, hacemos esto:

- hosts: group
  vars_files:
    - "{{ env }}/group_vars/group.yml
  roles:
    - ...

Sé que han pasado 2.5 años y que Ansible probablemente nunca verá esto, pero solo agregaré mi frustración con esto. ¿Por qué permitir que los usuarios coloquen un host en varios grupos si no puede usar los grupos por separado?

Por qué permitir que los usuarios coloquen un host en varios grupos

Ese es mi problema con los desarrolladores de Ansible. Parece que solo piensan en sí mismos. Al menos podrían intentar aliviar la frustración emitiendo algunas advertencias. En cambio, prefieren escupir.

Filtramos los problemas cerrados y no vemos comentarios sobre ellos, pero alguien me hizo ping para responder a algunas de estas preguntas. Si desea que los desarrolladores le presten atención, la lista de correo o el IRC son mejores conductos que los tickets cerrados.

Ansible considera los grupos como propiedades de un anfitrión. Por ejemplo, puede hacer que un host forme parte del grupo de servidores web (para instalar un servidor web reqs) y parte del grupo noreste_datacenter (para que sepa la puerta de enlace de red, los servidores ntp y dns que debe configurar) también parte del dev_group para instalar herramientas de desarrollo y apuntar a la base de datos de no producción, etc., etc.

PUEDE usar los grupos como una forma de apuntar a los hosts, pero eso no significa que las otras 'propiedades del host' desaparezcan. Estoy en el grupo 'machos' y en el grupo 'programadores', solo porque me 'seleccionas' como programador no dejo de ser hombre.

Al final, esta es una decisión de diseño (no un error) sobre cómo abordar los grupos, una forma de clasificar y agregar propiedades a los hosts. Sé que otras herramientas las usan de manera diferente, pero esa no es una razón para cambiar la forma en que funcionan en Ansible, ya que no hay una forma uniforme en que TODAS las demás herramientas usan grupos, muchas otras las ven de esta manera y muchas no las ven.

Esto tiene la limitación de no poder reutilizar los nombres de las variables y solo tiene el 'grupo actual aplicar', pero tiene la ventaja de ver siempre la imagen más grande de cómo se define el host y hace que los conflictos sean fáciles de detectar o resolver. En la mayoría de los casos anteriores, el uso de vars_files o include_vars parece más apropiado que configurarlos como grupos, cuando se habla de variables específicas de la aplicación.

Haciendo include_vars en group_vars ... bueno, así no es como lo diseñamos, pero si funciona para usted ... la advertencia es que está 'cargando doble' ya que los group_vars se incorporan automáticamente, esto puede llevar a problemas de rendimiento en general inventarios. Recomendamos más específico, vars_files: vars/app1.vars.yml o similar con include_vars.

Espero que esto aclare por qué los grupos funcionan de la manera en que lo hacen en Ansible y por qué eso es diferente a 'otra herramienta específica', avíseme si hay algo que pueda agregar a nuestros documentos http://docs.ansible.com/ansible/ intro_inventory.html para aclarar y evitar frustraciones.

Me encantaría adaptarme a la forma de trabajar de todos, Ansible es muy flexible en algunas áreas, pero no en este sentido y no veo una buena manera de hacerlo ni una forma sensata de compartir libros de jugadas después.
Si me equivoco, espero tu solicitud de extracción.

@bcoca ¿ es posible detectar casos en los que las variables de grupo se están usando de una manera extraña (lo siento, no puedo formular esto mejor, no lo he usado durante mucho tiempo) y hacer advertencias para ayudar a los usuarios a ahorrar tiempo?

@bcoca Lo que no me

¿Puede dar un ejemplo de un caso que se satisfaga bien con la solución actual pero dejaría de serlo si, por ejemplo, group_vars solo se cargan / consideran para los grupos seleccionados para una obra determinada, en lugar de para todo el inventario?

Parece bastante fácil encontrar ejemplos que están rotos por la forma en que está ahora.

Entiendo el punto de @bcoca ya que lo usamos de esa manera también. Mi mayor frustración con Ansible es que funciona principalmente bien para la administración de la configuración o para los flujos de trabajo ad-hoc. Tampoco hace un gran trabajo, pero está mejorando y tiene compatibilidad con complementos que creo que usaré para mejorar otro problema que tengo con él. La mayoría de los días todavía extraño Puppet únicamente por la gestión de la configuración ...

Probablemente, el mejor caso de uso para group_vars son múltiples centros de datos. Digamos que su archivo de inventario se ve así:

[dc1]
host1
host2

[dc2]
host3
host4

[app1]
host1
host3

[app2]
host2
host4

Puede usar group_vars para establecer variables específicas del centro de datos que serían heredadas por todos los hosts en ese centro de datos.

group_vars/
    dc1.yml
    dc2.yml
    app1.yml
    app2.yml

dc1.yml

---
ntp_servers:
  - 10.10.10.10
  - 10.10.10.11

dc2.yml

---
ntp_servers:
  - 10.11.10.10
  - 10.11.10.11

Usar group_vars como este está bien hasta que necesite fusionar o anular una variable en otro archivo group_var. Este es otro caso en el que group_vars se rompe. No hay forma de establecer el orden en el que se leen las variables en group_vars. Aquí me viene a la mente un diseño jerárquico (como Hiera) que puede ser determinado por hechos y no por grupos para cosas como variables ambientales, pero estoy divagando.

Desde mi perspectiva, este caso de uso es principalmente bueno para la administración de configuración directa, pero no es tan bueno en implementaciones o scripts ad-hoc. Es por eso que me encantaría ver un interruptor para deshabilitar esta función para ciertos libros de jugadas en los que no desea hacer esto.

@hanej No estoy seguro de cómo ese ejemplo rompe con el cambio de diseño que sugerí en mi comentario anterior.

Dado el inventario que ha enumerado, si ansible-playbook -i /my-inventory -v some_playbook.yml -l dc1:&app2 Cualquier some_playbook.yml usted escribiría contra ese inventario, tendría que ser bastante elaborado para que se rompa cuando las variables de dc1.yml y app1.yml solo se cargaron.

Estoy de acuerdo en que las implementaciones son un problema. Implementaciones multiinquilino, específicamente.

Tengo dos preocupaciones sobre cómo funcionan las cosas ahora:

Primero, falta de espacio de nombres de configuración. Específicamente, si mantengo la configuración para algunas aplicaciones en un entorno de múltiples inquilinos, ¿cómo me aseguro de que alguien que mantiene una aplicación diferente que se ejecuta en las mismas máquinas no agregará un nombre de variable que entre en conflicto con el mío? o que no agregaré uno que entre en conflicto con el de ellos?

En segundo lugar, el caso del que todo el mundo sigue hablando aquí. Esperaría que con el siguiente inventario, nunca terminaría con archivos escritos en /data/prod cuando ejecuto ansible-playbook -i inventory -v data_deploy.yml -l app1_staging , y que los archivos nunca se escribirían en /data/staging cuando ejecuto ansible-playbook -i inventory -v data_deploy.yml -l app1_prod

Estos dos problemas ya son bastante graves por sí solos, pero en una empresa grande donde muchas personas en diferentes zonas horarias pueden estar editando el mismo inventario, la solución actual parece más que un poco arriesgada.

Ejemplo de inventario.

[dc1]
host1
host2

[dc2]
host3
host4

[app1_staging]
host1
host2
host3
host4

[app1_prod]
host1
host2
host3
host4

app1_staging.yml:

---
  data_path: /data/staging

app1_prod.yml:

---
  data_path: /data/prod

No sé si la edición funcionó para ajustar la notificación, mi último comentario estaba destinado a ser dirigido a @hanej.

@benjamincburns Solicitó un ejemplo del uso de group_vars que satisfaga el método de carga actual pero se interrumpa si solo usa los grupos inmediatos. Proporcioné eso con el ejemplo del centro de datos. Si Ansible no carga variables para todos los grupos, entonces no puede establecer variables, por ejemplo, a nivel de centro de datos.

Creo que esto debería ser un interruptor en ansible.cfg o en la línea de comando para que pueda especificar cómo cargar group_vars para que no rompa los casos de uso existentes. Tenemos entornos multiinquilino aquí y solíamos ser mordidos por esto hasta que dejé de usar group_vars.

No estoy seguro de si ha oído hablar del patrón de roles y perfiles, pero es una lectura realmente buena y recomiendo este enfoque si está utilizando algún tipo de herramienta de administración de configuración. Fue escrito para Puppet pero se aplica a todas las herramientas. Probablemente no usaría esto para implementaciones o cosas ad-hoc, pero para la administración de configuración directa es genial.

http://www.craigdunn.org/2012/05/239/

Utilizo hosts de Docker, por lo que es bastante normal tener diferentes instancias de contenedores en diferentes entornos repartidos entre hosts y esto me mordió.

Gracias a @hanej por la solución alternativa y también agregaría que las variables de grupo no funcionan como se anuncia y parecen estar rotas por diseño.

Mi solución es definir una obra de la siguiente manera:

- hosts: "{{ group }}"
  vars_files:
    - "vars/{{ group }}.yml" 
  roles:
    - role1 etc

Ponga un directorio vars en el directorio del libro de jugadas con group1.yml, group2.yml allí.

Sería terrible si sus configuraciones cambiaran simplemente porque se _accedió de manera diferente_. Solo piense en el efecto que tendría en los intentos de arquitectura convergente. +1 al equipo de Ansible por mantener las variables lo más consistentes posible.

La pregunta más interesante es cómo se puede aplicar el mismo rol varias veces, compartiendo algunas configuraciones entre hosts mientras se _extender_ (y no reemplazar) otras. Creo que las dependencias de roles lo permiten, a saber, por:

  • Cree "roles de envoltura" que incluyan roles que desee ampliar como dependencias.
  • Especifique allow_duplicates: true en el meta/main.yml su contenedor.
  • Pase sus extensiones de configuración a la declaración de roles (ver más abajo).
  • Establezca configuraciones compartidas y estables en group/host_vars .

Entonces, en esencia, su rol de contenedor incluiría un meta.yml como:

---
# roles/my-app/meta.yml
allow_duplicates: true
dependencies:
  - role: nginx
    nginx_servers:
      - name: server-myapp
        contents: |
          ...

Cuando aplica la función de contenedor, solo se cambian realmente las configuraciones "extensibles". Los desarrolladores tienen la carga de diseñar sus roles de una manera que admita este patrón.

Equipo de Ansible: ¿era esta su intención sobre cómo se utilizarían los roles? Honestamente, no he visto un mejor caso de uso para las dependencias; todo lo demás parece conducir a una sopa de códigos.

Me acabo de unir a la lista de víctimas hoy después de una hora de depuración y tuve la suerte de encontrar esta publicación.
Creo que es solo un problema de documentación, nadie se quejará si se indica claramente aquí:
http://docs.ansible.com/ansible/intro_inventory.html#group -variables
el hecho de que las variables estén asociadas con hosts y grupos es solo una forma conveniente de establecer variables para todos los hosts que le pertenecen. Las variables se anularán si se utiliza el mismo host en varios grupos.

+1 Este problema afecta a nuestro equipo de software.

Lamentablemente, también nos encontramos con este problema hoy. La misma historia, aunque tenemos un rol genérico de "gato", variamos las variables como los números de puerto según el grupo que se utiliza.
Sin embargo, se pueden implementar varias instancias de Tomcat en los mismos servidores físicos, por lo que creamos varios grupos en los inventarios que contienen el mismo conjunto de servidores.

Sin embargo, este enfoque no parece funcionar. Todavía no tengo idea de cómo diseñar esto. No puedo crear roles de envoltura que tengan las variables porque algunas de las variables son en realidad específicas del inventario. Piense, por ejemplo, en una contraseña de base de datos oid.

Recientemente encontré esto que alivió mi dolor con este problema:
https://github.com/leapfrogonline/ansible-merge-vars

Permite la fusión de variables sin importar dónde se hayan definido, por lo que puede fusionar dos dictados / listas en dos grupos diferentes, por ejemplo, en lugar de que un grupo gane y sobrescriba la variable definida en los otros grupos como es el comportamiento actual. El complemento solo funciona con Ansible 2+.

Puede encontrar un buen artículo que explica el concepto y el caso de uso aquí .

Recientemente también hemos abordado este tema. Tenemos múltiples aplicaciones ejecutándose en un solo host como diferentes usuarios . Por ejemplo:

[group_a]
host1

[group_b]
host1

No tenemos forma de especificar ansible_user con vars correctamente, ni con host_vars ni group_vars . La última definición siempre gana en ambos casos.

Nuestra solución actual es definir múltiples jugadas con diferentes ansible_user en el libro de jugadas:

- hosts: group_a
  ansible_user: user_a
  roles:
    - my-role

- hosts: group_b
  ansible_user: user_b
  roles:
    - my-role

@hyojinbae sugirió una forma inteligente arriba para solucionar esto:

[group_a]
user_a<strong i="8">@host1</strong> ansible_user=user_a ansible_host=host1

[group_b]
user_b<strong i="9">@host1</strong> ansible_user=user_b ansible_host=host1

Así que ahora cada anfitrión tiene un nombre único en el inventario. No es un gran fanático poner vars de host en el inventario, pero esta es la mejor solución que he visto hasta ahora.

@hyojinbae Creo que te estás perdiendo los puntos de hostvars y directivas:

- hosts: group_a
  remote_user: user_a
  roles:
    - my-role

- hosts: group_b
  remote_user: user_b
  roles:
    - my-role

debería funcionar siempre que no establezca ansible_user. Los grupos son una propiedad del anfitrión, no una entidad en sí mismos.

Hubo una propuesta para hacer posible la escritura de complementos adecuados para la gestión de inventario. Sospecho que ahora que esta propuesta se cerró / terminó, debería ser posible implementar un complemento de inventario dinámico que solucione este punto de confusión.

Ir a +1 para cuestionar el diseño ansible aquí.
En el mundo real, se pueden ejecutar muchas aplicaciones diferentes en el mismo host.
El alcance de group_vars a nivel de host simplemente no cubre este caso de uso.

Solo como un experimento mental:

  • Supongamos que el comportamiento predeterminado se modificó para que la ejecución de ansible-playbook con la opción "-l" use el archivo secundario group_vars (si existe).
  • Aún puede manejar el caso de uso del "centro de datos" que se mencionó a través de los grupos principales.
  • Todo lo que cambiaría es que el grupo hijo "nombrado" para un partido anfitrión ganaría la batalla de herencia, en lugar del "último" grupo hijo para un partido anfitrión.

Hacer este pequeño cambio haría felices a cientos de personas de DevOps y no haría daño a nadie.

De mi comentario anterior, consulte https://github.com/ansible/proposals/issues/41 para ver una vía potencial para permitir un comportamiento más conectable aquí.

No puedo creer que Ansible no solucione (dé pistas, advierta) o responda más sobre este problema.
Me tomó algunas horas depurarlo.

También encontré esto. Un enfoque fue utilizar variables anidadas. Así que tome el grupo de inventario my_app_servers, por ejemplo, y se alinea con el archivo my_app_servers.yml dentro de su group_vars, y tiene más de una aplicación para administrar en un host común. Los anidaba así

Ejemplo: my_app_servers.yml

application_env:
  - application1
  - application2

application_environments:
  application1: 
    app_port: 8080
    app_conf_dir: "/somedirectory/conf"
    app_logs_dir: "/somedirectory/logs"
    app_install_name: app1prd

   application2: 
     app_port: 8081
     app_conf_dir: "/somedirectory/conf"
     app_logs_dir: "/somedirectory/logs"
     app_install_name: app2prd

En su main.yml, defina un ciclo e itere sobre la lista de variables anidadas como esta,

with_items: "{{application_env}}"
loop_control:
loop_var: application_env_item

Luego, en sus tareas, puede tomar la variable anidada que desee para ejecutar algo.
{{application_environments [application_env_item] ['app_install_name']}}
(si puede sacar una var de esa lista, puede obtener el resto). Espero que ayude.

Este problema (# 9065) se cerró en 2015. Mismo # 6538. Mismo # 6666. Y muchos más.
Aquí está 2018, 4 años después de que se abrieran muchos problemas, y aparentemente hace más calor que al principio, y todos perdieron horas debido a un diseño contra-intuitivo.
En mi humilde opinión, esto parece una necesidad de revisión por parte del equipo de diseño.

Si todos continúan usando los trucos propuestos, el código ansible se volverá feo:

En mi humilde opinión, estos trucos lo hacen menos atractivo si no está completamente alineado con el lema de "automatización de TI simple " de ansible;)

@bcoca ->

Creo que los propios group_vars deberían poder tener prioridad. Hiera for Puppet lo hizo bien. Puede especificar cómo se realizan las búsquedas en función de hechos o grupos. Permita que el usuario final pueda personalizar cómo se deben procesar group_vars y proporcione un mecanismo para ver fácilmente el orden en el que Ansible está aplicando esas variables.

Para su información, normalmente no vemos notificaciones sobre problemas cerrados, respondiendo aquí porque alguien me señaló esto, también voy a bloquear para que la gente no siga comentando en un foro que los mantenedores no verán.

@hanej creo que quieres la configuración ansible_group_priority y [defaults]precedence , ya que para la introspección en este momento tienes ansible-inventory que te muestra el resultado final, todavía estamos trabajando para darle a la gente una mejor ver dónde / qué establece el valor final de una variable.

@ReSearchITEng abre una propuesta (http://github.com/ansible/proposals), pero se trata de un enfoque fundamental de cada aplicación de diferencias. Ansible se enfoca en una tarea para un anfitrión, las otras herramientas que menciona se enfocan en una estructura mucho más compleja.

Para los 'grupos' ansible son solo una propiedad de un host, no una entidad principal, las otras herramientas se enfocan en los grupos como 'el contexto principal' y todo lo demás se agrega a eso.

No veo ninguno de los enfoques como "incorrecto", solo diferente. Tratar de hacer que Ansible funcione de esa manera romperá el paradigma de la simplicidad, se centrará en un anfitrión y una tarea para lo que es solo un enfoque organizacional y trasladará lo que veo como la 'forma de pensar acostumbrada' que la gente trae de otras herramientas.

Yo diría que esto es solo una percepción sobre la organización de datos y los hábitos, pero esa es solo mi opinión. Siéntase libre de enviar una propuesta, si convence y gana suficiente tracción con los mantenedores, podría obtener el cambio que desea, simplemente no creo que sea un cambio que necesitemos.

¿Fue útil esta página
0 / 5 - 0 calificaciones