Zum Hauptinhalt springen
Zurück zur Kategorie

Server-Automatisierung mit Ansible: Infrastructure as Code

Ansible-Installation, Inventory-Datei, Playbook-Erstellung, Rollenstruktur, Variablen, verschlüsselter Vault, Ad-hoc-Befehle und Server-Konfigurationsautomatisierung. Schritt-für-Schritt-Anleitung.

Lesezeit: 20 Min DevOps & Automatisierung
ansibleautomatisierunginfrastructure as codedevopsplaybookyamllinux

Inhaltsverzeichnis

Server-Automatisierung mit Ansible: Infrastructure as Code

Ansible ist ein Open-Source-Tool, mit dem Sie Server-Konfiguration, Anwendungsbereitstellung und Aufgabenautomatisierung als Code verwalten können. Dank seiner agentenlosen Architektur verbindet es sich nur über SSH mit Zielservern.

Was ist Ansible?

Hauptmerkmale von Ansible:

  • Agentenlos: Keine zusätzliche Software-Installation auf Zielservern erforderlich
  • Idempotent: Das mehrfache Ausführen desselben Playbooks liefert dasselbe Ergebnis
  • YAML-basiert: Einfach zu lesen und zu schreiben
  • Große Modulbibliothek: 3000+ fertige Module

Ansible verbindet sich vom Control Node über SSH mit Zielservern. Für Windows-Server wird WinRM verwendet.

Ansible-Installation

Ubuntu/Debian

hljs bash
# PPA-Repository hinzufügen
sudo apt update
sudo apt install software-properties-common -y
sudo add-apt-repository --yes --update ppa:ansible/ansible
sudo apt install ansible -y

# Version prüfen
ansible --version

RHEL/CentOS/AlmaLinux

hljs bash
# EPEL-Repository hinzufügen
sudo dnf install epel-release -y
sudo dnf install ansible -y

# Alternative: über pip installieren
pip3 install ansible

Installation über pip (Empfohlen)

hljs bash
# Python-Virtual-Environment erstellen
python3 -m venv ansible-env
source ansible-env/bin/activate

# Ansible und zusätzliche Tools installieren
pip install ansible ansible-lint

# Version prüfen
ansible --version

Inventory-Datei

Inventory definiert die Server, die Ansible verwalten soll:

INI-Format

hljs ini
# /etc/ansible/hosts oder benutzerdefinierte Inventory-Datei

# Einzelner Server
web1.example.com

# Gruppendefinition
[webservers]
web1.example.com
web2.example.com ansible_port=2222
192.168.1.10 ansible_user=ubuntu

[databases]
db1.example.com
db2.example.com

# Gruppenvariablen
[webservers:vars]
ansible_user=deploy
ansible_python_interpreter=/usr/bin/python3

# Übergeordnete Gruppe
[production:children]
webservers
databases

YAML-Format

hljs yaml
# inventory.yml
all:
  children:
    webservers:
      hosts:
        web1.example.com:
          ansible_port: 22
        web2.example.com:
          ansible_port: 2222
      vars:
        ansible_user: deploy
        http_port: 80

    databases:
      hosts:
        db1.example.com:
        db2.example.com:
      vars:
        ansible_user: dbadmin
        db_port: 5432

Ad-hoc-Befehle

Führen Sie Befehle ohne Playbook für schnelle Aufgaben aus:

hljs bash
# Ping-Test
ansible all -m ping
ansible webservers -m ping -i inventory.yml

# Befehl ausführen
ansible all -m command -a "uptime"
ansible webservers -m shell -a "df -h"

# Datei kopieren
ansible webservers -m copy -a "src=/local/file dest=/remote/path"

# Paket installieren
ansible webservers -m apt -a "name=nginx state=present" --become

# Dienst verwalten
ansible webservers -m service -a "name=nginx state=started enabled=yes" --become

# Datei erstellen/löschen
ansible all -m file -a "path=/tmp/test state=touch"
ansible all -m file -a "path=/tmp/test state=absent"

