# Ansible-Basics-Handbuch

## 1. Einführung in Ansible

### Was ist Ansible?
Ansible ist ein **Open-Source-Tool zur Automatisierung von IT-Infrastrukturen**. Es ermöglicht die **zentrale Verwaltung, Konfiguration und Bereitstellung** von Servern, Netzwerkgeräten und Anwendungen. Ansible ist besonders nützlich, weil es:

- **Zeit spart**: Automatisiert Routineaufgaben wie Software-Installationen, Updates oder Benutzerverwaltung.
- **Fehler reduziert**: Durch die Verwendung von **Playbooks** (Skripte in YAML) werden Konfigurationen **wiederholbar und konsistent** umgesetzt.
- **Einfach zu erlernen**: Nutzt **YAML**, eine leicht lesbare Sprache, und erfordert keine Programmierkenntnisse.
- **Agentenlos arbeitet**: Benötigt auf den verwalteten Systemen **keine zusätzliche Software** – nur **SSH** ist erforderlich.
- **Flexibel einsetzbar**: Unterstützt eine Vielzahl von Systemen, darunter **Ubuntu-Server, Docker-Container und Netzwerkgeräte**.

### Typische Anwendungsfälle
- **Server-Setup**: Automatisierte Installation und Konfiguration von Servern (z. B. für Webserver oder Datenbanken).
- **Benutzerverwaltung**: Erstellen und Verwalten von Benutzern und Gruppen.
- **Sicherheitsupdates**: Regelmäßige, automatische Updates für alle Systeme.
- **Software-Bereitstellung**: Installation und Konfiguration von Programmen wie **Nginx, Samba oder Docker**.
- **Backup-Strategien**: Automatisierte Sicherung von Daten.


### Wie funktioniert Ansible?
Ansible arbeitet nach dem **Push-Prinzip**:

1. **Control Node**: Der Rechner, von dem aus Ansible gesteuert wird. (Im Kurs das Linux Mint)
2. **Managed Nodes**: Die Systeme, die von Ansible verwaltet werden. (Im Kurs der Ubuntu-Server)
3. **Inventar**: Eine Liste der verwalteten Systeme (IP-Adressen oder Hostnamen).
4. **Playbooks**: Skripte, die definieren, welche Aufgaben auf den verwalteten Systemen ausgeführt werden sollen.

**Beispiel:**
Sie möchten auf mehreren Servern **Nginx installieren** und eine **Standard-Webseite** bereitstellen. Statt auf jedem Server manuell Befehle auszuführen, schreiben Sie ein **Ansible-Playbook**, das diese Aufgabe **automatisiert und zentral** erledigt.

---

### Voraussetzungen
- **Ubuntu Server** (als Managed Node).
- **SSH-Zugriff** auf die Server (mit Schlüsselpaar).
- **Ansible** auf dem Control Node (Linux Mint) installiert.

---

## 2. Vorbereitung: SSH-Key-Paar für Ansible erstellen

### Schritt 1: Schlüsselpaar auf dem Ansible-Control-Node erstellen
````bash
ssh-keygen -t ed25519 -C "ansible@control-node"
````
* Speicherort: /home/benutzer/.ssh/id_ed25519 (Standard)
* Passphrase: Optional, aber für zusätzliche Sicherheit empfohlen.

### Schritt 2: Öffentlichen Schlüssel auf die Managed Nodes übertragen
Kopieren Sie den öffentlichen Schlüssel mit folgendem Befehl auf Ihre Server:
````bash
ssh-copy-id -i ~/.ssh/id_ed25519.pub benutzer@server-ip
````
Beispiel:
````bash
ssh-copy-id -i ~/.ssh/id_ed25519.pub meisterkurs@192.168.100.250
````
Test der Verbindung:
````bash
ssh Meisterkurs@192.168.100.250
````
Die Anmeldung sollte jetzt **ohne Passwortabfrage** möglich sein.

## 3. Ansible installieren und konfigurieren

### Ansible auf dem Control Node installieren
Installieren Sie Ansible mit den folgenden Befehlen:
````bash
sudo apt update
sudo apt install ansible -y
````
### Inventar-Datei erstellen
Legen Sie eine Inventar-Datei an, z. B. ````/etc/ansible/hosts````, und tragen Sie Ihre Server ein:
````yaml
ubuntu_servers:
  hosts:
    sv1:
      ansible_host: 192.168.100.250
      ansible_user: meisterkurs
      ansible_become: true
      ansible_become_method: sudo
      ansible_become_password: passw0rd#
