2016-11-15 6 views
1

Die ansible Best Practices Dokumentation recommends auf Vorräte trennen:Wie teilen Sie Group_vars zwischen verschiedenen Inventaren in Ansible?

 
inventories/ 
    production/ 
     hosts.ini   # inventory file for production servers 
     group_vars/ 
     group1   # here we assign variables to particular groups 
     group2   # "" 
     host_vars/ 
     hostname1  # if systems need specific variables, put them here 
     hostname2  # "" 

    staging/ 
     hosts.ini   # inventory file for staging environment 
     group_vars/ 
     group1   # here we assign variables to particular groups 
     group2   # "" 
     host_vars/ 
     stagehost1  # if systems need specific variables, put them here 
     stagehost2  # "" 

Meine Inszenierung und Produktionsumgebungen sind in der gleichen Art und Weise strukturiert. Ich habe in beiden Umgebungen die gleichen Gruppen. Und es stellt sich heraus, dass ich auch die gleichen group_vars für die gleichen Gruppen habe. Das bedeutet Redundanz, die ich gerne auslöschen möchte.

Gibt es eine Möglichkeit, einige group_vars zwischen verschiedenen Inventaren zu teilen?

Als Work-Around habe ich begonnen, shared group_vars in die Rollen zu setzen.

my_var: 
    my_group: 
    - { var1: 1, var2: 2 } 

Dies macht es möglich, einige Vars iterieren durch die Gruppen von einem Host mit dem definierten var sich schneid:

with_items: "{{group_names | intersect(my_var.keys())}}" 

Aber das ist ein bisschen kompliziert zu verstehen, und ich denke, Rollen nicht wissen sollten irgendetwas über Gruppen.

Ich möchte die meisten Inventare trennen, teile aber einige der group_vars auf eine leicht verständliche Weise. Ist es möglich, globale group_vars mit inventarspezifischen group_vars zusammenzuführen?

Antwort

0

Ich kratzte die Idee, Ansible's Empfehlung zu folgen. Jetzt, ein Jahr später, bin ich davon überzeugt, dass die Empfehlung von Ansible für meine Anforderungen nicht geeignet ist. Stattdessen denke ich, dass es wichtig ist, so viel wie möglich zwischen den verschiedenen Phasen zu teilen.

Jetzt habe ich alle Vorräte im selben Verzeichnis:

production.ini 
reference.ini 

Und ich dafür sorgen, dass jedes Inventar eine Gruppe mit dem Namen der Bühne einschließlich allen Hosts definiert.

Die Datei production.ini hat die Gruppe production:

[production:children] 
all_production_hosts 

Und die Datei reference.ini die Gruppe reference hat:

[reference:children] 
all_reference_hosts 

Ich habe nur ein group_vars Verzeichnis, in dem ich eine Datei für jede Inszenierung definieren Gruppe:

group_vars/production.yml 
group_vars/reference.yml 

Und jede Datei definiert eine stage Variable. Die Datei production.yml definiert dies:

--- 
stage: production 

Und die Datei reference.yml legt fest, dass:

--- 
stage: reference 

Dies macht es möglich, alles andere zwischen Produktion und Bezug zu teilen. Aber die Gastgeber sind komplett anders. Durch die Verwendung führt das rechte Inventar des Textbuch entweder auf der Produktion oder auf Referenz Hosts:

ansible-playbook -i production.ini site.yml 
ansible-playbook -i reference.ini site.yml 

Wenn es notwendig ist, für die site.yml oder die Rollen etwas anders verhalten in der Produktion und die Referenzumgebung, können sie Bedingungen nutzen die Verwendung von stage Variable. Aber ich versuche sogar, das zu vermeiden. Weil es besser ist, alle Unterschiede in äquivalente Definitionen in den Staging-Dateien production.yml und reference.yml zu verschieben.

Zum Beispiel, wenn die group_vars/all.yml einige Benutzer definiert:

users: 
    - alice 
    - bob 
    - mallory 

Und ich mag die Benutzer in beiden Umgebungen schaffen, aber ich will mallory aus der Produktionsumgebung auszuschließen, kann ich eine neue Gruppe definiert aufgerufen effective_users. Im reference.yml ist es identisch mit der users Liste:

effective_users: >- 
    {{ users }} 

Aber in den production.yml kann ich ausschließen mallory:

effective_users: >- 
    {{ users | difference(['mallory']) }} 

Das Textbuch oder die Rollen müssen nicht zwischen den beiden Stufen zu unterscheiden, sie kann einfach die Gruppe effective_users verwenden. Die Gruppe enthält automatisch die richtige Benutzerliste, indem Sie einfach das Inventar auswählen.

2

Sie können group_vars auch in das Playbook-Verzeichnis einfügen. More info.

Ansible wird sie für alle Bestände abholen.

+0

Aber das funktioniert nur für Playbooks. Ad-hoc-Befehle schlagen fehl. Gibt es eine Möglichkeit, die Ad-hoc-Befehlsausführung so anzupassen, dass globale group_vars gelesen werden? – ceving

+0

Ein anderes Problem scheint zu sein, dass ich 'hash_behaviour = merge' einstellen muss, wenn ich eine Variable aus verschiedenen Gruppen sammeln möchte. Und wie wäre es mit Array-Werten in Hashes? – ceving

+0

Dies funktioniert nicht mit Ad-hoc. Listen können nicht automatisch zusammengeführt werden, Sie müssen dafür einige manuelle Aufgaben verwenden. –

2

Die einfache Option hier (und was wir tun) ist einfach Symlink generische Gruppe vars Dateien um.

Zum Beispiel haben wir vielleicht eine generische Rolle für etwas wie NGINX und dann ein paar konkrete Anwendungsfälle für diese Rolle. In diesem Fall erstellen wir eine Gruppen-VARS-Datei, die die NGINX-Rolle für jeden konkreten Anwendungsfall verwendet, und verknüpfen dann diese Gruppen-VARS-Dateien einfach mit den entsprechenden Ordnern.

Unser Projektordnerstruktur dann könnte wie folgt aussehen (stark vereinfacht):

. 
├── inventories 
│   ├── bar-dev 
│   │   ├── group_vars 
│   │   │   ├── bar.yml -> ../../shared/bar.yml 
│   │   │   └── dev.yml -> ../../shared/dev.yml 
│   │   └── inventory 
│   ├── bar-prod 
│   │   ├── group_vars 
│   │   │   ├── bar.yml -> ../../shared/bar.yml 
│   │   │   └── prod.yml -> ../../shared/prod.yml 
│   │   └── inventory 
│   ├── bar-test 
│   │   ├── group_vars 
│   │   │   ├── bar.yml -> ../../shared/bar.yml 
│   │   │   └── test.yml -> ../../shared/test.yml 
│   │   └── inventory 
│   ├── foo-dev 
│   │   ├── group_vars 
│   │   │   ├── dev.yml -> ../../shared/dev.yml 
│   │   │   └── foo.yml -> ../../shared/foo.yml 
│   │   └── inventory 
│   ├── foo-prod 
│   │   ├── group_vars 
│   │   │   ├── foo.yml -> ../../shared/foo.yml 
│   │   │   └── prod.yml -> ../../shared/prod.yml 
│   │   └── inventory 
│   ├── foo-test 
│   │   ├── group_vars 
│   │   │   ├── foo.yml -> ../../shared/foo.yml 
│   │   │   └── test.yml -> ../../shared/test.yml 
│   │   └── inventory 
│   └── shared 
│    ├── bar.yml 
│    ├── dev.yml 
│    ├── foo.yml 
│    ├── prod.yml 
│    └── test.yml 
└── roles 
    └── nginx 
     ├── defaults 
     │   └── main.yml 
     ├── meta 
     │   └── main.yml 
     ├── tasks 
     │   └── main.yml 
     └── templates 
      └── main.yml 

Jetzt können unsere Inventardateien haben die Gastgeber nutzen diese gemeinsame Gruppen Vars einfach durch die Gastgeber in den richtigen Gruppen setzen.

+1

Schön zu sehen, dass ich nicht der Einzige mit diesem Problem bin. – ceving

+0

BTW: Ich muss Fossil SCM verwenden und Fossil's Standard ist Symlinks zu folgen. Dies geschieht, um Windows-Probleme durch Unix-Probleme zu vermeiden. Die Fossilen denken wahrscheinlich, dass Unix-Probleme einfacher zu lösen sind als Windows-Probleme. Ich bin mir also nicht sicher, ob die symbolischen Links für mich eine Option sind. – ceving

Verwandte Themen