facts - register variable ansible
Ansible: cómo construir una variable a partir de otra variable y luego recuperar su valor (7)
Actualmente estoy usando la sintaxis similar a una matriz de Jinja 2 . No creo que esta sea una gran solución, pero aún tengo que encontrar algo mejor.
Déjame dar un ejemplo con una de mis tareas abstractas. Ver mi configuración de variables y tarea de ejemplo a continuación:
# Variables file, available in the task context
containers:
app:
image: mynamespace/myappcontainer:snapshot
web:
image: nginx:latest
db:
image: mariadb:latest
# Example task
- name: Start containers
docker_container:
name: "{{ item }}"
image: "{{ containers[item].image }}"
with_items:
- app
- web
- db
En el ejemplo anterior, estoy usando el bucle ansible with_items
, que ejecuta la tarea para cada elemento y hace que la variable {{ item }}
esté disponible en consecuencia.
Esto da como resultado la creación de 3 contenedores Docker, cada uno con el nombre del contenedor adecuado en función de la lista de elementos y la imagen adecuada recuperada de las variables externas que he configurado.
Aunque este ejemplo usa with_items
, por with_items
, es adaptable a su problema con el uso de sus propias variables.
Aunque esto funciona perfectamente bien en esta situación, me temo que requiere que las variables a las que desea acceder formen parte de alguna variable principal ( containers
en este ejemplo). Por lo tanto recomiendo dividir variables con a .
para construir una jerarquía, y no con una _
.
Una variable como abc
donde b
es dinámica, sería accesible usando a[b].c
.
Una variable como ab
donde b
es dinámica, sería accesible usando a[b]
.
Una solución que utilizarías podría parecer (sin probar):
- name: "Play to for dynamic groups"
hosts: local
vars:
- target: smtp
- hosts:
smtp: smtp.max.com
imap: imap.max.com
tasks:
- name: testing
debug: msg={{ hosts[target] }}
Tenga en cuenta que las variables se configuran de forma ligeramente diferente, ya que su estructura es jerárquica.
Aquí está mi problema, necesito usar una variable ''target_host'' y luego agregar ''_host'' a su valor para obtener otro nombre de variable cuyo valor necesito. Si miras mi libro de jugadas. La tarea nbr 1,2,3 obtiene el valor de la variable, sin embargo, nbr 4 no puede hacer lo que espero. ¿Hay alguna otra manera de lograr lo mismo en ansible?
---
- name: "Play to for dynamic groups"
hosts: local
vars:
- target_host: smtp
- smtp_host: smtp.max.com
tasks:
- name: testing
debug: msg={{ target_host }}
- name: testing
debug: msg={{ smtp_host }}
- name: testing
debug: msg={{ target_host }}_host
- name: testing
debug: msg={{ {{ target_host }}_host }}
Output:
TASK: [testing] ***************************************************************
ok: [127.0.0.1] => {
"msg": "smtp"
}
TASK: [testing] ***************************************************************
ok: [127.0.0.1] => {
"msg": "smtp.max.com"
}
TASK: [testing] ***************************************************************
ok: [127.0.0.1] => {
"msg": "smtp_host"
}
TASK: [testing] ***************************************************************
ok: [127.0.0.1] => {
"msg": "{{{{target_host}}_host}}"
}
Me parece que puedes usar la opción var
lugar de msg
:
debug: var="{{ target_host }}_host"
Da:
TASK [testing] ********************************************************************************************************************************
ok: [localhost] => {
"smtp_host": "smtp.max.com"
}
Necesitas poner comillas a su alrededor:
- hosts: local
vars: [ target_host: smtp ]
tasks:
debug: msg="{{ target_host }}_host"
editar
Kashyap necesito ir un nivel más que este. Imagine que hay otra variable ''smtp_host'' y quiero construir esa variable en tiempo de ejecución utilizando otra variable (target_host) y adjuntando una cadena ''_host'' a ella. = {{{{target_host}} _ host}} - Max
Mi error. No leí con la suficiente atención.
Esto (AFAIK) no es posible. La principal limitación que nos impide hacer esto (no importa cómo lo hagas girar), es que la "expansión variable" en ansible es un proceso de una sola pasada y lo que deseas requiere varias pasadas.
Las únicas formas en las que puedo pensar son:
- Cree el libro de jugadas dinámicamente desde su libro de jugadas usando una
template
y ejecútelo. - He oído que el motor Jinja2 hace una evaluación de varias pasadas. Puede ser si coloca estas cadenas en una plantilla y luego usa el filtro de
lookup(''template'', ...)
. Desafortunadamente, no tengo experiencia con las plantillas de Jinja2, así que no estoy seguro de si esto es una opción.
Puede usar "hostvars" para pasar la variable, los datos de host se pueden cargar desde vars de grupo o vars de host
yml
---
- name: "Play to for dynamic groups"
hosts: x0
vars:
- target_host: smtp
tasks:
- set_fact: smtp_host="smtp.max.com"
- set_fact: host_var_name={{target_host}}_host
- set_fact: dym_target_host={{hostvars[inventory_hostname][host_var_name]}}
- name: testing
debug: msg={{ target_host }}
- name: testing
debug: msg={{ smtp_host }}
- name: testing
debug: msg={{ target_host }}_host
- name: testing
debug: msg={{ dym_target_host }}
salida:
PLAY [Play to for dynamic groups] *********************************************
GATHERING FACTS ***************************************************************
ok: [x0]
TASK: [set_fact smtp_host="smtp.max.com"] *************************************
ok: [x0]
TASK: [set_fact host_var_name=smtp_host] **************************************
ok: [x0]
TASK: [set_fact dym_target_host={{hostvars[inventory_hostname][host_var_name]}}] ***
ok: [x0]
TASK: [testing] ***************************************************************
ok: [x0] => {
"msg": "smtp"
}
TASK: [testing] ***************************************************************
ok: [x0] => {
"msg": "smtp.max.com"
}
TASK: [testing] ***************************************************************
ok: [x0] => {
"msg": "smtp_host"
}
TASK: [testing] ***************************************************************
ok: [x0] => {
"msg": "smtp.max.com"
}
PLAY RECAP ********************************************************************
x0 : ok=8 changed=0 unreachable=0 failed=0
Puedes anidar tus búsquedas así:
---
- hosts: local
connection: local
gather_facts: no
vars:
target_host: smtp
lookup_host: "{{ target_host }}_host"
smtp_host: smtp.max.com
tasks:
- debug: var="{{ lookup_host }}"
Si tienes una variable como
vars: myvar: xxx xxx_var: anothervalue
La sintaxis de trabajo de Ansible:
- debug: msg={{ vars[myvar + ''_var''] }}
Te daremos el análogo de:
- debug: msg={{ xxx_var }}
Tienes dos formas de elegir:
1. Uso general.
vars:
- target_host: smtp
- smtp: smtp.max.com
tasks:
- name: testing
debug: msg={{ target_host }}
- name: testing
debug: msg={{ smtp }}
- name: testing
debug: msg={{ vars[target_host] }}
2. usando fact
tasks:
- set_fact: target_host=smtp
- set_fact: smtp=smtp.max.com
- name: testing
debug: msg={{ target_host }}
- name: testing
debug: msg={{ smtp }}
- name: testing
debug: msg={{hostvars[inventory_hostname][target_host]}}