````
### Verbindung testen

````bash
ansible -m ping all
````

> Erwartete Ausgabe:
````json
"sv1": {
  "ping": "pong"
}
````

## 4. System-Updates mit Ansible durchführen
### Playbook: 01-playbook-update_system.yml 
Erstellen Sie eine Datei namens 01-playbook-update_system.yml mit folgendem Inhalt:
````yaml
---
- name: Ubuntu Updates
  hosts: ubuntu_servers # Zielgruppe: Alle Ubuntu-Server im Inventar
  become: yes # Root-Rechte für Paketverwaltung
  tasks:
    - name: System-Paketlisten aktualisieren
      apt:
        update_cache: yes
      # Aktualisiert die Paketlisten, um die neuesten Versionen zu erhalten

    - name: Alle Pakete auf den neuesten Stand bringen
      apt:
        upgrade: dist # Führt ein Distribution-Upgrade durch
        autoremove: yes # Entfernt nicht mehr benötigte Pakete
      # Installiert alle verfügbaren Updates und bereinigt das System

    - name: Überprüfen, ob ein Neustart erforderlich ist
      stat:
        path: /var/run/reboot-required
      register: reboot_required
      # Prüft, ob ein Neustart nach den Updates erforderlich ist
    
    - name: Hinweis auf Neustart ausgeben (falls erforderlich)
      debug:
        msg: "Ein Neustart des Servers {{ inventory_hostname }} ist erforderlich!"
      when: reboot_required.stat.exists
      # Zeigt eine Warnung an, wenn ein Neustart erforderlich ist
  
````

Führen Sie das Playbook aus:
````bash
ansible-playbook 01-playbook-update_system.yml
````

## 5. Programm installieren und konfigurieren (Beispiel: Nginx)

### Playbook: 02-playbook-install-nginx.yaml

Erstellen Sie Datei 01-playbook-install.nginx.yaml

