Przejdź do treści
DevOps

Ansible - Automatisierung der Serverkonfiguration

Veröffentlicht am:
·6 Min. Lesezeit·Autor: MDS Software Solutions Group
Ansible - Automatisierung der Serverkonfiguration

Ansible - Automatisierung der Serverkonfiguration

Die manuelle Verwaltung von Serverinfrastruktur ist eine Sackgasse. Jeder Administrator, der jemals Dutzende von Servern konfiguriert hat, weiss, dass sich wiederholende Aufgaben enorm viel Zeit verschlingen und fehleranfaellig sind. Ansible, entwickelt von Michael DeHaan und derzeit von Red Hat weiterentwickelt, loest dieses Problem auf elegante und unkomplizierte Weise. In diesem Leitfaden behandeln wir alles, was Sie wissen muessen, um Serverkonfigurationen mit Ansible effektiv zu automatisieren.

Was ist Ansible?#

Ansible ist ein Open-Source-IT-Automatisierungswerkzeug, das Konfigurationsmanagement, Anwendungsbereitstellung und Infrastruktur-Orchestrierung ermoeglicht. Im Gegensatz zu vielen anderen Tools zeichnet sich Ansible durch seine Einfachheit aus - es verwendet YAML zur Definition von Aufgaben, wodurch Playbooks auch fuer Personen ohne Programmiererfahrung lesbar sind.

Die wichtigsten Anwendungsfaelle fuer Ansible umfassen:

  • Konfigurationsmanagement - Installation von Paketen, Konfiguration von Diensten, Verwaltung von Dateien
  • Anwendungsbereitstellung - automatisierte Deployments auf mehreren Servern gleichzeitig
  • Orchestrierung - Koordination komplexer mehrstufiger Prozesse
  • Provisionierung - Vorbereitung neuer Server von Grund auf
  • Sicherheit und Compliance - Durchsetzung von Sicherheitsrichtlinien

Agentenlose Architektur (Agentless)#

Eines der wichtigsten Unterscheidungsmerkmale von Ansible ist seine agentenlose Architektur. Das bedeutet, dass auf den verwalteten Servern keine zusaetzliche Software installiert werden muss. Ansible kommuniziert mit den Zielmaschinen ausschliesslich ueber SSH (fuer Linux/Unix-Systeme) oder WinRM (fuer Windows-Systeme).

Diese Architektur bringt viele Vorteile mit sich:

  • Kein Overhead - keine Agenten, die Ressourcen auf den Zielservern verbrauchen
  • Kein zusaetzlicher Wartungsaufwand - keine Notwendigkeit, Agenten auf Hunderten von Maschinen zu aktualisieren
  • Sicherheit - kleinere Angriffsflaeche, keine offenen Ports fuer Agenten
  • Einfacher Einstieg - nur SSH und Python auf den Zielmaschinen erforderlich
# Anforderungen auf den Zielmaschinen:
# - SSH-Server (OpenSSH)
# - Python 3.x
# - Benutzer mit sudo-Berechtigungen (optional)

Auf der Steuerungsmaschine (von der aus wir Ansible ausfuehren) muessen wir lediglich Ansible selbst installieren:

# Installation auf Ubuntu/Debian
sudo apt update
sudo apt install ansible

# Installation ueber pip
pip install ansible

# Installation auf CentOS/RHEL
sudo dnf install ansible-core

# Installation ueberpruefen
ansible --version

Inventar-Dateien (Inventory)#

Das Inventar ist eine Datei, die Hosts und Hostgruppen definiert, auf denen Ansible Aufgaben ausfuehren wird. Standardmaessig sucht Ansible nach der Datei /etc/ansible/hosts, aber Sie koennen mit dem Flag -i jede beliebige Datei angeben.

# inventory.ini - INI-Format

[webservers]
web1.example.com
web2.example.com
web3.example.com ansible_port=2222

[dbservers]
db1.example.com ansible_user=dbadmin
db2.example.com

[loadbalancers]
lb1.example.com

[production:children]
webservers
dbservers
loadbalancers

[webservers:vars]
http_port=80
max_clients=200

Das Inventar kann auch im YAML-Format definiert werden, was mehr Flexibilitaet bietet:

