Skip to content

Konfigurationsdateien automatisieren

YAML-, TOML- und INI-Dateien lesen, erzeugen und für Infrastruktur- und Automatisierungsaufgaben nutzen.

Moderne IT-Infrastrukturen werden zunehmend über Konfigurationsdateien beschrieben. Docker Compose, Kubernetes, Ansible, GitHub Actions, Prometheus, Grafana und viele weitere Werkzeuge verwenden deklarative Konfigurationen, um Systeme zu beschreiben und zu steuern.

Python eignet sich hervorragend, um solche Konfigurationen automatisch zu erzeugen, zu validieren oder anzupassen. Statt Dateien manuell zu bearbeiten, können Konfigurationen aus Daten, Vorlagen oder Inventarsystemen generiert werden.

Dadurch lassen sich Fehler reduzieren, wiederkehrende Aufgaben automatisieren und größere Umgebungen konsistent verwalten.

In diesem Kapitel lernen Sie die wichtigsten Konfigurationsformate kennen und erfahren, wie Python beim Erstellen und Verarbeiten solcher Dateien eingesetzt werden kann.

INI-Dateien mit configparser

Grundlagen von INI-Dateien und configparser

INI-Dateien sind ein klassisches und weit verbreitetes Format zur Konfiguration von Anwendungen und Systemdiensten. Sie bestehen aus Abschnitten, die in eckigen Klammern stehen, und Schlüssel-Wert-Paaren darunter. Beispiel:

[database]
host = db.example.com
port = 5432
user = admin
password = secret

[logging]
level = INFO
file = /var/log/app.log

Python bietet mit dem Modul configparser eine einfache Möglichkeit, solche Dateien zu lesen, zu schreiben und zu bearbeiten. Das ist besonders nützlich, wenn Sie Konfigurationen automatisiert anpassen oder auswerten wollen – etwa bei der Verwaltung von Serverdiensten oder Container-Setups.

INI-Dateien lesen

So lesen Sie eine INI-Datei ein und greifen auf die Werte zu:

import configparser

config = configparser.ConfigParser()
config.read('app.conf')  # Pfad zur INI-Datei

# Zugriff auf Werte
db_host = config['database']['host']
db_port = config.getint('database', 'port')  # Typkonvertierung

print(f'Datenbank-Host: {db_host}, Port: {db_port}')

Hinweis: config.getint() konvertiert automatisch in einen Integer, was bei Ports oder Zeitangaben praktisch ist.

INI-Dateien schreiben und ändern

Konfigurationsdateien lassen sich auch ändern oder neu erstellen:

config['logging'] = {
    'level': 'DEBUG',
    'file': '/var/log/app_debug.log'
}

with open('app.conf', 'w') as conf_file:
    config.write(conf_file)

Das Überschreiben ganzer Abschnitte ist einfach; einzelne Werte können auch gezielt gesetzt werden:

config.set('database', 'password', 'new_secret')

Automatisierte Verwaltung von INI-Dateien

In der Praxis wollen Sie oft INI-Dateien in Skripten automatisch anpassen, z. B. um Umgebungsvariablen zu übernehmen oder Deployments zu steuern.

Beispiel: Anpassung einer Docker-Compose-Umgebungsdatei env.ini mit dynamischen Werten:

[service]
image = myapp:latest
replicas = 3

[network]
mode = bridge
import configparser
import os

config = configparser.ConfigParser()
config.read('env.ini')

# Dynamisch Anzahl der Replikate aus Umgebungsvariable setzen
replicas = os.getenv('APP_REPLICAS', '3')
config.set('service', 'replicas', replicas)

with open('env.ini', 'w') as f:
    config.write(f)

Best Practices

  • Kommentare und Formatierung: configparser erhält Kommentare beim Schreiben nicht erhalten. Für kritische Dokumentation empfiehlt sich eine separate README oder Inline-Dokumentation im Skript.
  • Datentypen beachten: INI-Dateien speichern Werte als Strings. Nutzen Sie getint(), getboolean() oder getfloat(), um Typen korrekt zu interpretieren.
  • Fehlerbehandlung: Prüfen Sie vor dem Zugriff, ob Sektionen und Schlüssel existieren, um Laufzeitfehler zu vermeiden.
if config.has_section('database') and config.has_option('database', 'host'):
    host = config['database']['host']
else:
    host = 'localhost'  # Fallback

Vergleich zu Shell-Skripten

Shell-Skripte arbeiten oft mit grep, sed oder awk, um INI-Dateien zu bearbeiten. Python mit configparser bietet:

  • Strukturierte Datenzugriffe: Keine komplexen regulären Ausdrücke nötig
  • Einfache Typkonvertierung: Automatische Umwandlung in int/boolean
  • Bessere Lesbarkeit und Wartbarkeit: Klarer Code statt Shell-Tricks

