commands - ansible playbook example
Cómo asignar una matriz a una variable en Ansible-Playbook (5)
Las variables se pueden representar como estructuras YAML estándar, por lo que puede asignar un valor de lista a una clave como esta:
---
- hosts: db
vars:
postgresql_ext_install_contrib: yes
postgresql_pg_hba_passwd_hosts:
- ''10.129.181.241/32''
- ''1.2.3.0/8''
En un libro de jugadas obtuve el siguiente código:
---
- hosts: db
vars:
postgresql_ext_install_contrib: yes
postgresql_pg_hba_passwd_hosts: [''10.129.181.241/32'']
...
Me gustaría reemplazar el valor de postgresql_pg_hba_passwd_hosts
con todos mis servidores web privados ips . Entiendo que puedo obtener los valores como this en una plantilla :
{% for host in groups[''web''] %}
{{ hostvars[host][''ansible_eth1''][''ipv4''][''address''] }}
{% endfor %}
¿Cuál es la forma más sencilla / fácil de asignar el resultado de este bucle a una variable en un libro de jugadas ? ¿O hay una mejor manera de recopilar esta información en primer lugar? ¿Debo poner este bucle en una plantilla?
Desafío adicional: Tendría que agregar /32
a cada entrada.
Para agregar ''/ 32'' a la dirección, puede usar el filtro ipaddr de Ansible ( convertir a notación CIDR ).
{{ ip_addresses|ipaddr(''host'') }}
Puede asignar una lista a la variable por set_fact y un plugin de filtro ansible.
Ponga el complemento de filtro personalizado en el directorio filter_plugins como este:
(ansible top directory)
site.yml
hosts
filter_plugins/
to_group_vars.py
to_group_vars.py convierte hostvars en la lista que seleccionó por grupo.
from ansible import errors, runner
import json
def to_group_vars(host_vars, groups, target = ''all''):
if type(host_vars) != runner.HostVars:
raise errors.AnsibleFilterError("|failed expects a HostVars")
if type(groups) != dict:
raise errors.AnsibleFilterError("|failed expects a Dictionary")
data = []
for host in groups[target]:
data.append(host_vars[host])
return data
class FilterModule (object):
def filters(self):
return {"to_group_vars": to_group_vars}
Use así:
---
- hosts: all
tasks:
- set_fact:
web_ips: "{{hostvars|to_group_vars(groups, ''web'')|map(attribute=''ansible_eth0.ipv4.address'')|list }}"
- debug:
msg: "web ip is {{item}}/32"
with_items: web_ips
Puedes usar los filtros jinja2:
{{ groups[''nodes'']|map(''extract'', hostvars, [''ansible_eth1'',''ipv4'', ''address'']) |list }}
devolverá una lista de direcciones ip. es decir
---
- hosts: db
vars:
postgresql_ext_install_contrib: yes
postgresql_pg_hba_passwd_hosts: {{ groups[''nodes'']|map(''extract'', hostvars, [''ansible_eth1'',''ipv4'', ''address'']) |list }}
...
No incluye el desafío (anexo /32
). Pero también debería ser posible de alguna manera con los filtros jinja2.
Reqiures versión ansible> = 2.1
en el libro de jugadas:
vars:
- arrayname:
- name: itemname
value1: itemvalue1
value2: itemvalue2
- name: otheritem
value1: itemvalue3
value2: itemvalue4
en plantilla: (ejemplo es de tipo archivo ini, con secciones, claves y valores):
{% for item in arrayname %}
[{{ item.name }}]
key1 = {{ item.value1 }}
key2 = {{ item.value2 }}
{% endfor %}
Esto debería renderizar la plantilla como:
[itemname]
key1 = itemvalue1
key2 = itemvalue2
[otheritem]
key1 = itemvalue3
key2 = itemvalue4