# Facts sammeln
ansible web1.example.com -m setup
ansible all -m setup -a "filter=ansible_os_family"

Playbooks schreiben

Grundlegende Playbook-Struktur

hljs yaml
# site.yml
---
- name: Webserver konfigurieren
  hosts: webservers
  become: yes  # sudo verwenden
  vars:
    http_port: 80
    max_clients: 200

  tasks:
    - name: Nginx installieren
      apt:
        name: nginx
        state: present
        update_cache: yes

    - name: Nginx-Konfiguration kopieren
      template:
        src: templates/nginx.conf.j2
        dest: /etc/nginx/nginx.conf
        owner: root
        group: root
        mode: '0644'
      notify: Nginx neu starten

    - name: Nginx-Dienst starten
      service:
        name: nginx
        state: started
        enabled: yes

  handlers:
    - name: Nginx neu starten
      service:
        name: nginx
        state: restarted

Tasks, Handlers und Roles

hljs yaml
# Bedingte Tasks
- name: Paket auf Ubuntu installieren
  apt:
    name: "{{ item }}"
    state: present
  loop:
    - nginx
    - curl
    - git
  when: ansible_os_family == "Debian"

- name: Paket auf RHEL installieren
  dnf:
    name: "{{ item }}"
    state: present
  loop:
    - nginx
    - curl
    - git
  when: ansible_os_family == "RedHat"

# Benutzer mit Schleife erstellen
- name: Benutzer erstellen
  user:
    name: "{{ item.name }}"
    groups: "{{ item.groups }}"
    state: present
  loop:
    - { name: 'alice', groups: 'sudo' }
    - { name: 'bob', groups: 'www-data' }

# Registrieren und Bedingung
- name: Nginx-Version prüfen
  command: nginx -v
  register: nginx_version
  ignore_errors: yes

- name: Nginx installieren wenn nicht vorhanden
  apt:
    name: nginx
    state: present
  when: nginx_version.rc != 0

Variablen und Facts

hljs yaml
# group_vars/webservers.yml
http_port: 80
https_port: 443
app_user: www-data
app_dir: /var/www/html

# host_vars/web1.example.com.yml
ansible_host: 192.168.1.10
server_name: web1.example.com
hljs yaml
# Variablenverwendung im Playbook
- name: Anwendungsverzeichnis erstellen
  file:
    path: "{{ app_dir }}"
    state: directory
    owner: "{{ app_user }}"
    mode: '0755'

# Facts verwenden
- name: Systeminformationen anzeigen
  debug:
    msg: |
      OS: {{ ansible_distribution }} {{ ansible_distribution_version }}
      CPU: {{ ansible_processor_vcpus }} Kerne
      RAM: {{ ansible_memtotal_mb }} MB
      IP: {{ ansible_default_ipv4.address }}

Ansible Vault

Zum Verschlüsseln sensibler Daten:

hljs bash
# Verschlüsselte Datei erstellen
ansible-vault create secrets.yml

# Vorhandene Datei verschlüsseln
ansible-vault encrypt vars/passwords.yml

# Verschlüsselte Datei bearbeiten
ansible-vault edit secrets.yml

# Verschlüsselte Datei anzeigen
ansible-vault view secrets.yml

# Verschlüsselung entfernen
ansible-vault decrypt vars/passwords.yml

# Passwort ändern
ansible-vault rekey secrets.yml

# Playbook mit Vault ausführen
ansible-playbook site.yml --ask-vault-pass
ansible-playbook site.yml --vault-password-file ~/.vault_pass

Rollenstruktur

hljs bash
# Rolle erstellen
ansible-galaxy init roles/nginx

# Rollen-Verzeichnisstruktur
roles/nginx/
├── defaults/
│   └── main.yml      # Standardvariablen
├── files/
│   └── nginx.conf    # Statische Dateien
├── handlers/
│   └── main.yml      # Handler
├── meta/
│   └── main.yml      # Rollen-Metadaten
├── tasks/
│   └── main.yml      # Hauptaufgaben
├── templates/
│   └── vhost.conf.j2 # Jinja2-Templates
└── vars/
    └── main.yml      # Variablen