Zusammenfassung

Mit configparser verwalten Sie klassische INI-Konfigurationsdateien in Python sicher und automatisiert. Dies erleichtert die Anpassung von Infrastruktur- und Anwendungssettings, etwa bei Container-Orchestrierung oder Monitoring-Tools. Der modulare Zugriff auf Sektionen und Werte macht Ihre Skripte robust und flexibel – ein klarer Vorteil gegenüber reinem Shell-Scripting.

YAML-Dateien verarbeiten

YAML-Grundlagen in der Infrastrukturautomation

YAML ("YAML Ain't Markup Language") ist ein weit verbreitetes Format zur Beschreibung von Konfigurationen und Infrastrukturdefinitionen. Es ist besonders in DevOps- und Container-Umgebungen beliebt, da es lesbarer ist als JSON und gleichzeitig komplexe Strukturen abbilden kann.

Typische Beispiele sind Docker-Compose-Dateien, Kubernetes-Manifeste oder Ansible-Playbooks. Python bietet mit Bibliotheken wie PyYAML eine einfache Möglichkeit, YAML-Dateien zu lesen, zu verändern und zu schreiben.


YAML-Dateien mit Python einlesen

Zuerst installieren Sie PyYAML:

pip install pyyaml

Ein einfaches Beispiel: Ein Docker-Compose-Auszug als YAML-Datei docker-compose.yml:

version: '3.8'
services:
  webapp:
    image: myapp:latest
    ports:
      - "8080:80"
    environment:
      - ENV=production

Mit Python können Sie diese Datei so einlesen:

import yaml

with open('docker-compose.yml', 'r', encoding='utf-8') as f:
    config = yaml.safe_load(f)

print(config['services']['webapp']['image'])  # Ausgabe: myapp:latest

safe_load lädt die YAML-Datei sicher und wandelt sie in Python-Datenstrukturen (Dictionaries, Listen) um.


YAML-Dateien erzeugen und verändern

Sie können YAML-Daten auch in Python erstellen oder verändern und anschließend speichern:

import yaml

# Neue Service-Konfiguration
new_service = {
    'version': '3.8',
    'services': {
        'db': {
            'image': 'postgres:15',
            'ports': ['5432:5432'],
            'environment': ['POSTGRES_PASSWORD=secret']
        }
    }
}

with open('docker-compose-db.yml', 'w', encoding='utf-8') as f:
    yaml.dump(new_service, f, sort_keys=False)

Das Ergebnis ist eine gut lesbare YAML-Datei, die Sie direkt in Docker-Compose verwenden können.


Praxis: Automatisiertes Erzeugen von Docker-Compose-Dateien

In größeren Projekten möchten Sie oft Docker-Compose-Dateien dynamisch erzeugen, z.B. basierend auf Inventardaten oder Umgebungsparametern.

import yaml

def generate_compose(services):
    compose = {'version': '3.8', 'services': {}}
    for name, params in services.items():
        compose['services'][name] = {
            'image': params['image'],
            'ports': [f"{host}:{container}" for host, container in params.get('ports', [])],
            'environment': [f"{k}={v}" for k, v in params.get('environment', {}).items()]
        }
    return compose

services_config = {
    'webapp': {
        'image': 'myapp:latest',
        'ports': [(8080, 80)],
        'environment': {'ENV': 'production'}
    },
    'db': {
        'image': 'postgres:15',
        'ports': [(5432, 5432)],
        'environment': {'POSTGRES_PASSWORD': 'secret'}
    }
}

compose_yaml = generate_compose(services_config)

with open('docker-compose-generated.yml', 'w', encoding='utf-8') as f:
    yaml.dump(compose_yaml, f, sort_keys=False)

So können Sie z.B. aus einer Inventardatenbank oder API-Daten automatisiert Docker-Compose-Dateien erzeugen und so Deployments standardisieren.


Warum Python statt Shell-Skripte?

Shell-Skripte sind oft schwer lesbar und fehleranfällig, wenn es um komplexe Datenstrukturen wie YAML geht. Python bietet:

  • Klare Datenstrukturen (Dictionaries, Listen)
  • Leicht verständliche Syntax
  • Umfangreiche Bibliotheken
  • Bessere Fehlerbehandlung

Dadurch lassen sich komplexe Konfigurationsdateien zuverlässig und wartbar automatisieren.


Zusammenfassung

  • YAML ist ein Standardformat für Infrastruktur- und Deployment-Konfigurationen.
  • PyYAML ermöglicht einfaches Einlesen, Verändern und Schreiben von YAML-Dateien.
  • Python eignet sich hervorragend, um Docker-Compose- oder Kubernetes-Konfigurationen dynamisch zu erzeugen.
  • Automatisierung mit Python erhöht die Zuverlässigkeit und Wartbarkeit gegenüber Shell-Skripten.

