2014-07-17 17 views
17

In un playbook ho ottenuto il seguente codice:Come assegnare un array ad una variabile in un Ansible-Playbook

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

Vorrei sostituire il valore di postgresql_pg_hba_passwd_hosts con tutti i miei server web ips privati ​​ . Capisco che posso ottenere i valori come this in un modello:

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

Qual è il miglior/modo più semplice più semplice per assegnare il risultato di questo ciclo per una variabile in un playbook? O c'è un modo migliore per raccogliere queste informazioni in primo luogo? Dovrei inserire questo loop in un modello?

Ulteriore sfida: dovrei aggiungere /32 a ogni voce.

+0

Questo è esattamente il mio caso –

risposta

21

È possibile assegnare un elenco di variabili da set_fact e ansible filter plugin.

Put personalizzato filtro plugin per filter_plugins directory come questo:

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

to_group_vars.py convertire hostvars nella lista che ha selezionato dal gruppo.

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} 

Usa come questo:

--- 
- 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 
+0

L'esempio funziona molto bene. Grazie! Ora l'unico passo che mi manca è come posso assegnare il valore di 'web_ips' a' postgresql_pg_hba_passwd_hosts' come nella domanda? – dabai

+0

Ottima risposta! È un peccato non poter premere 'upvote' più di una volta –

+1

In Ansible 2.0, HostVars può essere trovato in ansible.vars.hostvars. – johncip

2

Le variabili possono essere rappresentati come strutture YAML standard, in modo da poter assegnare un valore lista ad un tasto in questo modo:

--- 
- hosts: db 
    vars: 
    postgresql_ext_install_contrib: yes 
    postgresql_pg_hba_passwd_hosts: 
     - '10.129.181.241/32' 
     - '1.2.3.0/8' 
+1

Si può fornire una soluzione completa, vale a dire come faccio a ottenere i valori in modo dinamico dai fatti raccolti? – dabai

+0

KISS, funziona perfettamente e può essere usato come tale {{% per ntpserver nel server ntpservers%} {{ntpserver}} iburst {% endfor%} ' – elge

+0

o se è necessario solo il primo elemento dell'array,' { {ntpservers [0]}} ' – elge

6

nel playbook:

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

in Template: (esempio è di tipo di file ini, con sezioni, chiavi e valori):

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

Questo dovrebbe rendere il templ Abbiamo mangiato come:

[itemname] 
key1 = itemvalue1 
key2 = itemvalue2 
[otheritem] 
key1 = itemvalue3 
key2 = itemvalue4 
3

È possibile utilizzare filtri Jinja2:

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

restituirà un elenco di indirizzi IP. vale a dire

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

non comprende la sfida (aggiungendo /32). Ma dovrebbe anche essere possibile in qualche modo con i filtri jinja2.

Reqiures versione ansible> = 2.1

+1

questo è così semplice ora grazie :) –

0

Per aggiungere '/ 32' per l'indirizzo, è possibile utilizzare l'Ansible ipaddr filtro (converting to CIDR notation).

{{ ip_addresses|ipaddr('host') }} 
Problemi correlati