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
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 .
Ce sujet est compliqué et il y a deux réponses différentes selon ce que vous voulez.
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}}"
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».
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.
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
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
.