Im nächsten Abschnitt lernen Sie, wie Sie TOML-Dateien ähnlich effizient verarbeiten können.

TOML-Dateien verarbeiten

TOML-Dateien lesen und schreiben

TOML (Tom's Obvious, Minimal Language) ist ein modernes Konfigurationsformat, das besonders in der Python-Welt durch Dateien wie pyproject.toml an Bedeutung gewonnen hat. Es ist lesbar, strukturiert und unterstützt verschiedene Datentypen wie Strings, Zahlen, Listen und Tabellen.

Python bietet mit dem Modul tomllib (ab Python 3.11) eine native Möglichkeit, TOML-Dateien einzulesen. Für das Schreiben oder Ändern von TOML-Dateien empfiehlt sich das externe Paket tomli-w, das kompatibel und einfach zu nutzen ist.

TOML-Datei einlesen

Angenommen, wir haben eine pyproject.toml mit folgenden Inhalten:

[tool.poetry]
name = "mein-projekt"
version = "0.1.0"
description = "Ein Beispielprojekt"

[tool.poetry.dependencies]
python = ">=3.8"
requests = "^2.28"

[tool.poetry.dev-dependencies]
pytest = "^7.1"

So lesen wir diese Datei ein und greifen auf einzelne Werte zu:

import tomllib

with open("pyproject.toml", "rb") as f:
    config = tomllib.load(f)

# Zugriff auf Projektname
projektname = config["tool"]["poetry"]["name"]
print(f"Projektname: {projektname}")

# Abhängigkeiten ausgeben
dependencies = config["tool"]["poetry"]["dependencies"]
print("Abhängigkeiten:")
for paket, version in dependencies.items():
    print(f"  {paket}: {version}")

TOML-Datei schreiben und ändern

Um eine TOML-Datei zu erzeugen oder zu verändern, installieren Sie zuerst tomli-w:

pip install tomli-w

Beispiel: Eine neue deploy_config.toml für ein Infrastruktur-Deployment erzeugen:

import tomli_w

config = {
    "server": {
        "host": "10.0.0.5",
        "port": 22,
        "user": "admin"
    },
    "deployment": {
        "version": "1.2.3",
        "services": ["web", "db", "cache"]
    }
}

with open("deploy_config.toml", "wb") as f:
    f.write(tomli_w.dumps(config).encode("utf-8"))

Praxis: pyproject.toml automatisiert anpassen

In DevOps-Szenarien kann es sinnvoll sein, Versionsnummern oder Abhängigkeiten automatisiert zu aktualisieren, z.B. nach einem Build oder Release.

import tomllib
import tomli_w

# pyproject.toml einlesen
with open("pyproject.toml", "rb") as f:
    config = tomllib.load(f)

# Versionsnummer aktualisieren
config["tool"]["poetry"]["version"] = "0.1.1"

# Neue Dev-Abhängigkeit hinzufügen
dev_deps = config["tool"]["poetry"].setdefault("dev-dependencies", {})
dev_deps["black"] = "^23.1"

# Datei überschreiben
with open("pyproject.toml", "wb") as f:
    f.write(tomli_w.dumps(config).encode("utf-8"))

Vorteile von Python gegenüber Shell-Skripten

  • Strukturierte Daten: TOML wird als verschachteltes Wörterbuch geladen, was einfache und sichere Änderungen erlaubt, ohne auf komplexe Textmanipulation zurückgreifen zu müssen.
  • Fehlervermeidung: Syntaxfehler in TOML werden beim Parsen erkannt, bevor die Datei gespeichert wird.
  • Wiederverwendbarkeit: Python-Skripte lassen sich modular gestalten, z.B. um aus Inventardaten dynamisch Konfigurationen zu generieren.

Best Practices

  • Verwenden Sie immer rb-Modus beim Einlesen mit tomllib, da das Modul Bytes erwartet.
  • Nutzen Sie tomli-w zum Schreiben, da tomllib nur Lesezugriff bietet.
  • Validieren Sie geänderte Konfigurationen vor dem Deployment, um Inkonsistenzen zu vermeiden.
  • Dokumentieren Sie automatisch generierte Dateien klar, z.B. mit einem Kommentar am Anfang.

Zusammenfassung

Mit Python können Sie TOML-Dateien zuverlässig und einfach lesen, ändern und erzeugen. Das ist besonders nützlich für moderne Infrastruktur- und Anwendungsprojekte, die auf pyproject.toml oder ähnliche Formate setzen. Die Kombination aus tomllib und tomli-w ermöglicht eine robuste Automatisierung, die weit über einfache Textmanipulationen hinausgeht und so die Wartbarkeit und Qualität Ihrer Konfigurationsverwaltung erhöht.