66 Troubleshooting und Fehlerbehebung

66.1 Typische Fehlerbilder und Ursachen

66.1.1 Berechtigungsfehler erkennen und verstehen

Symptom: “Permission denied” Fehler

fatal: [webserver]: FAILED! => {"msg": "sudo: a password is required"}

Häufige Ursachen:

Symptom: “User not allowed to execute” Fehler

fatal: [webserver]: FAILED! => {"msg": "Sorry, user ansible is not allowed to execute '/bin/systemctl' as root"}

Häufige Ursachen:

66.1.2 Authentifizierungsprobleme

Symptom: SSH-Schlüssel werden abgelehnt

fatal: [webserver]: UNREACHABLE! => {"msg": "Failed to connect to the host via ssh: Permission denied (publickey)"}

Häufige Ursachen:

Symptom: LDAP/AD-Authentifizierung fehlschlägt

Authentication failed for user 'john.doe@company.com'

Häufige Ursachen:

66.1.3 Rollen- und Berechtigungsprobleme

Symptom: Benutzer kann Playbooks nicht ausführen

User does not have permission to execute job template 'Deploy Application'

Häufige Ursachen:

Symptom: Vault-Entschlüsselung schlägt fehl

fatal: [localhost]: FAILED! => {"msg": "Decryption failed (no vault secrets would found that could decrypt)"}

Häufige Ursachen:

66.2 Werkzeuge zur Fehlerdiagnose

66.2.1 Debug-Module effektiv einsetzen

Grundlegende Debug-Ausgabe:

- name: Aktuellen Benutzer und Berechtigungen anzeigen
  debug:
    msg: |
      Benutzer: {{ ansible_user }}
      Effektive UID: {{ ansible_user_uid }}
      Gruppen: {{ ansible_user_gid }}
      Become-Methode: {{ ansible_become_method | default('nicht gesetzt') }}

Berechtigungen vor kritischen Aktionen prüfen:

- name: Sudo-Berechtigungen testen
  command: sudo -n true
  register: sudo_test
  failed_when: false
  changed_when: false

- name: Warnung bei fehlenden sudo-Rechten
  debug:
    msg: "WARNUNG: Keine passwordlosen sudo-Rechte verfügbar"
  when: sudo_test.rc != 0

Vault-Status überprüfen:

- name: Vault-Verfügbarkeit prüfen
  debug:
    msg: "Vault-Variable verfügbar: {{ vault_password is defined }}"

66.2.2 Erweiterte Ausgabe und Logging

Detaillierte Playbook-Ausführung:

# Maximale Verbosity für Debugging
ansible-playbook playbook.yml -vvvv

# Nur SSH-Debugging
ansible-playbook playbook.yml -vvv | grep -i ssh

# Ausgabe in Logfile umleiten
ansible-playbook playbook.yml -vvv > debug.log 2>&1

Check-Modus für sichere Tests:

# Trockenlauf ohne Änderungen
ansible-playbook playbook.yml --check --diff

# Nur bestimmte Tags prüfen
ansible-playbook playbook.yml --check --tags "user-management"

66.2.3 AWX/Tower Log-Analyse

Wichtige Logfile-Pfade:

# Job-Ausführungsdetails
/var/log/tower/job_events/

# Authentifizierungs-Logs
/var/log/tower/tower.log | grep -i auth

# LDAP-Synchronisation
/var/log/tower/tower.log | grep -i ldap

Log-Analyse-Befehle:

# Fehlgeschlagene Authentifizierungen
journalctl -u nginx -f | grep "401\|403"

# SSH-Verbindungsprobleme
tail -f /var/log/tower/tower.log | grep -i "ssh\|connection"

66.2.4 Strukturierte Fehlerdiagnose

Pause-Module für Zwischenprüfungen:

- name: System-Status vor kritischen Änderungen prüfen
  pause:
    prompt: |
      Bitte prüfen Sie:
      - Sind alle Benutzer korrekt angelegt?
      - Funktioniert die SSH-Verbindung?
      - Sind die Berechtigungen korrekt gesetzt?
      Drücken Sie Enter zum Fortfahren oder Ctrl+C zum Abbrechen
  when: ansible_check_mode is not defined

Conditional Debugging:

- name: Erweiterte Diagnose bei Fehlern
  block:
    - name: Kritische Aufgabe ausführen
      user:
        name: "{{ item.name }}"
        groups: "{{ item.groups }}"
      loop: "{{ users }}"
  
  rescue:
    - name: Fehlerkontext sammeln
      debug:
        msg: |
          Fehler bei Benutzer: {{ item.name | default('unbekannt') }}
          Verfügbare Gruppen: {{ ansible_facts.getent_group.keys() | list }}
          Aktueller Benutzer: {{ ansible_user }}
          
    - name: System-Zustand protokollieren
      shell: |
        id {{ ansible_user }}
        groups {{ ansible_user }}
        cat /etc/passwd | tail -5
      register: system_state
      
    - debug:
        var: system_state.stdout_lines

66.3 Spezielle Troubleshooting-Szenarien