````yaml
---
- name: Installiere nginx auf einstellbarem Port
  hosts: ubuntu_servers
  become: yes
  vars:
    nginx_port: 5000 # Port, auf dem Nginx laufen soll
    example_page_content: |
      <!DOCTYPE html>
      <html>
        <head>
          <title>Nginx auf Port 5000</title>
          <style>
            body { font-family: Arial, sans-serif; text-align: center; margin-top: 50px; }
            h1 { color: #0078d7; }
          </style>
        </head>
        <body>
          <h1>Willkommen auf der Nginx-Beispielseite!</h1>
          <p>Diese Seite wird auf <strong>Port {{ nginx_port }}</strong> bereitgestellt.</p>
          <p>Ansible-Playbook erfolgreich ausgeführt!</p>
        </body>
      </html>

  tasks:
    - name: Nginx installieren
      apt:
        name: nginx
        state: present
    # Installiert Nginx, falls nicht bereits vorhanden

    - name: Nginx-Konfiguration für Port 5000 anpassen
      template:
        src: nginx.conf.j2 # Template-Datei für die Nginx-Konfiguration
        dest: /etc/nginx/sites-available/default
      notify: Nginx neu starten
    # Ersetzt die Standardkonfiguration von Nginx durch unsere angepasste Version

    - name: Beispiel-HTML-Seite bereitstellen
      copy:
        dest: /var/www/nginx/index.html
        content: "{{ example_page_content }}"
      notify: Nginx neu starten
    # Kopiert die Beispiel-HTML-Seite in das Webverzeichnis von Nginx

    - name: Nginx-Dienst starten und aktivieren
      service:
        name: nginx
        state: started
        enabled: yes
    # Startet Nginx und aktiviert den Autostart beim Systemstart

    - name: Firewall für Port 5000 öffnen (falls UFW aktiv)
      ufw:
        rule: allow
        port: "{{ nginx_port }}"
        proto: tcp
      when: "'ufw' in ansible_facts.packages"
    # Öffnet den Port 5000 in der Firewall, falls UFW installiert ist

    - name: Überprüfen, ob Nginx auf Port 5000 erreichbar ist
      uri:
        url: "http://localhost:{{ nginx_port }}"
        return_content: yes
      register: nginx_status
      until: nginx_status.status == 200
      retries: 5
      delay: 10
    # Prüft, ob Nginx auf dem konfigurierten Port erreichbar ist
    # - retries: 5: Wiederholt die Prüfung 5 Mal, falls der Port noch nicht erreichbar ist
    # - delay: 10: Wartezeit von 10 Sekunden zwischen den Versuchen

    - name: Statusmeldung ausgeben
      debug:
        msg: "Nginx ist erfolgreich auf Port {{ nginx_port }} gestartet und erreichbar unter http://{{ ansible_host }}:{{ nginx_port }}"
      # Zeigt eine Erfolgsmeldung mit der URL zur Beispielseite an


  handlers:
    - name: Nginx neu starten
      service:
        name: nginx
        state: restarted
    # Startet Nginx neu, um Änderungen an der Konfiguration zu übernehmen
````
#### Was sind Handler?
> Handler in Ansible sind spezielle Aufgaben, die nur dann ausgeführt werden, wenn sie von einer anderen Aufgabe explizit benachrichtigt (notify) werden. Sie werden typischerweise für Dienst-Neustarts oder Konfigurationsänderungen verwendet, die nur dann notwendig sind, wenn sich etwas geändert hat.


### Nginx-Konfigurationsdatei (nginx.conf.j2)

Im Script wird eine Kopierquelle für die konfiguration des Servers angegeben. Diese darf direkt daneben angelegt werden: ````nginx.conf.j2````

````nginx
server {
    listen {{ nginx_port }} default_server;
    listen [::]:{{ nginx_port }} default_server;

    root /var/www/nginx;
    index index.html;

    server_name _;

    location / {
        try_files $uri $uri/ =404;
    }
}
````


Ausführung des Playbooks:
````bash
ansible-playbook 01-playbook-install.nginx.yaml
````

### Nach der Installation: 
Öffnen Sie einen Browser und verbinden Sie sich mit port 5000
> Sie sollten die Beispielseite sehen.
Port-Überprüfung:
Das Playbook prüft automatisch, ob Nginx auf Port 5000 erreichbar ist, und gibt eine Erfolgsmeldung aus.

## 6. Playbook: Benutzer und Gruppen verwalten
````03-playbook-manage-users.yml````
````yaml
---
- name: Benutzer und Gruppen auf den Managed Nodes verwalten
  hosts: sv1
  become: yes

  vars:
    users:
      - name: dbecker
        groups: ["Geschäftsleitung"]
      - name: spoller
        groups: ["Projektleitung"]
    groups:
      - Geschäftsleitung
      - Projektleitung

  tasks:
    - name: Gruppen erstellen
      group:
        name: "{{ item }}"
        state: present
      loop: "{{ groups }}"
      # Erstellt die in der Variable "groups" definierten Gruppen

    - name: Benutzer erstellen
      user:
        name: "{{ item.name }}"
        groups: "{{ item.groups | join(',') }}"
        shell: /bin/bash
      loop: "{{ users }}"
      # Erstellt die in der Variable "users" definierten Benutzer
      # - groups: Fügt die Benutzer den angegebenen Gruppen hinzu
      # - shell: Setzt die Standard-Shell auf Bash
````

## 7. Playbook: Automatische Updates einrichten
````04-playbook-auto-update.yml````

````yaml
---
- name: Automatische Updates auf den Managed Nodes einrichten
  hosts: ubuntu_servers
  become: yes

  tasks:
    - name: unattended-upgrades installieren
      apt:
        name: unattended-upgrades
        state: present
      # Installiert das Paket für automatische Updates

    - name: Automatische Updates aktivieren
      copy:
        dest: /etc/apt/apt.conf.d/20auto-upgrades
        content: |
          APT::Periodic::Update-Package-Lists "1";
          APT::Periodic::Unattended-Upgrade "1";
      # Konfiguriert die automatische Aktualisierung der Paketlisten und Installation von Updates
````
## 8. Zusammenfassung
Was wurde erreicht?

* SSH-Key-Authentifizierung für sichere Ansible-Kommunikation.
* Automatisierte System-Updates und Programm-Installation.
* Benutzer- und Gruppenverwaltung.
* Automatische Sicherheitsupdates.
