Dieses Problem trat in einem Setup auf, in dem ich mehrere Bereitstellungsumgebungen (Live, Demo, Sandbox) auf demselben physischen Server erstellen musste (hier sind keine virtuellen Maschinen zulässig), und dann ein Skript zum Bereitstellen beliebiger SVN-Repos
Dies erforderte einen Verzeichnisbaum von (optionalen) variablen.yml-Dateien, die übereinander zusammengeführt wurden und keine Ausnahme auslösten, falls eine fehlte
Beginnen Sie, indem Sie das Zusammenführen von Variablen in Ansible aktivieren. Beachten Sie, dass dies nur eine flache Hash-Zusammenführung (1 Ebene tief) und keine vollständig rekursive, tiefe Zusammenführung bewirkt
ansible.cfg
[defaults]
hash_behaviour=merge ;; merge rather than replace dictionaries http://docs.ansible.com/ansible/intro_configuration.html###hash-behaviour
Ansible Verzeichnislayout
/group_vars
└── all.yml
/playbooks
├── boostrap.yml
├── demo.yml
├── live.yml
└── sandbox.yml
/roles/deploy/
├── files
├── tasks
│ ├── includes.yml
│ ├── main.yml
└── vars
├── main.yml
├── project_1.yml
├── project_2.yml
├── demo
│ ├── project_1.yml
│ ├── project_2.yml
│ └── main.yml
├── live
│ ├── project_1.yml
│ ├── project_2.yml
│ └── main.yml
└── sandbox
├── project_1.yml
├── project_2.yml
└── main.yml
rolls / deploy / tasks / includes.yml
Dies ist die Hauptlogik für einen Verzeichnisbaum optionaler Variablendateien.
;; imports in this order:
;; - /roles/deploy/vars/main.yml
;; - /roles/deploy/vars/{{ project_name }}.yml
;; - /roles/deploy/vars/{{ project_name }}/main.yml
;; - /roles/deploy/vars/{{ project_name }}/{{ project_env }}.yml
- include_vars:
dir: 'vars'
files_matching: "{{ item }}"
depth: 1
with_items:
- "main.yml"
- "{{ project_name }}.yml"
- include_vars:
dir: 'vars/{{ env_name }}'
files_matching: "{{ item }}"
depth: 1
with_items:
- "main.yml"
- "{{ project_name }}.yml"
group_vars / all.yml
Konfigurieren Sie Standardvariablen für das Projekt und verschiedene Benutzer und Umgebungen
project_users:
bootstrap:
env: bootstrap
user: ansible
group: ansible
mode: 755
root: /cs/ansible/
home: /cs/ansible/home/ansible/
directories:
- /cs/ansible/
- /cs/ansible/home/
live:
env: live
user: ansible-live
group: ansible
mode: 755
root: /cs/ansible/live/
home: /cs/ansible/home/ansible-live/
demo:
env: demo
user: ansible-demo
group: ansible
mode: 755
root: /cs/ansible/demo/
home: /cs/ansible/home/ansible-demo/
sandbox:
env: sandbox
user: ansible-sandbox
group: ansible
mode: 755
root: /cs/ansible/sandbox/
home: /cs/ansible/home/ansible-sandbox/
project_env: bootstrap
project_user: "{{ ansible_users[project_env] }}" ;; this will be retroactively updated if project_env is redefined later
role / deploy / vars / main.yml
Projektstandards
ansible_project:
node_env: development
node_port: 4200
nginx_port: 4400
role / deploy / vars / project_1.yml
Standardeinstellungen für project_1
ansible_project:
node_port: 4201
nginx_port: 4401
role / deploy / vars / live / main.yml
Standardeinstellungen für die Live-Umgebung überschreiben die Standardeinstellungen des Projekts
ansible_project:
node_env: production
role / deploy / vars / live / project_1.yml
endgültige Überschreibungen für project_1 in der Live-Umgebung
ansible_project:
nginx_port: 80
Spielbücher / demo.yml
Konfigurieren Sie separate Playbooks für jede Umgebung
- hosts: shared_server
remote_user: ansible-demo
vars:
project_env: demo
pre_tasks:
- debug: "msg='{{ facter_gid }}@{{ facter_fqdn }} ({{ server_pseudonym }})'"
- debug: var=project_ssh_user
roles:
- { role: deploy, project_name: project_1 }
WARNUNG: Da sich alle Umgebungen auf einem einzigen Host befinden, müssen alle Playbooks einzeln ausgeführt werden. Andernfalls versucht Ansible, alle Skripte als erster SSH-Anmeldebenutzer auszuführen und verwendet nur die Variablen für den ersten Benutzer. Wenn Sie alle Skripten nacheinander ausführen müssen, verwenden Sie xargs, um sie jeweils als separate Befehle auszuführen.
find ./playbooks/*.yml | xargs -L1 time ansible-playbook