with_items playbook example commands ansible ansible-playbook

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