66.3.1 LDAP/Active Directory Debugging

LDAP-Verbindung testen:

# Basis-LDAP-Test
ldapsearch -x -H ldap://dc.company.com -D "CN=service,OU=Users,DC=company,DC=com" -w password -b "DC=company,DC=com" "(sAMAccountName=testuser)"

# LDAP-SSL-Verbindung prüfen
openssl s_client -connect dc.company.com:636 -verify_return_error

AWX LDAP-Konfiguration validieren:

# AWX Management Command für LDAP-Test
awx-manage test_ldap_configuration

Häufige LDAP-Mappings prüfen:

# LDAP-Gruppen-Mapping in AWX
AUTH_LDAP_GROUP_SEARCH: "OU=Groups,DC=company,DC=com"
AUTH_LDAP_GROUP_TYPE_PARAMS:
  name_attr: "cn"
  member_attr: "member"

# Debug LDAP-Attribute
AUTH_LDAP_USER_ATTR_MAP:
  first_name: "givenName"
  last_name: "sn"
  email: "mail"

66.3.2 Become-Troubleshooting

Sudo-Konfiguration validieren:

# Als Ansible-Benutzer testen
sudo -l -U ansible

# Passwordlose sudo prüfen
sudo -n true && echo "OK" || echo "Password required"

Alternative become-Methoden:

# su statt sudo verwenden
- name: Mit su eskalieren
  user:
    name: testuser
  become: true
  become_method: su
  become_user: root

# doas für BSD-Systeme
- name: Mit doas eskalieren
  user:
    name: testuser
  become: true
  become_method: doas

Become-Debugging im Playbook:

- name: Become-Kontext prüfen
  debug:
    msg: |
      Become aktiv: {{ ansible_become | default(false) }}
      Become-Benutzer: {{ ansible_become_user | default('nicht gesetzt') }}
      Effektive UID: {{ ansible_user_uid }}
      Effektive GID: {{ ansible_user_gid }}

66.3.3 Systematische Troubleshooting-Strategien

1. Isolierte Tests erstellen:

# Minimal-Playbook für Berechtigungstests
---
- hosts: test-system
  gather_facts: false
  tasks:
    - name: Verbindung testen
      ping:
      
    - name: Become-Test
      command: whoami
      become: true
      register: become_test
      
    - debug:
        msg: "Become erfolgreich als: {{ become_test.stdout }}"

2. Schritt-für-Schritt Diagnose:

# 1. Basis-Konnektivität
ansible test-host -m ping

# 2. Fakten sammeln
ansible test-host -m setup | grep ansible_user

# 3. Become testen
ansible test-host -m command -a "whoami" --become

# 4. Spezifische Befehle testen
ansible test-host -m command -a "systemctl status nginx" --become

3. Benutzer-Audit durchführen:

- name: Benutzer-Audit für Troubleshooting
  block:
    - name: Alle Systembenutzer auflisten
      shell: "cut -d: -f1 /etc/passwd | sort"
      register: system_users
      
    - name: Aktuelle Gruppenmitgliedschaften
      shell: "groups {{ ansible_user }}"
      register: user_groups
      
    - name: Sudo-Berechtigungen prüfen
      shell: "sudo -l -U {{ ansible_user }}"
      register: sudo_rights
      failed_when: false
      
    - name: Audit-Zusammenfassung
      debug:
        msg: |
          System-Benutzer: {{ system_users.stdout_lines | length }}
          Ansible-Benutzer: {{ ansible_user }}
          Gruppen: {{ user_groups.stdout }}
          Sudo verfügbar: {{ sudo_rights.rc == 0 }}

66.4 Debugging-Checkliste und Best Practices

66.4.1 Vorgehen bei Fehlern

Schritt 1: Grundlagen prüfen

Schritt 2: Berechtigungen validieren

Schritt 3: Systematisch eingrenzen

66.4.2 Zentrale Debug-Strategien

Umgebungsvariablen für Debugging:

export ANSIBLE_DEBUG=1
export ANSIBLE_VERBOSITY=3
export ANSIBLE_LOG_PATH=/tmp/ansible.log
export ANSIBLE_KEEP_REMOTE_FILES=1

Playbook-Templates für schnelle Tests:

# Quick-Test Template
---
- hosts: "{{ target_host | default('localhost') }}"
  gather_facts: "{{ gather_facts | default(true) }}"
  become: "{{ use_become | default(false) }}"
  
  tasks:
    - name: Debug-Informationen sammeln
      debug:
        msg: |
          Host: {{ inventory_hostname }}
          User: {{ ansible_user | default('undefined') }}
          Become: {{ ansible_become | default(false) }}
          Python: {{ ansible_python_interpreter | default('system default') }}
      tags: [always, debug]

Logging und Dokumentation:

# Strukturierte Logs für Troubleshooting
mkdir -p /var/log/ansible/troubleshooting
ansible-playbook playbook.yml -vvv 2>&1 | tee "/var/log/ansible/troubleshooting/$(date +%Y%m%d-%H%M%S)-debug.log"