Beispiel-Playbooks

Nginx-Installations-Playbook

hljs yaml
---
- name: Nginx-Webserver-Installation
  hosts: webservers
  become: yes
  vars:
    domain: example.com
    web_root: /var/www/{{ domain }}

  tasks:
    - name: Nginx installieren
      apt:
        name: nginx
        state: present
        update_cache: yes

    - name: Web-Verzeichnis erstellen
      file:
        path: "{{ web_root }}"
        state: directory
        owner: www-data
        group: www-data
        mode: '0755'

    - name: Beispiel-index.html erstellen
      copy:
        content: "<h1>Hallo von {{ inventory_hostname }}</h1>"
        dest: "{{ web_root }}/index.html"
        owner: www-data

    - name: Virtual Host konfigurieren
      template:
        src: vhost.conf.j2
        dest: /etc/nginx/sites-available/{{ domain }}
      notify: Nginx neu laden

    - name: Virtual Host aktivieren
      file:
        src: /etc/nginx/sites-available/{{ domain }}
        dest: /etc/nginx/sites-enabled/{{ domain }}
        state: link
      notify: Nginx neu laden

    - name: Standard-Site deaktivieren
      file:
        path: /etc/nginx/sites-enabled/default
        state: absent
      notify: Nginx neu laden

    - name: UFW Nginx-Erlaubnis
      ufw:
        rule: allow
        name: 'Nginx Full'

  handlers:
    - name: Nginx neu laden
      service:
        name: nginx
        state: reloaded

Benutzerverwaltungs-Playbook

hljs yaml
---
- name: Benutzerverwaltung
  hosts: all
  become: yes
  vars_files:
    - vars/users.yml

  tasks:
    - name: Sudo-Gruppe erstellen
      group:
        name: sudo
        state: present

    - name: Benutzer erstellen
      user:
        name: "{{ item.username }}"
        comment: "{{ item.full_name }}"
        groups: "{{ item.groups | join(',') }}"
        shell: /bin/bash
        create_home: yes
        state: present
      loop: "{{ users }}"

    - name: SSH-Public-Key hinzufügen
      authorized_key:
        user: "{{ item.username }}"
        key: "{{ item.ssh_key }}"
        state: present
      loop: "{{ users }}"
      when: item.ssh_key is defined

    - name: Sudo-Berechtigung erteilen
      copy:
        content: "{{ item.username }} ALL=(ALL) NOPASSWD:ALL"
        dest: /etc/sudoers.d/{{ item.username }}
        mode: '0440'
      loop: "{{ users }}"
      when: item.sudo | default(false)

Playbooks ausführen

hljs bash
# Grundlegende Ausführung
ansible-playbook site.yml

# Mit spezifischem Inventory
ansible-playbook -i inventory.yml site.yml

# Spezifischer Host oder Gruppe
ansible-playbook site.yml --limit webservers
ansible-playbook site.yml --limit web1.example.com

# Dry-Run (Prüfung ohne Änderungen)
ansible-playbook site.yml --check

# Verbose-Modus
ansible-playbook site.yml -v
ansible-playbook site.yml -vvv

# Bestimmte Tags ausführen
ansible-playbook site.yml --tags "nginx,ssl"
ansible-playbook site.yml --skip-tags "debug"

# Zusätzliche Variablen
ansible-playbook site.yml -e "env=production version=1.5"

Fazit

Ansible ist einer der zugänglichsten Wege, Server-Automatisierung als Code zu verwalten. Mit seiner agentenlosen Architektur, der großen Modulbibliothek und der YAML-basierten Struktur können Sie sowohl kleine als auch große Infrastrukturen einfach verwalten. Halten Sie sensible Daten mit Vault sicher, während Sie mit Rollen wiederverwendbare Konfigurationen erstellen.