# inventory.yml - YAML-Format
all:
  children:
    webservers:
      hosts:
        web1.example.com:
          http_port: 80
        web2.example.com:
          http_port: 8080
      vars:
        ansible_user: deploy
        nginx_version: "1.24"
    dbservers:
      hosts:
        db1.example.com:
          postgresql_version: "16"
        db2.example.com:
          postgresql_version: "16"
      vars:
        ansible_user: dbadmin
    production:
      children:
        webservers:
        dbservers:

Playbooks und Aufgaben (Tasks)#

Playbooks sind das Herzsstueck von Ansible. Es sind YAML-Dateien, die eine Reihe von Aufgaben definieren, die auf bestimmten Hostgruppen ausgefuehrt werden sollen. Jedes Playbook besteht aus einem oder mehreren "Plays", und jeder Play enthaelt eine Liste von Tasks.

# site.yml - Beispiel-Playbook
---
- name: Webserver konfigurieren
  hosts: webservers
  become: yes
  vars:
    app_name: meineanwendung
    app_port: 8080

  tasks:
    - name: Apt-Cache aktualisieren
      apt:
        update_cache: yes
        cache_valid_time: 3600

    - name: Erforderliche Pakete installieren
      apt:
        name:
          - nginx
          - curl
          - git
          - ufw
        state: present

    - name: Nginx starten und aktivieren
      service:
        name: nginx
        state: started
        enabled: yes

    - name: HTTP in der Firewall erlauben
      ufw:
        rule: allow
        port: "80"
        proto: tcp

    - name: HTTPS in der Firewall erlauben
      ufw:
        rule: allow
        port: "443"
        proto: tcp

Ausfuehrung eines Playbooks:

# Grundlegende Ausfuehrung
ansible-playbook -i inventory.ini site.yml

# Mit sudo-Passwortabfrage
ansible-playbook -i inventory.ini site.yml --ask-become-pass

# Trockenlauf (Pruefung ohne Aenderungen)
ansible-playbook -i inventory.ini site.yml --check

# Beschraenkung auf einen bestimmten Host
ansible-playbook -i inventory.ini site.yml --limit web1.example.com

# Mit erhoehter Ausfuehrlichkeit
ansible-playbook -i inventory.ini site.yml -vvv

Ansible-Module#

Module sind die Arbeitseinheiten in Ansible. Jedes Modul fuehrt eine bestimmte Aufgabe aus. Ansible wird mit Hunderten von integrierten Modulen ausgeliefert. Hier sind die am haeufigsten verwendeten:

apt/yum-Modul - Paketverwaltung#

# Fuer Debian/Ubuntu-Systeme
- name: Mehrere Pakete installieren
  apt:
    name:
      - nginx
      - postgresql
      - python3-pip
      - certbot
    state: present
    update_cache: yes

# Fuer CentOS/RHEL-Systeme
- name: Pakete auf CentOS installieren
  yum:
    name:
      - httpd
      - mariadb-server
      - php
    state: latest

# Ein Paket entfernen
- name: Apache-Paket entfernen
  apt:
    name: apache2
    state: absent
    purge: yes

copy-Modul - Dateien kopieren#

- name: Konfigurationsdatei kopieren
  copy:
    src: files/nginx.conf
    dest: /etc/nginx/nginx.conf
    owner: root
    group: root
    mode: "0644"
    backup: yes

- name: Datei mit Inline-Inhalt erstellen
  copy:
    content: |
      # Anwendungskonfiguration
      APP_ENV=production
      APP_DEBUG=false
      APP_PORT=8080
    dest: /etc/myapp/.env
    owner: www-data
    group: www-data
    mode: "0600"

template-Modul - Jinja2-Templates#

- name: Nginx-Konfiguration aus Template bereitstellen
  template:
    src: templates/nginx-vhost.conf.j2
    dest: "/etc/nginx/sites-available/{{ app_name }}"
    owner: root
    group: root
    mode: "0644"
  notify: Nginx neustarten

service-Modul - Dienstverwaltung#

- name: PostgreSQL neustarten und aktivieren
  service:
    name: postgresql
    state: restarted
    enabled: yes

- name: Apache stoppen (falls installiert)
  service:
    name: apache2
    state: stopped
    enabled: no
  ignore_errors: yes

Variablen und Jinja2-Templates#

Das Jinja2-Templatesystem ist ein fundamentales Element von Ansible. Es ermoeglicht die dynamische Generierung von Konfigurationsdateien basierend auf Variablen.

