web-dev-qa-db-fra.com

Passer des variables Ansible d'un rôle (s'exécutant sur un hôte) à un autre rôle s'exécutant sur un autre hôte du même livre de lecture

J'ai un livre de lecture qui exécute différents rôles sur différents hôtes. Est-il possible de passer une variable d'un rôle s'exécutant sur un hôte à un autre rôle sur un autre hôte exécuté dans la même exécution de livre de lecture? Ou une solution de contournement?

playbook
   Host1
     role1
       here I get some variables: var1 var2 ...etc
   Host2
     role2
       here I need to use var1 var2 ... etc from the above Host/role

La tâche dans role1 qui définit la variable db se présente comme suit:

- Shell: cd /ACE/conf && grep ^db.url local1.properties | awk -F/ '{print $4}' | awk -F? '{print $1}'
  register: db

UPDATE: sur le premier hôte, les valeurs sont dynamiques, c'est comme un fichier de configuration qui est toujours mis à jour. Après avoir stocké les valeurs dans des variables sur Host1 avec le rôle1, je passe ensuite à l'hôte2, lance le rôle2 et crée des éléments avec ces valeurs à partir de variables stockées par Host1. 

J'ai essayé avec hostvars:

{{ hostvars.LBL.db.stdout }}
{{ hostvars['LBL']['db'] }}
{{ hostvars['LBL']['db']['stdout'] }}

et j'obtiens une erreur:

in get_variables raise Exception("Host not found: %s" % hostname) Exception: Host not found: LBL

LBL existe dans les hôtes car je lance le premier rôle

Je mets une variable sur un hôte et je veux que cette variable soit disponible pour l'autre hôte. Tout cela dans un seul livre de jeu. Cela peut-il être fait?

hostvars ne fonctionne pas en l'utilisant comme ceci:

---   
- name: test hostvars Host1
  hosts: LBL
  tasks:
    - command: "ls /bin"
        register: ls_out

- name: test hostvars Host2
  hosts: LM
  tasks:
    - debug:
        var: "{{ hostvars['LBL']['ls_out']['stdout'] }}"

erreur:

fatal: [10.104.148.138] => Host not found: LBL

/ etc/ansible/hosts

[root@NS1 ansible]# cat /etc/ansible/hosts
[LBL]
10.104.148.136
[LM]
10.104.148.138
7
ady8531

Le problème est dans votre inventaire.

Ce message: 

fatal: [10.104.148.138] => Host not found: LBL

est parce que LBL est un groupe et non un hôte. Le groupe LBL contient un hôte: 10.104.148.136

Effectuez l'une des actions suivantes:

1. Modifiez votre inventaire (/etc/ansible/hosts) en:

LBL ansible_ssh_Host=10.104.148.136
LM ansible_ssh_Host=10.104.148.138

2. ou si vous savez vraiment ce que vous faites et que LBL est un groupe et que vous voulez le conserver ainsi, accédez à la variable avec:

{{ hostvars['10.104.148.136']['db']['stdout'] }}

Encore une fois, LBL est un groupe et non un hôte. Plus d'informations .

6
Kashyap

Ce sujet est compliqué et il y a deux réponses différentes selon ce que vous voulez.

Variable d'accès d'un livre de jeu à un autre pour le même hôte

Exemple:

---
- hosts: Host1
- roles:
    - role1
    - role2

Objectif: Vous souhaitez accéder à une variable de role1 dans role2.

Utilisez le module set_fact.

Inside role1:

name: save precious value
set_fact: 
  pantsu: shiroi

Inside role2:

name: Nozoki...
debug: msg="Color is {{pantsu}}"

Accès aux variables statiques d’un hôte (ou groupe) à un autre

Exemple:

[group_foo]
Host1
Host2
[group_bar]
Host3
Host4

group_vars/group_foo

important_value=bla-bla-ba

Objectif: vous souhaitez l’utiliser dans playbook pour group2.

