DevOps & Ansible

Ansible mit Claude Code: Automation & Configuration 2026

Ansible Playbooks, Inventory, Roles, Vault, Jinja2-Templates und Galaxy — Claude Code schreibt idempotente Server-Konfigurationen in Minuten.

6. Mai 2026 11 min Lesezeit Von SpockyMagicAI

Ansible ist das meistgenutzte Konfigurations-Management-Tool in der DevOps-Welt — und das aus gutem Grund. Kein Agent, kein spezieller Server-Daemon, reines SSH. Wer heute Infrastruktur verwaltet, kommt an Ansible kaum vorbei. Claude Code versteht Ansible nativ: Playbooks, Inventory-Strukturen, Roles-Hierarchie, Vault-Verschlüsselung und Galaxy-Integration.

In diesem Artikel zeigen wir, wie du mit Claude Code im Jahr 2026 produktiv Ansible-Projekte aufsetzt, idempotente Konfigurationen schreibst und komplexe Infrastruktur sicher verwaltest — von einem einzelnen Server bis hin zu AWX/Tower-verwalteten Umgebungen mit Hunderten von Hosts.

1. Ansible Grundlagen: Inventory, ansible.cfg & erste Playbooks

Bevor Claude Code sinnvoll helfen kann, braucht es einen soliden Grundriss. Ansible arbeitet ohne zentralen Server — alle Konfigurationen liegen als YAML-Dateien in deinem Repository. Das macht es besonders gut für KI-gestützte Entwicklung geeignet: Claude Code sieht den gesamten Kontext auf einmal.

Inventory-Struktur

Das Inventory definiert, welche Hosts Ansible verwaltet und wie diese gruppiert sind. Ein gut strukturiertes Inventory ist das Fundament jedes Ansible-Projekts.

# inventory/hosts.ini [webservers] web01.beispiel.de ansible_user=deploy web02.beispiel.de ansible_user=deploy web03.beispiel.de ansible_user=deploy [dbservers] db01.beispiel.de ansible_user=dba ansible_port=2222 db02.beispiel.de ansible_user=dba ansible_port=2222 [monitoring] mon01.beispiel.de [production:children] webservers dbservers monitoring [production:vars] ansible_ssh_private_key_file=~/.ssh/prod_key ansible_python_interpreter=/usr/bin/python3

ansible.cfg — Projekt-Konfiguration

Die Datei ansible.cfg im Projektverzeichnis überschreibt globale Defaults. Claude Code generiert diese automatisch basierend auf deiner Projektstruktur.

# ansible.cfg [defaults] inventory = ./inventory/hosts.ini roles_path = ./roles:~/.ansible/roles host_key_checking = False retry_files_enabled= False stdout_callback = yaml callbacks_enabled = profile_tasks forks = 10 gathering = smart fact_caching = jsonfile fact_caching_connection = /tmp/ansible_facts fact_caching_timeout = 86400 [ssh_connection] pipelining = True control_path_dir = /tmp/ansible-ssh-%%h-%%p-%%r [privilege_escalation] become = True become_method = sudo become_user = root

Ad-hoc Commands & erstes Playbook

Ad-hoc Commands sind ideal für schnelle Tests und Einmaltätigkeiten. Für alles Wiederkehrende schreiben wir Playbooks.