# group_vars/webservers.yml
---
nginx_worker_processes: auto
nginx_worker_connections: 1024
server_name: "{{ inventory_hostname }}"
app_root: /var/www/{{ app_name }}
php_version: "8.3"
php_memory_limit: "256M"
php_max_execution_time: 30
ssl_enabled: true
ssl_certificate: "/etc/letsencrypt/live/{{ server_name }}/fullchain.pem"
ssl_certificate_key: "/etc/letsencrypt/live/{{ server_name }}/privkey.pem"

Beispiel eines Jinja2-Templates fuer die Nginx-Konfiguration:

{# templates/nginx-vhost.conf.j2 #}
server {
    listen 80;
    server_name {{ server_name }};

{% if ssl_enabled %}
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name {{ server_name }};

    ssl_certificate {{ ssl_certificate }};
    ssl_certificate_key {{ ssl_certificate_key }};
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
{% endif %}

    root {{ app_root }}/public;
    index index.php index.html;

    access_log /var/log/nginx/{{ app_name }}_access.log;
    error_log /var/log/nginx/{{ app_name }}_error.log;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php{{ php_version }}-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2)$ {
        expires 30d;
        add_header Cache-Control "public, immutable";
    }
}

Jinja2 bietet auch erweiterte Konstrukte:

{# Schleifen und Bedingungen in Templates #}
{% for upstream_server in upstream_servers %}
    server {{ upstream_server }}:{{ app_port }} weight=1;
{% endfor %}

{% if environment == 'production' %}
    error_page 500 502 503 504 /50x.html;
{% else %}
    # In der Entwicklungsumgebung detaillierte Fehler anzeigen
{% endif %}

Handler#

Handler sind spezielle Tasks, die nur ausgefuehrt werden, wenn sie durch eine notify-Direktive ausgeloest werden. Sie sind ideal zum Neustarten von Diensten nach Konfigurationsaenderungen:

---
- name: Nginx konfigurieren
  hosts: webservers
  become: yes

  tasks:
    - name: Nginx-Konfiguration bereitstellen
      template:
        src: templates/nginx.conf.j2
        dest: /etc/nginx/nginx.conf
      notify:
        - Nginx-Konfiguration validieren
        - Nginx neustarten

    - name: PHP-FPM-Konfiguration bereitstellen
      template:
        src: templates/php-fpm.conf.j2
        dest: "/etc/php/{{ php_version }}/fpm/pool.d/www.conf"
      notify: PHP-FPM neustarten

  handlers:
    - name: Nginx-Konfiguration validieren
      command: nginx -t
      changed_when: false

    - name: Nginx neustarten
      service:
        name: nginx
        state: restarted

    - name: PHP-FPM neustarten
      service:
        name: "php{{ php_version }}-fpm"
        state: restarted

Eine wichtige Eigenschaft von Handlern ist, dass sie nur einmal am Ende eines Plays ausgefuehrt werden, selbst wenn sie mehrfach ausgeloest werden. Dies stellt sicher, dass ein Dienst nicht unnoetigerweise mehrfach neu gestartet wird.

Rollen und Ansible Galaxy#

Rollen sind eine Moeglichkeit, Ansible-Code zu organisieren und wiederzuverwenden. Eine Rolle gruppiert Tasks, Handler, Variablen, Templates und Dateien in einer strukturierten Weise.

# Rollenstruktur
roles/
  webserver/
    tasks/
      main.yml
    handlers/
      main.yml
    templates/
      nginx-vhost.conf.j2
    files/
      ssl-params.conf
    vars/
      main.yml
    defaults/
      main.yml
    meta/
      main.yml
# roles/webserver/tasks/main.yml
---
- name: Nginx installieren
  apt:
    name: nginx
    state: present
    update_cache: yes

- name: PHP und Erweiterungen installieren
  apt:
    name:
      - "php{{ php_version }}-fpm"
      - "php{{ php_version }}-cli"
      - "php{{ php_version }}-pgsql"
      - "php{{ php_version }}-mbstring"
      - "php{{ php_version }}-xml"
      - "php{{ php_version }}-curl"
      - "php{{ php_version }}-zip"
    state: present

- name: Virtual Host konfigurieren
  template:
    src: nginx-vhost.conf.j2
    dest: "/etc/nginx/sites-available/{{ app_name }}"
  notify: Nginx neustarten

- name: Virtual Host aktivieren
  file:
    src: "/etc/nginx/sites-available/{{ app_name }}"
    dest: "/etc/nginx/sites-enabled/{{ app_name }}"
    state: link
  notify: Nginx neustarten

- name: Standardkonfiguration entfernen
  file:
    path: /etc/nginx/sites-enabled/default
    state: absent
  notify: Nginx neustarten
# roles/webserver/defaults/main.yml
---
php_version: "8.3"
app_name: myapp
app_port: 8080
nginx_worker_processes: auto
ssl_enabled: false

Ansible Galaxy ist ein Community-Repository fuer Rollen und Collections:

# Eine Rolle von Galaxy installieren
ansible-galaxy install geerlingguy.nginx
ansible-galaxy install geerlingguy.postgresql
ansible-galaxy install geerlingguy.php

# Rollen aus einer Requirements-Datei installieren
ansible-galaxy install -r requirements.yml

# Ein neues Rollengeruest erstellen
ansible-galaxy init meine_neue_rolle
# requirements.yml
---
roles:
  - name: geerlingguy.nginx
    version: "3.2.0"
  - name: geerlingguy.postgresql
    version: "3.4.0"
  - name: geerlingguy.php
    version: "6.0.0"
  - name: geerlingguy.certbot
    version: "4.1.0"

collections:
  - name: community.postgresql
    version: "3.2.0"
  - name: ansible.posix
    version: "1.5.0"

Verwendung von Rollen in einem Playbook:

# site.yml
---
- name: Webserver provisionieren
  hosts: webservers
  become: yes
  vars:
    app_name: produktion
    php_version: "8.3"

  roles:
    - role: geerlingguy.nginx
    - role: geerlingguy.php
      vars:
        php_packages:
          - "php{{ php_version }}-fpm"
          - "php{{ php_version }}-pgsql"
    - role: webserver

- name: Datenbank konfigurieren
  hosts: dbservers
  become: yes

  roles:
    - role: geerlingguy.postgresql
      vars:
        postgresql_version: "16"

Praktisches Beispiel - Provisionierung eines Nginx + PHP + PostgreSQL Servers#

Nachfolgend ein vollstaendiges Playbook zur Provisionierung eines Produktionsservers mit einem kompletten Technologie-Stack:

# provision-webserver.yml
---
- name: Produktionsserver provisionieren
  hosts: webservers
  become: yes
  vars:
    app_name: meineanwendung
    app_user: deploy
    app_root: "/var/www/{{ app_name }}"
    php_version: "8.3"
    node_version: "20"
    postgresql_version: "16"
    db_name: "{{ app_name }}_production"
    db_user: "{{ app_name }}_user"
    db_password: "{{ vault_db_password }}"
    server_name: app.example.com

  tasks:
    # === GRUNDKONFIGURATION ===
    - name: Systempakete aktualisieren
      apt:
        upgrade: dist
        update_cache: yes
        cache_valid_time: 3600

    - name: Grundlegende Pakete installieren
      apt:
        name:
          - curl
          - git
          - unzip
          - ufw
          - fail2ban
          - htop
          - supervisor
        state: present

    - name: Anwendungsbenutzer erstellen
      user:
        name: "{{ app_user }}"
        shell: /bin/bash
        groups: www-data
        append: yes
        create_home: yes

    # === FIREWALL ===
    - name: UFW konfigurieren - Standardrichtlinie
      ufw:
        direction: incoming
        policy: deny

    - name: UFW - SSH erlauben
      ufw:
        rule: allow
        port: "22"
        proto: tcp

    - name: UFW - HTTP/HTTPS erlauben
      ufw:
        rule: allow
        port: "{{ item }}"
        proto: tcp
      loop:
        - "80"
        - "443"

    - name: UFW aktivieren
      ufw:
        state: enabled

    # === NGINX ===
    - name: Nginx installieren
      apt:
        name: nginx
        state: present

    - name: Nginx-Konfiguration bereitstellen
      template:
        src: templates/nginx-vhost.conf.j2
        dest: "/etc/nginx/sites-available/{{ app_name }}"
      notify: Nginx neustarten

    - name: Seite aktivieren
      file:
        src: "/etc/nginx/sites-available/{{ app_name }}"
        dest: "/etc/nginx/sites-enabled/{{ app_name }}"
        state: link
      notify: Nginx neustarten

    # === PHP ===
    - name: PHP-Repository hinzufuegen
      apt_repository:
        repo: "ppa:ondrej/php"
        state: present

    - name: PHP und Erweiterungen installieren
      apt:
        name:
          - "php{{ php_version }}-fpm"
          - "php{{ php_version }}-cli"
          - "php{{ php_version }}-pgsql"
          - "php{{ php_version }}-mbstring"
          - "php{{ php_version }}-xml"
          - "php{{ php_version }}-curl"
          - "php{{ php_version }}-zip"
          - "php{{ php_version }}-gd"
          - "php{{ php_version }}-intl"
          - "php{{ php_version }}-redis"
        state: present
        update_cache: yes

    - name: PHP-FPM-Pool konfigurieren
      template:
        src: templates/php-fpm-pool.conf.j2
        dest: "/etc/php/{{ php_version }}/fpm/pool.d/{{ app_name }}.conf"
      notify: PHP-FPM neustarten

    # === POSTGRESQL ===
    - name: PostgreSQL installieren
      apt:
        name:
          - "postgresql-{{ postgresql_version }}"
          - "postgresql-client-{{ postgresql_version }}"
          - python3-psycopg2
        state: present

    - name: PostgreSQL starten
      service:
        name: postgresql
        state: started
        enabled: yes

    - name: Datenbank erstellen
      become_user: postgres
      community.postgresql.postgresql_db:
        name: "{{ db_name }}"
        encoding: UTF-8
        lc_collate: de_DE.UTF-8
        lc_ctype: de_DE.UTF-8

    - name: Datenbankbenutzer erstellen
      become_user: postgres
      community.postgresql.postgresql_user:
        name: "{{ db_user }}"
        password: "{{ db_password }}"
        db: "{{ db_name }}"
        priv: ALL
        state: present

    # === ANWENDUNGSVERZEICHNIS ===
    - name: Anwendungsverzeichnis erstellen
      file:
        path: "{{ app_root }}"
        state: directory
        owner: "{{ app_user }}"
        group: www-data
        mode: "0755"

    - name: Speicherverzeichnisse erstellen
      file:
        path: "{{ app_root }}/{{ item }}"
        state: directory
        owner: "{{ app_user }}"
        group: www-data
        mode: "0775"
      loop:
        - storage
        - storage/logs
        - storage/cache
        - storage/uploads

    # === SSL (Certbot) ===
    - name: Certbot installieren
      apt:
        name:
          - certbot
          - python3-certbot-nginx
        state: present

    - name: SSL-Zertifikat erhalten
      command: >
        certbot certonly --nginx
        -d {{ server_name }}
        --non-interactive
        --agree-tos
        --email admin@example.com
      args:
        creates: "/etc/letsencrypt/live/{{ server_name }}/fullchain.pem"

  handlers:
    - name: Nginx neustarten
      service:
        name: nginx
        state: restarted

    - name: PHP-FPM neustarten
      service:
        name: "php{{ php_version }}-fpm"
        state: restarted

Anwendungsbereitstellung mit Ansible#

Ansible eignet sich hervorragend zur Automatisierung des Bereitstellungsprozesses (Deployment) von Anwendungen:

# deploy.yml
---
- name: Anwendung bereitstellen
  hosts: webservers
  become: yes
  become_user: deploy
  vars:
    app_name: meineanwendung
    app_root: /var/www/meineanwendung
    repo_url: "git@github.com:firma/meineanwendung.git"
    branch: main
    release_dir: "{{ app_root }}/releases/{{ ansible_date_time.epoch }}"
    shared_dir: "{{ app_root }}/shared"
    current_link: "{{ app_root }}/current"

  tasks:
    - name: Release-Verzeichnis erstellen
      file:
        path: "{{ release_dir }}"
        state: directory

    - name: Repository klonen
      git:
        repo: "{{ repo_url }}"
        dest: "{{ release_dir }}"
        version: "{{ branch }}"
        depth: 1
        accept_hostkey: yes

    - name: Composer-Abhaengigkeiten installieren
      composer:
        command: install
        working_dir: "{{ release_dir }}"
        no_dev: yes
        optimize_autoloader: yes

    - name: Gemeinsame Verzeichnisse verlinken
      file:
        src: "{{ shared_dir }}/{{ item }}"
        dest: "{{ release_dir }}/{{ item }}"
        state: link
        force: yes
      loop:
        - .env
        - storage
        - node_modules

    - name: Datenbankmigrationen ausfuehren
      command: php artisan migrate --force
      args:
        chdir: "{{ release_dir }}"

    - name: Frontend-Assets bauen
      command: npm run build
      args:
        chdir: "{{ release_dir }}"

    - name: Caches leeren und neu aufbauen
      command: "php artisan {{ item }}"
      args:
        chdir: "{{ release_dir }}"
      loop:
        - cache:clear
        - config:cache
        - route:cache
        - view:cache

    - name: Symlink auf neues Release umschalten
      file:
        src: "{{ release_dir }}"
        dest: "{{ current_link }}"
        state: link
        force: yes

    - name: PHP-FPM neustarten
      become_user: root
      service:
        name: "php8.3-fpm"
        state: restarted

    - name: Alte Releases bereinigen (letzte 5 behalten)
      shell: |
        ls -dt {{ app_root }}/releases/*/ | tail -n +6 | xargs rm -rf
      args:
        warn: false
      changed_when: false

Idempotenz - Eine Schluesseleigenschaft von Ansible#

Idempotenz bedeutet, dass das mehrfache Ausfuehren desselben Playbooks identische Ergebnisse liefert. Ansible prueft den aktuellen Zustand des Systems und fuehrt nur die Aenderungen durch, die notwendig sind:

# Dieser Task ist idempotent - wenn das Paket bereits installiert ist,
# wird Ansible keine Aktion durchfuehren
- name: Nginx installieren
  apt:
    name: nginx
    state: present
  # Ergebnis: "ok" wenn bereits installiert, "changed" wenn jetzt installiert

# Dieser Task ist NICHT idempotent - er wird immer ausgefuehrt
- name: Anwendung neustarten (schlechtes Beispiel)
  command: systemctl restart nginx
  # Ergebnis: immer "changed"

# Besserer Ansatz - idempotent
- name: Sicherstellen, dass Nginx laeuft
  service:
    name: nginx
    state: started
  # Ergebnis: "ok" wenn bereits laeuft, "changed" wenn jetzt gestartet

Dank der Idempotenz koennen Sie Playbooks sicher mehrfach ausfuehren, ohne sich um unerwuenschte Nebeneffekte sorgen zu muessen. Dies ist ein wesentlicher Unterschied zwischen Ansible und traditionellen Bash-Skripten.

Ansible vs Puppet vs Chef#

| Merkmal | Ansible | Puppet | Chef | |---------|---------|--------|------| | Architektur | Agentenlos (SSH) | Agent auf jedem Host | Agent auf jedem Host | | Konfigurationssprache | YAML | Puppet DSL | Ruby DSL | | Lernkurve | Flach | Mittel | Steil | | Idempotenz | Ja | Ja | Ja | | Push vs Pull | Push (Standard) | Pull | Pull | | Community | Sehr gross | Gross | Mittel | | Am besten fuer | Deployments und Orchestrierung | Konfigurationsmanagement | Komplexe Umgebungen |

Ansible gewinnt durch seine Einfachheit und niedrige Einstiegshuerde. Es erfordert kein Erlernen einer dedizierten Programmiersprache, und YAML-Playbooks sind fuer jedes Teammitglied lesbar. Puppet und Chef koennen in sehr grossen, statischen Umgebungen die bessere Wahl sein, wo das Pull-Modell besser geeignet ist.

Ansible Tower / AWX#

Ansible Tower (kommerziell) und AWX (Open-Source) sind webbasierte Plattformen zur Verwaltung von Ansible auf Organisationsebene:

# Beispiel Job-Template in Tower/AWX
# Definiert ueber API oder Weboberflaeche:
#
# - Name: "Deploy Production"
# - Playbook: deploy.yml
# - Inventory: Production
# - Credentials: SSH Key + Vault Password
# - Schedule: On-demand
# - Notifications: Slack #deployments
# - RBAC: Nur DevOps-Team

Die wichtigsten Tower/AWX-Funktionen:

  • Weboberflaeche - visuelle Verwaltung von Playbooks und Inventaren
  • Zugriffskontrolle (RBAC) - granulare Berechtigungen fuer Teams
  • Zeitplanung - automatische Playbook-Ausfuehrung nach Zeitplan
  • Benachrichtigungen - Integration mit Slack, E-Mail, Webhooks
  • REST-API - vollstaendige Automatisierung ueber die API
  • Audit-Trail - vollstaendiges Protokoll, wer was wann ausgefuehrt hat

CI/CD-Integration#

Ansible laesst sich nahtlos in gaengige CI/CD-Tools integrieren:

# .github/workflows/deploy.yml - GitHub Actions
name: Deploy to Production
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Ansible installieren
        run: pip install ansible

      - name: SSH-Schluessel konfigurieren
        run: |
          mkdir -p ~/.ssh
          echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
          chmod 600 ~/.ssh/id_rsa
          ssh-keyscan -H ${{ secrets.SERVER_IP }} >> ~/.ssh/known_hosts

      - name: Deploy-Playbook ausfuehren
        run: |
          ansible-playbook \
            -i "${{ secrets.SERVER_IP }}," \
            --user deploy \
            --extra-vars "branch=${{ github.sha }}" \
            deploy.yml
        env:
          ANSIBLE_HOST_KEY_CHECKING: "false"
# .gitlab-ci.yml - GitLab CI
stages:
  - test
  - deploy

deploy_production:
  stage: deploy
  image: python:3.11
  only:
    - main
  before_script:
    - pip install ansible
    - mkdir -p ~/.ssh
    - echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
    - chmod 600 ~/.ssh/id_rsa
  script:
    - ansible-playbook -i inventory/production deploy.yml
  environment:
    name: production
    url: https://app.example.com

Best Practices#

Zum Abschluss einige bewaehrte Praktiken fuer die Arbeit mit Ansible:

  1. Verwenden Sie Ansible Vault zum Speichern von Passwoertern und Geheimnissen:
ansible-vault create secrets.yml
ansible-vault edit secrets.yml
ansible-playbook site.yml --ask-vault-pass
  1. Strukturieren Sie Ihr Projekt gemaess den offiziellen Empfehlungen:
project/
  inventory/
    production/
    staging/
  group_vars/
  host_vars/
  roles/
  playbooks/
  ansible.cfg
  requirements.yml
  1. Testen Sie Playbooks mit Molecule und ansible-lint:
pip install molecule ansible-lint
ansible-lint site.yml
molecule test
  1. Verwenden Sie Tags fuer die selektive Ausfuehrung von Tasks:
- name: Nginx installieren
  apt:
    name: nginx
    state: present
  tags: [nginx, install]
  1. Verwenden Sie Umgebungsvariablen anstelle von fest codierten Werten.

  2. Schreiben Sie beschreibende Task-Namen - jeder Task sollte einen klaren, beschreibenden Namen haben.

Zusammenfassung#

Ansible ist ein unverzichtbares Werkzeug im Arsenal jedes DevOps-Teams. Dank seiner einfachen YAML-Syntax, der agentenlosen Architektur und der umfangreichen Modulbibliothek ermoeglicht es eine schnelle und zuverlaessige Infrastrukturautomatisierung. Ob Sie einen einzelnen Server oder Hunderte von Maschinen verwalten, Ansible hilft Ihnen, Zeit zu sparen und Fehler durch manuelle Konfiguration zu vermeiden.

Die wichtigsten Erkenntnisse:

  • Einfachheit - YAML ist fuer jeden lesbar
  • Agentenlos - keine zusaetzliche Software auf Servern
  • Idempotenz - sicheres mehrfaches Ausfuehren
  • Skalierbarkeit - von einem Server bis zu Tausenden von Maschinen
  • Community - riesige Bibliothek von Rollen und Collections in Galaxy

Brauchen Sie Hilfe bei der Infrastrukturautomatisierung?#

Bei MDS Software Solutions Group sind wir auf Infrastrukturautomatisierung und DevOps-Prozesse spezialisiert. Wir bieten:

  • Entwurf und Implementierung von Automatisierung mit Ansible
  • CI/CD-Pipeline-Konfiguration
  • Audit und Optimierung bestehender Infrastruktur
  • Cloud-Migration (Azure, AWS, GCP)
  • Schulungen zu Ansible und DevOps-Best-Practices
  • 24/7-Infrastruktur-Support und -Wartung

Kontaktieren Sie uns, um die Automatisierung Ihrer Infrastruktur zu besprechen!

Autor
MDS Software Solutions Group

Team von Programmierexperten, die sich auf moderne Webtechnologien spezialisiert haben.

Ansible - Automatisierung der Serverkonfiguration | MDS Software Solutions Group | MDS Software Solutions Group