web-dev-qa-db-fra.com

Comment assigner un tableau à une variable dans un Ansible-Playbook

Dans un livre de jeu, j'ai obtenu le code suivant:

---
- hosts: db
  vars:
    postgresql_ext_install_contrib: yes
    postgresql_pg_hba_passwd_hosts: ['10.129.181.241/32']
...

Je voudrais remplacer la valeur de postgresql_pg_hba_passwd_hosts par tous mes ips privés de serveurs Web. Je comprends que je peux obtenir les valeurs telles que this dans un modèle:

{% for Host in groups['web'] %}
   {{ hostvars[Host]['ansible_eth1']['ipv4']['address'] }}
{% endfor %}

Quel est le moyen le plus simple/le plus simple de affecter le résultat de cette boucle à une variable dans un livre de jeu? Ou existe-t-il un meilleur moyen de collecter ces informations? Devrais-je mettre cette boucle dans un modèle?

Défi supplémentaire: je devrais ajouter /32 à chaque entrée.

21
dabai

Vous pouvez assigner une liste à une variable avec set_fact et ansible filter plugin .

Placez le plugin de filtre personnalisé dans le répertoire filter_plugins comme suit:

(ansible top directory)
site.yml
hosts
filter_plugins/
    to_group_vars.py

to_group_vars.py convertit hostvars en liste sélectionnée par groupe.

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}

Utilisez comme ceci:

---
- 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
24
Yuichiro

en playbook:

vars:
     - arrayname:
        - name: itemname
          value1: itemvalue1
          value2: itemvalue2
        - name: otheritem
          value1: itemvalue3
          value2: itemvalue4

dans template: (exemple: fichier de type ini, avec sections, clés et valeurs):

{% for item in arrayname %}
[{{ item.name }}]
key1 = {{ item.value1 }}
key2 = {{ item.value2 }}
{% endfor %}

Cela devrait rendre le modèle comme:

[itemname]
key1 = itemvalue1
key2 = itemvalue2
[otheritem]
key1 = itemvalue3
key2 = itemvalue4
9
anneb

Les variables peuvent être représentées sous forme de structures YAML standard afin que vous puissiez affecter une valeur de liste à une clé telle que

---
- hosts: db
  vars:
    postgresql_ext_install_contrib: yes
    postgresql_pg_hba_passwd_hosts:
      - '10.129.181.241/32'
      - '1.2.3.0/8'
6
tima

Vous pouvez utiliser les filtres jinja2:

{{ groups['nodes']|map('extract', hostvars, ['ansible_eth1','ipv4', 'address']) |list }}

retournera une liste d'adresses IP. c'est à dire.

---
- hosts: db
  vars:
    postgresql_ext_install_contrib: yes
    postgresql_pg_hba_passwd_hosts: {{ groups['nodes']|map('extract', hostvars, ['ansible_eth1','ipv4', 'address']) |list }}
...

N'inclut pas le défi (en ajoutant /32). Mais cela devrait aussi être possible avec les filtres jinja2.

Requiert version ansible> = 2.1

4
turkenh

Pour ajouter «/ 32» à l'adresse, vous pouvez utiliser le filtre Ansible ipaddr ( conversion en notation CIDR ).

{{ ip_addresses|ipaddr('Host') }}
0
arpe