group_vars und host_varsIn Ansible können Variablen auf verschiedenen Ebenen und durch unterschiedliche Mechanismen definiert werden, um flexible und wiederverwendbare Konfigurationen zu schaffen. Das Verständnis der Variablenauflösung und -priorisierung ist entscheidend für die professionelle Automatisierung.
Globale Variablen gelten für alle Hosts in einem Inventory und werden
primär in group_vars/all.yml definiert. Diese Datei dient
als Basis-Konfiguration, die durch spezifischere Variablen überschrieben
werden kann.
Beispiel für globale Variablen:
# Datei: group_vars/all.yml
ntp_server: ntp.example.com
timezone: UTC
log_level: info
ansible_ssh_common_args: '-o StrictHostKeyChecking=no'Gruppenvariablen werden für definierte Host-Gruppen angewendet und überschreiben globale Variablen. Sie ermöglichen die Konfiguration von Umgebungen oder Rollen.
Beispiel für gruppenspezifische Variablen:
# Datei: group_vars/webservers.yml
http_port: 80
https_port: 443
max_clients: 200
ssl_certificate_path: /etc/ssl/certs/web.crt
# Datei: group_vars/dbservers.yml
db_port: 3306
max_connections: 100
innodb_buffer_pool_size: "1G"Host-Variablen haben die höchste Priorität unter den inventory-basierten Variablen und ermöglichen individuelle Konfigurationen für einzelne Hosts.
Beispiel für host-spezifische Variablen:
# Datei: host_vars/web1.example.com.yml
ansible_host: 192.168.1.10
ansible_user: admin
ansible_ssh_private_key_file: ~/.ssh/web1_key
max_clients: 500 # Überschreibt GruppenvariableAnsible verwendet eine komplexe Hierarchie zur Variablenauflösung. Die folgende Tabelle zeigt die wichtigsten Ebenen in absteigender Priorität:
| Priorität | Quelle | Beschreibung | Anwendungsfall |
|---|---|---|---|
| 1 | Extra Vars (-e) |
Kommandozeilen-Parameter | Überschreibung zur Laufzeit |
| 2 | Task Vars | Variablen innerhalb von Tasks | Task-spezifische Werte |
| 3 | Block Vars | Variablen in Block-Strukturen | Block-spezifische Konfiguration |
| 4 | Role and Include Vars | vars/main.yml in Rollen |
Rollen-Konfiguration |
| 5 | Play Vars | vars: Sektion im Playbook |
Playbook-spezifische Werte |
| 6 | host_vars |
Host-spezifische Dateien | Individuelle Host-Konfiguration |
| 7 | group_vars |
Gruppen-spezifische Dateien | Gruppenbasierte Konfiguration |
| 8 | group_vars/all |
Globale Inventory-Variablen | Basis-Konfiguration |
| 9 | Playbook group_vars |
Im Playbook-Verzeichnis | Playbook-lokale Gruppenvariablen |
| 10 | Inventory group_vars |
Im Inventory-Verzeichnis | Inventory-spezifische Gruppenvariablen |
| 11 | Inventory Vars | Direkt im Inventory definiert | Legacy-Methode |
| 12 | Role Defaults | defaults/main.yml in Rollen |
Standard-Rollenwerte |
Wichtiger Hinweis: set_facts-Module
können zur Laufzeit Variablen definieren, die host_vars überschreiben
können, je nach Ausführungskontext.
Beispiel zur Prioritätendemonstration:
# group_vars/webservers.yml
http_port: 80
# host_vars/web1.example.com.yml
http_port: 8080
# Playbook mit extra vars
# ansible-playbook -e "http_port=9090" site.yml
# Resultat: web1.example.com verwendet Port 9090Ansible sucht group_vars und host_vars in
mehreren Locations:
Erweiterte Verzeichnisstruktur:
project/
├── inventories/
│ ├── production/
│ │ ├── hosts
│ │ ├── group_vars/
│ │ │ ├── all/
│ │ │ │ ├── main.yml
│ │ │ │ └── vault.yml
│ │ │ ├── webservers.yml
│ │ │ └── dbservers/
│ │ │ ├── main.yml
│ │ │ └── database.yml
│ │ └── host_vars/
│ │ └── web1.example.com/
│ │ ├── main.yml
│ │ ├── networking.yml
│ │ └── vault.yml
│ └── staging/
│ └── [ähnliche Struktur]
├── playbooks/
│ ├── group_vars/ # Playbook-lokale Variablen
│ └── host_vars/
└── roles/
└── nginx/
├── vars/main.yml # Rollen-Variablen
└── defaults/main.yml # Rollen-Defaults
Für komplexe Konfigurationen können Variablen in Verzeichnissen mit
main.yml organisiert werden:
# host_vars/web1.example.com/main.yml
ansible_host: 192.168.1.10
# host_vars/web1.example.com/networking.yml
firewall_rules:
- port: 80
protocol: tcp
- port: 443
protocol: tcp
# host_vars/web1.example.com/vault.yml (verschlüsselt)
db_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
66396439396439643964396439643964...vars_files---
- hosts: webservers
vars_files:
- "vars/common.yml"
- "vars/{{ env }}.yml"
- "vars/secrets/{{ inventory_hostname }}.yml"
tasks:
- name: Configure application
template:
src: app.conf.j2
dest: /etc/app/app.confinclude_vars- name: Load OS-specific variables
include_vars: "{{ item }}"
with_first_found:
- "vars/{{ ansible_distribution }}-{{ ansible_distribution_version }}.yml"
- "vars/{{ ansible_distribution }}.yml"
- "vars/{{ ansible_os_family }}.yml"
- "vars/default.yml"
- name: Load environment-specific secrets
include_vars:
file: "vault/{{ env }}_secrets.yml"
when: env is definedset_fact- name: Calculate derived configuration
set_fact:
nginx_worker_processes: "{{ ansible_processor_vcpus }}"
max_client_body_size: "{{ (ansible_memtotal_mb * 0.1) | int }}m"
- name: Merge configuration dictionaries
set_fact:
app_config: "{{ default_config | combine(env_config, recursive=True) }}"Inventory-Struktur anzeigen:
# Vollständige Inventory-Struktur mit allen Variablen
ansible-inventory -i inventories/production/ --list
# Spezifische Host-Variablen anzeigen
ansible-inventory -i inventories/production/ --host web1.example.com
# Gruppenvariablen einer spezifischen Gruppe
ansible-inventory -i inventories/production/ --list | jq '.webservers.vars'
# YAML-Format für bessere Lesbarkeit
ansible-inventory -i inventories/production/ --list --yamlAd-hoc Variable Debugging:
# Alle Facts und Variablen eines Hosts
ansible web1.example.com -i inventories/production/ -m setup
# Spezifische Variablen testen
ansible web1.example.com -i inventories/production/ -m debug -a "var=http_port"
# Variable Precedence testen
ansible-playbook -i inventories/production/ debug.yml --limit web1.example.com -vDebug-Playbook Beispiel:
---
- hosts: all
gather_facts: no
tasks:
- name: Show variable precedence
debug:
msg: |
Host: {{ inventory_hostname }}
HTTP Port: {{ http_port | default('not defined') }}
All variables: {{ hostvars[inventory_hostname] }}
- name: Show group membership
debug:
var: group_names
- name: Show variable source analysis
debug:
msg: "Variable 'http_port' resolved to: {{ http_port }}"
when: http_port is definedEnvironment-basierte Trennung:
inventories/
├── production/
│ ├── group_vars/all/
│ │ ├── main.yml # Basis-Konfiguration
│ │ ├── monitoring.yml # Monitoring-spezifisch
│ │ └── vault.yml # Verschlüsselte Werte
├── staging/
└── development/
Namenskonventionen:
# Präfix-basierte Namensgebung
app_name: myapp
app_version: "1.2.3"
app_port: 8080
app_config_dir: "/etc/{{ app_name }}"
# Umgebungsspezifische Präfixe
prod_db_host: db.prod.example.com
staging_db_host: db.staging.example.com
# Rollenspezifische Gruppierung
nginx_worker_processes: 4
nginx_worker_connections: 1024
nginx_keepalive_timeout: 65Vault-Integration:
# Vault-Dateien erstellen
ansible-vault create group_vars/all/vault.yml
ansible-vault create host_vars/web1.example.com/vault.yml
# Vault-Password-File nutzen
echo "vault_password" > .vault_pass
chmod 600 .vault_pass
export ANSIBLE_VAULT_PASSWORD_FILE=.vault_passSichere Variable-Referenzierung:
# group_vars/all/vault.yml (verschlüsselt)
vault_db_password: "secret123"
vault_api_key: "api_key_here"
# group_vars/all/main.yml (unverschlüsselt)
db_password: "{{ vault_db_password }}"
api_key: "{{ vault_api_key }}"Variable-Validierung:
- name: Validate required variables
assert:
that:
- app_name is defined
- app_version is defined
- app_port is number
- app_port > 1024
fail_msg: "Required application variables not properly defined"
- name: Validate environment consistency
assert:
that:
- env in ['production', 'staging', 'development']
fail_msg: "Environment '{{ env }}' is not valid"Test-Playbook für Variable-Konsistenz:
---
- hosts: all
gather_facts: no
tasks:
- name: Collect all host variables
set_fact:
all_host_vars: "{{ hostvars[inventory_hostname] }}"
- name: Generate variable report
template:
src: variable_report.j2
dest: "reports/{{ inventory_hostname }}_variables.yml"
delegate_to: localhost
- name: Validate critical variables exist
fail:
msg: "Critical variable {{ item }} is not defined for {{ inventory_hostname }}"
when: hostvars[inventory_hostname][item] is not defined
loop:
- ansible_host
- app_name
- env