# Ad-hoc: Ping alle Webserver $ ansible webservers -m ping # Ad-hoc: Paket installieren $ ansible webservers -m apt -a "name=nginx state=present update_cache=yes" # Ad-hoc: Service neu starten $ ansible webservers -m service -a "name=nginx state=restarted" # Ad-hoc: Freien Speicher anzeigen $ ansible all -m shell -a "df -h | grep -v tmpfs"
# playbooks/site.yml — Haupt-Playbook --- - name: Webserver einrichten hosts: webservers become: true gather_facts: true vars: nginx_version: "1.26" app_port: 8080 handlers: - name: nginx neu starten ansible.builtin.service: name: nginx state: restarted - name: nginx neu laden ansible.builtin.service: name: nginx state: reloaded tasks: - name: Systempakete aktualisieren ansible.builtin.apt: update_cache: yes cache_valid_time: 3600 - name: Nginx installieren ansible.builtin.apt: name: nginx state: present notify: nginx neu starten - name: Nginx-Konfiguration deployen ansible.builtin.template: src: templates/nginx.conf.j2 dest: /etc/nginx/nginx.conf owner: root group: root mode: '0644' notify: nginx neu laden - name: Nginx-Service aktivieren und starten ansible.builtin.service: name: nginx state: started enabled: true

Claude Code Prompt für Playbook-Erstellung

"Erstelle ein Ansible-Playbook, das auf Ubuntu 22.04 Webservern nginx installiert, eine Virtual-Host-Konfiguration aus einem Jinja2-Template deployt und sicherstellt, dass der Service nach jedem Reboot automatisch startet. Idempotenz ist Pflicht."

Claude Code generiert dabei automatisch Playbook, Handler, Template und Inventory-Einträge.

2. Tasks & Module: apt, copy, template, service, user & mehr

Ansible-Module sind die Bausteine jedes Playbooks. Claude Code kennt alle gängigen Module auswendig — inklusive ihrer Parameter, Fallstricke und Best Practices für Idempotenz.

apt / yum copy template service user file command vs shell

Paketverwaltung: apt & yum

# Pakete auf Debian/Ubuntu - name: Mehrere Pakete installieren ansible.builtin.apt: pkg: - git - curl - htop - vim - python3-pip state: present update_cache: yes # Spezifische Version installieren - name: PostgreSQL 16 installieren ansible.builtin.apt: name: postgresql-16 state: present # Paket entfernen (inkl. Konfigurationsdateien) - name: Apache entfernen ansible.builtin.apt: name: apache2 state: absent purge: yes # RedHat / CentOS / RHEL - name: Pakete auf RHEL installieren ansible.builtin.yum: name: - nginx - firewalld state: latest

Dateien & Templates: copy vs. template

# copy: Statische Datei deployen - name: SSH-Konfiguration kopieren ansible.builtin.copy: src: files/sshd_config dest: /etc/ssh/sshd_config owner: root group: root mode: '0600' backup: yes notify: sshd neu starten # copy: Inline-Inhalt - name: Motd setzen ansible.builtin.copy: content: | Willkommen auf {{ inventory_hostname }} Verwaltung durch Ansible — keine manuellen Aenderungen! dest: /etc/motd # template: Jinja2-Template mit Variablen - name: Nginx Virtual Host deployen ansible.builtin.template: src: templates/vhost.conf.j2 dest: /etc/nginx/sites-available/{{ app_name }}.conf owner: www-data group: www-data mode: '0644' validate: nginx -t -c %s notify: nginx neu laden

Benutzer, Dienste & Verzeichnisse

# user: Deploy-User erstellen - name: Deploy-User anlegen ansible.builtin.user: name: deploy uid: 1050 group: www-data shell: /bin/bash home: /home/deploy create_home: yes password_lock: yes state: present # file: Verzeichnis mit korrekten Rechten - name: App-Verzeichnisse erstellen ansible.builtin.file: path: "{{ item }}" state: directory owner: deploy group: www-data mode: '0755' loop: - /var/www/app - /var/www/app/releases - /var/www/app/shared - /var/log/app # service: Dienst steuern - name: PostgreSQL starten und aktivieren ansible.builtin.service: name: postgresql state: started enabled: true

Idempotenz-Regel: Immer command statt shell bevorzugen, wenn keine Shell-Features (Pipes, Wildcards, Redirects) benötigt werden. command ist schneller, sicherer und idempotenter. Nutze creates oder removes um Doppelausführungen zu verhindern.

