Archiv nach Monaten: Juni 2018

[ansible] Mit dictonaries arbeiten

Wichtig: getestet mit Ansible 2.4.2.0

Wenn man in Ansible Variablen deklarieren möchte, kann es der Übersichtlichkeit halber interessant sein, diese in Dictionaries anzulegen. Beispielsweise wenn man mit mehreren Umgebungen arbeitet  – Test/vProd/Prod – und Fachanwendungen auf Server „taggen“ möchte. Sprich eine List wo steht auf welchen Server die einzelnen Fachanwendungen installiert sind.

Deklaration

Ort der „vars“-Datei

wir deklarieren eine neue Variablen-Datei
<ansible-root>/vars/main.yml
oder mit Rollen
<ansible-root>/roles/<role-name>/vars/main.yml

Alternativ:

## include <meinVarName> 2 host vars (host tagging)
- name: include <meinVarName> vars
  include_vars: "vars/<meinVarName>.yml"

Inhalt der Datei

anwendung_a:
&nbsp;- port: 8563
   hosts:
   - host_a
   - host_b
   - host_c

anwendung_b:
&nbsp;- port: 8565
   hosts:
   - host_a
   - host_c
   - host_d

Auf diese Weise kann man ein „Host-Tagging“ bewerkstelligen.
Sprich man deklariert, auf welchen Servern eine bestimmte Anwendung installiert ist, und führt hier entsprechende Task’s aus.

Anwendung

Einen Parameter abfragen

- shell: echo "{{ item.port }}" > /tmp/test
  with_items:
  - "{{ anwendung_a }}"

Ergebnis:

cat /tmp/test
8563

Parameter und Host abfragen

Jetzt wird es ein wenig komplizierter, wir wollen einen Parameter und einen bestimmten Server abfragen.
Achtung! Eignet sich nur wenn man einen bestimmten Server sucht! Nicht für eine Gruppe von Servern.

- shell: echo "{{ item.hosts | select("match", "dbserver01") | first }} {{ item.port }}" > /tmp/test 
  with_items: 
  - "{{ anwendung_a }}"

Tipp: Variablen werden ohne Klammern deklariert

- vars:
  - mysearchstring: dbserver0

- shell: echo "{{ item.hosts | select("match", mysearchstring.*) | first }} {{ item.port }}" > /tmp/test 
  with_items: 
  - "{{ anwendung_a }}"

Alle hosts ausgeben

- shell: echo "{{ item.1 }}" >> /tmp/test
  with_subelements:
  - "{{ anwendung_a }}"
  - hosts

Ergebnis:

cat /tmp/test
host_a 
host_b
host_c

 

Loop over dictonary

Um mit allen Werten zu arbeiten bietet sich folgende Vorgehensweise an:

- shell: echo "{{ item.1 }} {{ item.0.port }}" >> /tmp/test
  with_subelements:
  - "{{ anwendung_a }}"
  - hosts

Ergebnis:

cat /tmp/test
host_a 8563 
host_b 8563
host_c 8563

 

Task auf host „taggen“

Auf diese Weise kann man deklarieren, dass ein Task auf dem aktuellem Server nur ausgeführt wird, wenn er in einer entsprechenden Liste deklariert wurde.

Oder auf Klardeutsch:
Wenn host_a NICHT in den hosts von anwendung_a aufgelistet ist, würde der Task nicht auf diesem Host ausgeführt werden.

- include_tasks: install_webserver.yml
  with_subelements:
  - "{{ anwendung_a }}"
  - hosts
  when: 'inventory_hostname in item'

Zum nachlesen:

Hier wird das gut erklärt finde ich:
https://stackoverflow.com/questions/31566568/double-loop-ansible