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:
- 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
- Strukturieren Sie Ihr Projekt gemaess den offiziellen Empfehlungen:
project/
inventory/
production/
staging/
group_vars/
host_vars/
roles/
playbooks/
ansible.cfg
requirements.yml
- Testen Sie Playbooks mit Molecule und ansible-lint:
pip install molecule ansible-lint
ansible-lint site.yml
molecule test
- Verwenden Sie Tags fuer die selektive Ausfuehrung von Tasks:
- name: Nginx installieren
apt:
name: nginx
state: present
tags: [nginx, install]
-
Verwenden Sie Umgebungsvariablen anstelle von fest codierten Werten.
-
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!
Team von Programmierexperten, die sich auf moderne Webtechnologien spezialisiert haben.