# command: bevorzugt, kein Shell-Overhead - name: Datenbankinitialisierung (einmalig) ansible.builtin.command: cmd: /opt/app/bin/db-init creates: /opt/app/.db_initialized # shell: wenn Pipes/Redirects noetig - name: Benutzerliste in Datei schreiben ansible.builtin.shell: cmd: getent passwd | awk -F: '{print $1}' > /tmp/users.txt changed_when: false register: user_list

3. Variablen & Jinja2: group_vars, host_vars & Filter

Das Variablen-System ist eines der mächtigsten Features von Ansible. Claude Code versteht die Precedence-Hierarchie mit ihren 22 Ebenen und wählt automatisch den richtigen Ort für jede Variable.

Variablen-Struktur

# Projektstruktur fuer Variablen ansible-projekt/ ├── group_vars/ │ ├── all.yml # Gilt fuer ALLE Hosts │ ├── all/ │ │ ├── common.yml # Aufgeteilt nach Themen │ │ └── vault.yml # Verschluesselte Secrets │ ├── webservers.yml # Gilt fuer webservers-Gruppe │ └── dbservers.yml # Gilt fuer dbservers-Gruppe └── host_vars/ ├── web01.beispiel.de.yml # Host-spezifisch └── db01.beispiel.de.yml
# group_vars/all.yml --- company_name: "Beispiel GmbH" admin_email: "ops@beispiel.de" timezone: "Europe/Berlin" ntp_servers: - 0.de.pool.ntp.org - 1.de.pool.ntp.org ssh_allowed_users: - deploy - ansible common_packages: - vim - curl - wget - htop - jq - unzip # group_vars/webservers.yml --- nginx_worker_processes: auto nginx_worker_connections: 1024 app_port: 8080 ssl_enabled: true certbot_email: "{{ admin_email }}" domains: - beispiel.de - www.beispiel.de

Jinja2-Filter in der Praxis

Jinja2-Filter erlauben mächtige Transformationen direkt in YAML. Claude Code kennt alle Built-in-Filter und Ansible-spezifischen Erweiterungen.

# Jinja2-Filter-Beispiele # String-Filter app_name_upper: "{{ app_name | upper }}" hostname_short: "{{ inventory_hostname | regex_replace('\..*$', '') }}" safe_filename: "{{ release_name | replace('/', '-') | lower }}" # Listen-Filter unique_users: "{{ all_users | unique | sort }}" admin_ips: "{{ allowed_ips | select('match', '^10\\.') | list }}" first_db: "{{ groups['dbservers'] | first }}" # Default-Werte log_level: "{{ custom_log_level | default('info') }}" workers: "{{ nginx_workers | default(ansible_processor_vcpus) }}" # Typ-Konvertierung port_number: "{{ app_port | int }}" debug_mode: "{{ enable_debug | bool }}" config_json: "{{ config_dict | to_json }}" parsed_config: "{{ config_string | from_yaml }}"

when-Bedingungen & Loops

# Bedingte Tasks - name: UFW nur auf Ubuntu installieren ansible.builtin.apt: name: ufw state: present when: ansible_distribution == "Ubuntu" - name: Firewall nur in Produktion konfigurieren ansible.builtin.ufw: rule: allow port: "{{ item }}" loop: ['80', '443', '22'] when: - environment == "production" - ansible_distribution_major_version | int >= 20 # Loop mit Dict - name: Mehrere Datenbanken erstellen community.postgresql.postgresql_db: name: "{{ item.name }}" encoding: "{{ item.encoding | default('UTF-8') }}" state: present loop: - { name: app_production, encoding: UTF-8 } - { name: app_analytics, encoding: UTF-8 } - { name: app_reporting } become_user: postgres

4. Ansible Roles: Struktur, Galaxy-Init & Dependencies

Roles sind das Herzstück wiederverwendbarer Ansible-Infrastruktur. Claude Code erzeugt vollständige Role-Strukturen mit korrekten defaults, tasks, handlers und templates in einem einzigen Prompt.