C'est une chose beaucoup plus délicate à faire. 

Inside group_vars/group_bar

other_var: '{{hostvars[groups["group_foo"][0]].important_value}}'

Vous pouvez utiliser d'autres index que «0».

11
George Shuklin

Voici ma solution. Ma tâche était de synchroniser les données entre deux serveurs et je voulais transmettre les noms de serveur comme suit: ansible-playbook sync.yaml -e "source = Host1 destination = Host2"

Voici le livre de jeu principal:

---

- name: get_sync_facts
  hosts: "{{ source }}"
  roles:
    - set_sync_facts

- name: sync
  hosts: "{{ destination }}" 
  roles:
    - get_sync_facts
    - sync

Voici le rôle set_sync_facts:

---

- set_fact: src_media_dir='/some/dir/'
- set_fact: src_user='myuser'
- set_fact: src_Host='1.1.1.1'
- set_fact: src_port=12345
- set_fact: src_db_user='dbuser'
- set_fact: src_db_password='something'
- set_fact: src_db_name='some_db'

(J'ai en fait dérivé certaines de ces tâches et d'autres de vars de l'hôte mais vous obtenez le point)

Et voici le rôle get_sync_facts:

---

- set_fact: src_media_dir={{ hostvars[source]['src_media_dir'] }}
- set_fact: src_user={{ hostvars[source]['src_user'] }}
- set_fact: src_Host={{ hostvars[source]['src_Host'] }}
- set_fact: src_port={{ hostvars[source]['src_port'] }}
- set_fact: src_db_user={{ hostvars[source]['src_db_user'] }}
- set_fact: src_db_password={{ hostvars[source]['src_db_password'] }}
- set_fact: src_db_name={{ hostvars[source]['src_db_name'] }}

Vous pouvez vous en passer et simplement référencer hostvars directement dans vos jeux, mais cela semblait plus facile à maintenir car il correspond directement au rôle set_sync_facts. 

2
Andy Baker

c'est un sujet assez ancien, mais peut-être sera-t-il utile à quelqu'un. J'ai utilisé sed pour obtenir le nom d'hôte en fonction de "cible" spécifiée dans des paramètres supplémentaires.

Pour utiliser ce groupe "cible", il ne doit contenir qu'un seul nom d'hôte.

Mes hôtes d'inventaire:

[ansible_local]
localhost

[machine1]
machine1.domain.tld

upgrade_packages.yml

---
- hosts: '{{ target }}'
  Sudo: yes
  tasks:
  - name: check for Debian system
    Shell: /bin/false
    when: ansible_pkg_mgr != "apt"

  - name: full-upgrade all packages
    apt: update_cache=yes upgrade=full
    register: upgrade_result

- hosts: ansible_local
  tasks:
  - name: find out Host from target
    Shell: /bin/sed -n -e '/^\[{{ target }}\]$/,/^\[.*\]$/ { /^\[/d; /^$/d; p; }' {{ inventory_file }}
    register: target_inventory

  - name: Display all facts from target machine (change when to true if needed)
    debug: var=hostvars[target_inventory.stdout]
    when: false

  - name: Display upgrade result on ansible_local node
    debug: var=hostvars[target_inventory.stdout].upgrade_result.msg

Invoquer avec: ansible-playbook ./upgrade-packages.yml -e "target=machine1" -v

1
Quoing

J'ai eu une configuration similaire où il y a trois hôtes h1, h2, h3 et sur chacun d'eux je voulais définir un fait { "important_fact": "foo" } (et bar, et baz, respectivement)

Pour obtenir une liste contenant tous les différents important_facts sur tous les hôtes, procédez comme suit:

- set_fact:
    important_facts_list: "{{ hostvars | json('*.important_fact') }}"
  run_once: yes
  delegate_to: h1

important_facts_list contiendra [ 'foo', 'bar', 'baz' ], et vous pouvez maintenant les parcourir en utilisant with_items.

0
Johannes Meixner