Ich habe ein Playbook, das verschiedene Rollen auf verschiedenen Hosts ausführt. Ist es möglich, eine Variable von einer Rolle, die auf einem Host ausgeführt wird, an eine andere Rolle auf einem anderen Host zu übergeben, der innerhalb des gleichen Playbook-Laufs läuft? Oder eine Problemumgehung?
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
Die Aufgabe in Rolle1, die die Variable db
setzt, sieht folgendermaßen aus:
- Shell: cd /ACE/conf && grep ^db.url local1.properties | awk -F/ '{print $4}' | awk -F? '{print $1}'
register: db
UPDATE: Auf dem ersten Host sind die Werte dynamisch, es ist wie eine Konfigurationsdatei, die immer aktualisiert wird. Nachdem ich die Werte in Variablen auf Host1 mit der Rolle1 gespeichert habe, gehe ich zum Host2, starte die Rolle2 und erledige diese Werte mit den von Host1 gespeicherten Variablen.
Ich habe mit hostvars versucht:
{{ hostvars.LBL.db.stdout }}
{{ hostvars['LBL']['db'] }}
{{ hostvars['LBL']['db']['stdout'] }}
und ich bekomme Fehler:
in get_variables raise Exception("Host not found: %s" % hostname) Exception: Host not found: LBL
LBL ist in Hosts vorhanden, da ich die erste Rolle auf ihr ausführe
Ich setze eine Variable für einen Host und möchte, dass diese Variable für den anderen Host verfügbar ist. All dies in einem einzigen Spielbuch. Kann es gemacht werden
hostvars funktioniert nicht so:
---
- 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'] }}"
error:
fatal: [10.104.148.138] => Host not found: LBL
/ etc/ansible/hosts
[[email protected] ansible]# cat /etc/ansible/hosts
[LBL]
10.104.148.136
[LM]
10.104.148.138
Das Problem liegt in Ihrem Inventar.
Diese Nachricht:
fatal: [10.104.148.138] => Host not found: LBL
ist weil LBL
eine Gruppe und kein Host ist. Die Gruppe LBL
enthält einen Host: 10.104.148.136
Führen Sie einen der folgenden Schritte aus:
1. Ändern Sie Ihren Bestand (/etc/ansible/hosts
) in:
LBL ansible_ssh_Host=10.104.148.136
LM ansible_ssh_Host=10.104.148.138
2. oder wenn Sie wirklich wissen, was Sie tun, und LBL
eine Gruppe ist und Sie dies beibehalten möchten, dann greifen Sie auf die Variable zu:
{{ hostvars['10.104.148.136']['db']['stdout'] }}
Wieder ist LBL eine Gruppe und kein Host. Mehr Info .
Dieses Thema ist kompliziert und es gibt zwei verschiedene Antworten, je nachdem, was Sie möchten.
Beispiel:
---
- hosts: Host1
- roles:
- role1
- role2
Ziel: Sie möchten auf einige Variable von Rolle1 in Rolle2 zugreifen.
Set_fact-Modul verwenden.
Innere Rolle1:
name: save precious value
set_fact:
pantsu: shiroi
Inside Rolle2:
name: Nozoki...
debug: msg="Color is {{pantsu}}"
Beispiel:
[group_foo]
Host1
Host2
[group_bar]
Host3
Host4
group_vars/group_foo
important_value=bla-bla-ba
Ziel: Sie möchten es im Playbook für Gruppe2 verwenden.
Das ist viel schwieriger.
Innerhalb von group_vars/group_bar
other_var: '{{hostvars[groups["group_foo"][0]].important_value}}'
Sie können außer '0' auch andere Indizes verwenden.
Hier ist meine Lösung. Meine Aufgabe bestand darin, Daten zwischen zwei Servern zu synchronisieren, und ich wollte die Servernamen wie folgt weitergeben: ansible-playbook sync.yaml -e "source = Host1 destination = Host2"
Hier ist das Hauptbuch:
---
- name: get_sync_facts
hosts: "{{ source }}"
roles:
- set_sync_facts
- name: sync
hosts: "{{ destination }}"
roles:
- get_sync_facts
- sync
Hier ist die Rolle 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'
(Ich habe einige davon aus Aufgaben und andere von Host-Vars abgeleitet, aber Sie verstehen den Punkt)
Und hier ist die Rolle 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'] }}
Sie könnten darauf verzichten und nur Hostvars direkt in Ihren Spielen referenzieren, dies schien jedoch einfacher zu verwalten, da es direkt der Rolle set_sync_facts entspricht.
es ist ein ziemlich altes Thema, aber vielleicht wird es jemandem helfen. Ich habe sed verwendet, um den Hostnamen basierend auf "target" in zusätzlichen Parametern zu erhalten.
Um diese "Zielgruppe" zu verwenden, darf nur 1 Hostname enthalten.
Meine Inventar-Hosts:
[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
Aufruf mit: ansible-playbook ./upgrade-packages.yml -e "target=machine1" -v
Ich hatte ein ähnliches Setup, bei dem es drei Hosts h1, h2, h3 gibt, und auf jedem davon wollte ich eine Tatsache { "important_fact": "foo" }
(bzw. bar und baz) definieren.
Um eine Liste mit allen verschiedenen wichtigen_Fakten auf allen Hosts zu erhalten, können Sie dies wie folgt tun:
- set_fact:
important_facts_list: "{{ hostvars | json('*.important_fact') }}"
run_once: yes
delegate_to: h1
important_facts_list
enthält [ 'foo', 'bar', 'baz' ]
, und Sie können sie jetzt mit with_items
durchlaufen.