Role Galaxy Dependencies meta

Role mit ansible-galaxy init erstellen

# Role-Struktur erstellen $ ansible-galaxy init roles/nginx_vhost # Ergebnis: vollstaendige Verzeichnisstruktur roles/nginx_vhost/ ├── defaults/ │ └── main.yml # Ueberschreibbare Standard-Variablen ├── files/ │ └── nginx.mime.types # Statische Dateien ├── handlers/ │ └── main.yml # Handler fuer Notifications ├── meta/ │ └── main.yml # Metadaten, Dependencies ├── tasks/ │ ├── main.yml # Einstiegspunkt │ ├── install.yml # Installation │ └── configure.yml # Konfiguration ├── templates/ │ ├── nginx.conf.j2 # Haupt-Konfiguration │ └── vhost.conf.j2 # Virtual Host Template ├── tests/ │ ├── inventory │ └── test.yml └── vars/ └── main.yml # Interne (nicht ueberschreibbare) Vars
# roles/nginx_vhost/defaults/main.yml --- nginx_user: www-data nginx_worker_processes: auto nginx_worker_connections: 1024 nginx_keepalive_timeout: 65 nginx_client_max_body_size: "50m" nginx_gzip_enabled: true nginx_ssl_protocols: "TLSv1.2 TLSv1.3" nginx_ssl_ciphers: "ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512" nginx_vhosts: [] nginx_remove_default_vhost: true # roles/nginx_vhost/tasks/main.yml --- - name: Nginx installieren ansible.builtin.import_tasks: install.yml - name: Nginx konfigurieren ansible.builtin.import_tasks: configure.yml - name: Virtual Hosts deployen ansible.builtin.include_tasks: vhosts.yml when: nginx_vhosts | length > 0

Role Dependencies & meta/main.yml

# roles/app_server/meta/main.yml --- galaxy_info: author: Beispiel GmbH DevOps description: Vollstaendiger App-Server mit Nginx, Node.js und PM2 company: Beispiel GmbH license: MIT min_ansible_version: "2.15" platforms: - name: Ubuntu versions: ['22.04', '24.04'] - name: Debian versions: ['11', '12'] galaxy_tags: [web, nginx, nodejs, pm2] dependencies: - role: common_packages - role: nginx_vhost vars: nginx_worker_processes: 4 - role: geerlingguy.nodejs vars: nodejs_version: "20.x"
# Playbook mit mehreren Roles --- - name: App-Server vollstaendig einrichten hosts: webservers become: true roles: - role: common_packages - role: security_hardening - role: nginx_vhost vars: nginx_vhosts: - name: beispiel.de server_name: "beispiel.de www.beispiel.de" root: /var/www/app/current/public ssl: true - role: app_server - role: monitoring_agent when: monitoring_enabled | default(true)

Claude Code-Prompt für vollständige Role

"Erstelle eine Ansible Role 'postgresql_server' mit defaults, tasks, handlers und templates. Die Role soll PostgreSQL 16 installieren, pg_hba.conf aus einem Jinja2-Template konfigurieren, einen dedizierten DB-User anlegen und Backups mit pg_dump einrichten. Idempotenz ist Pflicht."

Claude Code liefert die komplette Role-Struktur — alle Dateien, sofort einsatzbereit.

5. Ansible Vault: Secrets sicher in Git verwalten

Ansible Vault verschlüsselt sensible Daten (Passwörter, API-Keys, SSL-Zertifikate) direkt in den YAML-Dateien. Die verschlüsselten Dateien sind git-safe — du kannst sie gefahrlos committen.

Vault encrypt Vault decrypt vault_password_file git-safe

Vault-Grundoperationen

