In großen IT-Umgebungen, die Hunderte oder sogar Tausende von Hosts umfassen, ist eine durchdachte und skalierbare Inventarstruktur entscheidend. Eine einfache Liste von Hosts reicht hier oft nicht aus, um die Komplexität der Umgebung zu bewältigen. Stattdessen werden erweiterte Konzepte wie hierarchische Gruppierung, strukturierte Verzeichnisse und dynamische Inventories eingesetzt.
Die empfohlene Praxis für große Umgebungen ist die Verwendung eines
strukturierten inventory/-Verzeichnisses:
inventory/
├── hosts.yml # Haupt-Inventory-Datei
├── group_vars/ # Gruppenvariablen
│ ├── all.yml # Variablen für alle Hosts
│ ├── production.yml # Produktionsumgebung
│ ├── staging.yml # Testumgebung
│ ├── webservers.yml # Webserver-spezifische Variablen
│ └── databases.yml # Datenbank-spezifische Variablen
├── host_vars/ # Host-spezifische Variablen
│ ├── web1.example.com.yml
│ └── db1.example.com.yml
└── dynamic/ # Dynamische Inventories
├── aws_ec2.yml # AWS EC2 Plugin
└── azure_rm.yml # Azure Plugin
Verwenden Sie YAML-Format für bessere Lesbarkeit und Struktur:
# inventory/hosts.yml
all:
children:
production:
children:
webservers:
hosts:
web1.prod.example.com:
web2.prod.example.com:
databases:
hosts:
db1.prod.example.com:
db2.prod.example.com:
staging:
children:
webservers:
hosts:
web1.staging.example.com:
databases:
hosts:
db1.staging.example.com:
datacenter_east:
children:
production:
staging:
vars:
ansible_user: ansible
ntp_server: ntp.internal.example.comOrganisieren Sie Hosts nach logischen Kriterien:
# Geografische Aufteilung
all:
children:
datacenter_europe:
children:
eu_web_tier:
hosts:
web-eu-1.example.com:
web-eu-2.example.com:
eu_db_tier:
hosts:
db-eu-1.example.com:
datacenter_americas:
children:
us_web_tier:
hosts:
web-us-1.example.com:
web-us-2.example.com:
us_db_tier:
hosts:
db-us-1.example.com:Trennen Sie Umgebungen klar voneinander:
# inventory/production.yml
production:
children:
prod_frontend:
hosts:
web[01:10].prod.example.com:
prod_backend:
hosts:
api[01:05].prod.example.com:
prod_database:
hosts:
db[01:03].prod.example.com:Erstellen Sie eine zentrale ansible.cfg für einheitliche
Konfiguration:
[defaults]
inventory = ./inventory/
remote_user = ansible
host_key_checking = False
timeout = 30
gathering = smart
fact_caching = jsonfile
fact_caching_connection = ./ansible_cache
fact_caching_timeout = 3600
[inventory]
enable_plugins = yaml, ini, script, auto, aws_ec2, azure_rm
[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=60s
pipelining = TrueAnsible liest automatisch alle Dateien aus einem Inventory-Verzeichnis:
ansible-playbook -i inventory/ site.ymlansible-playbook -i inventory/static.yml -i inventory/dynamic/ playbook.yml# inventory/combined.yml
plugin: constructed
strict: False
compose:
ansible_host: network.v4[0]
datacenter: placement.region
environment: tags.Environment | default('unknown')
groups:
webservers: "'web' in inventory_hostname"
databases: "'db' in inventory_hostname"
production: "environment == 'prod'"
staging: "environment == 'staging'"all:
children:
web_tier:
vars:
http_port: 80
https_port: 443
children:
apache_servers:
hosts:
web[01:05].example.com:
nginx_servers:
hosts:
nginx[01:03].example.com:
db_tier:
vars:
db_port: 3306
children:
mysql_primary:
hosts:
mysql-master.example.com:
mysql_secondary:
hosts:
mysql-slave[01:02].example.com:# group_vars/webservers.yml
---
packages:
- nginx
- php-fpm
- certbot
firewall_rules:
- port: 80
protocol: tcp
- port: 443
protocol: tcp
# group_vars/databases.yml
---
packages:
- mysql-server
- mysql-client
firewall_rules:
- port: 3306
protocol: tcp
source: "{{ groups['webservers'] }}"# ansible.cfg
[defaults]
gathering = smart
fact_caching = jsonfile
fact_caching_connection = ./ansible_cache
fact_caching_timeout = 3600# Nur Webserver ausführen
ansible-playbook -i inventory/ --limit webservers site.yml
# Nur spezifische Hosts
ansible-playbook -i inventory/ --limit "web01.example.com,web02.example.com" site.yml
# Pattern-basierte Limits
ansible-playbook -i inventory/ --limit "web*:&production" site.yml# ansible.cfg
[defaults]
forks = 20
strategy = free
[ssh_connection]
pipelining = True
ssh_args = -o ControlMaster=auto -o ControlPersist=300sRichtig: Sensible Daten in separaten Variablendateien verschlüsseln:
# Verschlüsseln von Gruppenvariablen
ansible-vault encrypt group_vars/production.yml
# Verschlüsseln von Host-Variablen
ansible-vault encrypt host_vars/db1.prod.example.com.yml# group_vars/production.yml (verschlüsselt)
$ANSIBLE_VAULT;1.1;AES256
66386439653233386464626...Falsch: Komplette Inventory-Dateien verschlüsseln (strukturelle YAML-Elemente werden unlesbar)
# inventory/hosts.yml (unverschlüsselt - strukturelle Daten)
all:
children:
databases:
hosts:
db1.prod.example.com:
# group_vars/databases.yml (verschlüsselt - sensible Daten)
db_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
66386439653233386464626...# Inventory-Verzeichnis schützen
chmod 750 inventory/
chmod 640 inventory/*.yml
# Sensible Dateien extra schützen
chmod 600 group_vars/production.yml
chmod 600 host_vars/*.yml# .gitignore
ansible_cache/
*.retry
vault_password.txt
# Vault-Passwort aus separater Datei
ansible-playbook -i inventory/ --vault-password-file ~/.ansible/vault_pass site.yml# Inventory-Struktur prüfen
ansible-inventory -i inventory/ --list --yaml
# Gruppenmitgliedschaften verifizieren
ansible-inventory -i inventory/ --graph
# Host-Variablen anzeigen
ansible-inventory -i inventory/ --host web1.prod.example.com# validate_inventory.yml
---
- name: Validate inventory structure
hosts: localhost
tasks:
- name: Check required groups exist
assert:
that:
- "'webservers' in groups"
- "'databases' in groups"
- "'production' in groups"
fail_msg: "Required groups missing from inventory"
- name: Verify all hosts are reachable
ping:
delegate_to: "{{ item }}"
loop: "{{ groups['all'] }}"# inventory/aws_ec2.yml
plugin: aws_ec2
regions:
- us-east-1
- eu-west-1
hostnames:
- tag:Name
compose:
ansible_host: public_ip_address
datacenter: placement.region
environment: tags.Environment | default('unknown')
groups:
webservers: "'web' in tags.Role"
databases: "'db' in tags.Role"
production: "tags.Environment == 'prod'"# inventory/azure_rm.yml
plugin: azure_rm
include_vm_resource_groups:
- production-rg
- staging-rg
auth_source: auto
compose:
ansible_host: public_ip
datacenter: location
groups:
webservers: "'web' in name"
databases: "'db' in name"# Problem: Langsame Inventory-Verarbeitung
# Lösung: Cache verwenden und Parallelisierung optimieren
# Debug-Informationen sammeln
ansible-inventory -i inventory/ --list --export > inventory_export.json# Variablen-Priorität prüfen
ansible-inventory -i inventory/ --host hostname --vars
# Gruppen-Hierarchie visualisieren
ansible-inventory -i inventory/ --graph#!/bin/bash
# cleanup_inventory.sh
# Nicht erreichbare Hosts identifizieren
ansible all -i inventory/ -m ping --one-line | grep UNREACHABLE > unreachable_hosts.txt
# Verwaiste Variablendateien finden
find group_vars/ host_vars/ -name "*.yml" | while read file; do
if ! ansible-inventory -i inventory/ --list | grep -q "$(basename "$file" .yml)"; then
echo "Orphaned file: $file"
fi
done# inventory/README.yml
---
inventory_documentation:
structure:
description: "Multi-tier application inventory"
environments:
- production
- staging
- development
tiers:
- web
- app
- database
groups:
webservers:
description: "Frontend web servers"
variables: "group_vars/webservers.yml"
databases:
description: "Database servers"
variables: "group_vars/databases.yml"
security_notes:
- "Sensitive variables encrypted with ansible-vault"
- "Production access restricted to ops team"
- "Vault password stored in secure location"__ Die Verwaltung von Inventories in großen Umgebungen erfordert:
inventory/-VerzeichnissenDurch die konsequente Anwendung dieser modernen Praktiken können Sie auch komplexeste Infrastrukturen effizient und sicher mit Ansible verwalten.