# Ganze Datei verschluesseln $ ansible-vault encrypt group_vars/all/vault.yml New Vault password: *** Confirm New Vault password: *** Encryption successful # Einzelnen Wert verschluesseln (inline) $ ansible-vault encrypt_string 'supergeheim123' --name 'db_password' db_password: !vault | $ANSIBLE_VAULT;1.1;AES256 38306461306239313630373736353966356230623065656337643336... # Datei entschluesseln (temporaer anschauen) $ ansible-vault view group_vars/all/vault.yml # Datei bearbeiten (entschluesselt oeffnen, re-encrypt beim Speichern) $ ansible-vault edit group_vars/all/vault.yml # Passwort aendern $ ansible-vault rekey group_vars/all/vault.yml

vault.yml & Playbook-Integration

# group_vars/all/vault.yml (VOR Verschluesselung) --- vault_db_password: "P@ssw0rd_Supergeheim_2026!" vault_app_secret_key: "aB3xK9mN2pQ7rS4tU6vW1yZ8" vault_smtp_password: "smtp_secret_xyz" vault_ssl_private_key: | -----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEA1234... -----END RSA PRIVATE KEY----- # group_vars/all/main.yml (Klartext, referenziert Vault-Vars) --- db_password: "{{ vault_db_password }}" app_secret_key: "{{ vault_app_secret_key }}" smtp_password: "{{ vault_smtp_password }}" # Playbook ausfuehren mit Vault-Passwort $ ansible-playbook site.yml --ask-vault-pass $ ansible-playbook site.yml --vault-password-file ~/.vault_pass.txt

vault_password_file & CI/CD-Integration

# .gitignore: Vault-Passwortdatei NIEMALS committen! .vault_pass.txt *.vault_pass .ansible_vault_password # ansible.cfg: vault_password_file konfigurieren [defaults] vault_password_file = ~/.vault_pass.txt # GitLab CI/CD: Vault-Passwort als CI-Secret # .gitlab-ci.yml deploy: script: - echo "$ANSIBLE_VAULT_PASSWORD" > /tmp/.vault_pass.txt - ansible-playbook site.yml --vault-password-file /tmp/.vault_pass.txt - rm -f /tmp/.vault_pass.txt variables: ANSIBLE_VAULT_PASSWORD: ${ANSIBLE_VAULT_PASSWORD} # aus CI-Secrets # Mehrere Vault-IDs fuer verschiedene Umgebungen $ ansible-playbook site.yml \ --vault-id prod@~/.vault_prod.txt \ --vault-id staging@~/.vault_staging.txt

Sicherheitsregel: Vault-Passwortdateien niemals in Git committen. Nutze CI/CD-Secrets, AWS Secrets Manager, HashiCorp Vault oder ansible-vault-pass-client. Die verschlüsselten vault.yml-Dateien selbst dürfen committet werden — sie sind ohne das Passwort wertlos.

6. Ansible Galaxy & AWX/Tower: Community Roles & Enterprise Automation

Ansible Galaxy ist das öffentliche Repository für Community-Roles und Collections. AWX (Open Source) bzw. Ansible Tower (Enterprise) sind Web-UIs für zentral verwaltete Ansible-Ausführungen mit RBAC, Scheduling und Audit-Log.

Galaxy Collections requirements.yml AWX/Tower

Galaxy: Roles & Collections installieren

# Einzelne Role installieren $ ansible-galaxy role install geerlingguy.nginx # Collection installieren $ ansible-galaxy collection install community.postgresql $ ansible-galaxy collection install community.docker $ ansible-galaxy collection install community.general # requirements.yml: alle Abhaengigkeiten in einer Datei
# requirements.yml --- roles: - name: geerlingguy.nginx version: "3.2.0" - name: geerlingguy.nodejs version: "6.2.0" - name: geerlingguy.postgresql version: "3.4.0" - src: https://github.com/meinefirma/ansible-role-custom.git name: custom_app_role version: main collections: - name: community.postgresql version: ">=3.0.0,<4.0.0" - name: community.docker version: "3.10.0" - name: amazon.aws version: "7.0.0" - name: community.general
# Alle Requirements installieren $ ansible-galaxy install -r requirements.yml $ ansible-galaxy collection install -r requirements.yml # In CI/CD (z.B. GitHub Actions) - name: Ansible Galaxy Requirements installieren run: | ansible-galaxy install -r requirements.yml --roles-path ./roles ansible-galaxy collection install -r requirements.yml

AWX/Tower: Job Templates & CI/CD-Integration

# AWX-Konfiguration via Ansible (awx.awx Collection) --- - name: AWX Job Template erstellen hosts: localhost gather_facts: false collections: - awx.awx tasks: - name: Job Template anlegen awx.awx.job_template: name: "Deploy Webserver" organization: "Beispiel GmbH" inventory: "Production" project: "Infrastruktur-Repo" playbook: "playbooks/webserver.yml" credentials: - SSH Production Key - Vault Production limit: "webservers" survey_enabled: true ask_limit_on_launch: true become_enabled: true state: present controller_host: "https://awx.beispiel.de" controller_username: "{{ awx_user }}" controller_password: "{{ vault_awx_password }}"
# GitHub Actions: AWX Job per API triggern name: Deploy via AWX on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest steps: - name: AWX Job Template starten run: | curl -s -X POST \ -H "Authorization: Bearer ${{ secrets.AWX_TOKEN }}" \ -H "Content-Type: application/json" \ -d '{"limit": "webservers", "extra_vars": {"release_tag": "${{ github.sha }}"}}' \ https://awx.beispiel.de/api/v2/job_templates/42/launch/ \ | jq '.id' - name: Auf Job-Abschluss warten run: | JOB_ID=$(cat job_id.txt) while true; do STATUS=$(curl -s -H "Authorization: Bearer ${{ secrets.AWX_TOKEN }}" \ https://awx.beispiel.de/api/v2/jobs/$JOB_ID/ | jq -r '.status') echo "Job Status: $STATUS" [[ "$STATUS" == "successful" ]] && break [[ "$STATUS" == "failed" ]] && exit 1 sleep 10 done

Ansible-Versionsverwaltung mit pip

# Ansible in virtuelle Umgebung installieren (empfohlen) $ python3 -m venv .venv $ source .venv/bin/activate $ pip install ansible==9.3.0 ansible-lint==24.2.0 # requirements.txt fuer Python-Abhaengigkeiten ansible==9.3.0 ansible-lint==24.2.0 jinja2==3.1.4 pyyaml==6.0.1 boto3==1.34.0 # fuer AWS-Module psycopg2-binary==2.9.9 # fuer PostgreSQL-Module
Feature AWX (Open Source) Ansible Tower (Enterprise) CLI (lokal)
Kosten Kostenlos Abo-basiert Kostenlos
Web-UI Ja Ja (erweitert) Nein
RBAC Ja Ja (granular) Nein
Scheduling Ja Ja via Cron
Audit-Log Basis Erweitert Stdout/File
Support Community Red Hat Community

Claude Code + Ansible-Idempotenz: Claude Code prüft bei jeder generierten Task automatisch auf Idempotenz. Es vermeidet shell wo command reicht, nutzt immer state: present statt ad-hoc-Befehle und empfiehlt changed_when / failed_when für sauberes Change-Tracking.

Zusammenfassung: Claude Code als Ansible-Copilot

Claude Code versteht Ansible auf semantischer Ebene — nicht nur die Syntax, sondern auch Best Practices, Idempotenz-Prinzipien und die Feinheiten der Variablen-Precedence. Das macht es zum idealen Partner für:

Ansible DevOps Configuration Management Playbooks Ansible Vault Ansible Galaxy AWX Jinja2 Claude Code IaC 2026

Ansible-Automation mit Claude Code ausprobieren

Teste jetzt kostenlos, wie Claude Code deine Ansible-Playbooks, Roles und Vault-Konfigurationen beschleunigt — keine Kreditkarte, sofort starten.

Kostenlos testen →