Ansible ist ein agentenloses Automatisierungstool für Konfigurationsmanagement, Deployment und Orchestrierung. Es nutzt SSH und YAML für einfache, lesbare Automatisierung.
Warum Ansible?
Vorteile
- Agentenlos (nur SSH)
- YAML-basierte Konfiguration
- Idempotent
- Push-basiert
- Große Modul-Bibliothek
- Einfache Lernkurve
- Aktive CommunityAnsible vs andere Tools
| Tool | Agent | Sprache | Push/Pull | |------|-------|---------|-----------| | Ansible | Nein | Python/YAML | Push | | Puppet | Ja | Ruby/DSL | Pull | | Chef | Ja | Ruby | Pull | | Salt | Optional | Python | Beide |
Installation
Via pip (empfohlen)
pip install ansibleDebian/Ubuntu
apt install ansibleVersion prüfen
ansible --versionInventory
Einfaches Inventory
# /etc/ansible/hosts oder inventory.ini
[webserver]
web1.example.de
web2.example.de
[database]
db1.example.de
db2.example.de
[production:children]
webserver
databaseMit Variablen
[webserver]
web1.example.de ansible_user=deploy ansible_port=22
web2.example.de ansible_user=deploy
[webserver:vars]
http_port=80
max_clients=200
[all:vars]
ansible_python_interpreter=/usr/bin/python3YAML-Format
# inventory.yml
all:
children:
webserver:
hosts:
web1.example.de:
web2.example.de:
vars:
http_port: 80
database:
hosts:
db1.example.de:
ansible_user: postgres
db2.example.de:Dynamisches Inventory
# AWS
ansible-inventory -i aws_ec2.yml --list
# Plugins aktivieren
# ansible.cfg
[inventory]
enable_plugins = aws_ec2, azure_rmAd-hoc-Befehle
Grundlagen
# Ping alle Hosts
ansible all -m ping
# Befehl ausführen
ansible webserver -m shell -a "uptime"
# Datei kopieren
ansible webserver -m copy -a "src=/local/file dest=/remote/file"
# Paket installieren
ansible webserver -m apt -a "name=nginx state=present" -b
# Service starten
ansible webserver -m service -a "name=nginx state=started" -bOptionen
| Option | Beschreibung | |--------|--------------| | -i | Inventory-Datei | | -m | Modul | | -a | Argumente | | -b | Become (sudo) | | -u | Benutzer | | -k | Passwort-Prompt | | -K | Sudo-Passwort |
Playbooks
Erstes Playbook
# site.yml
---
- name: Webserver konfigurieren
hosts: webserver
become: yes
tasks:
- name: Nginx installieren
apt:
name: nginx
state: present
update_cache: yes
- name: Nginx starten
service:
name: nginx
state: started
enabled: yes
- name: Konfiguration kopieren
template:
src: templates/nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: Reload Nginx
handlers:
- name: Reload Nginx
service:
name: nginx
state: reloadedAusführen
ansible-playbook -i inventory.ini site.ymlMit Optionen
# Check-Modus (Dry-Run)
ansible-playbook site.yml --check
# Verbose
ansible-playbook site.yml -v
ansible-playbook site.yml -vvv
# Limit auf Hosts
ansible-playbook site.yml --limit web1.example.de
# Tags
ansible-playbook site.yml --tags "nginx,config"
# Extra-Variablen
ansible-playbook site.yml -e "version=1.0.0"Variablen
Im Playbook
- hosts: webserver
vars:
http_port: 80
app_name: myapp
tasks:
- name: Template deployen
template:
src: config.j2
dest: "/etc/{{ app_name }}/config.conf"Group Variables
# group_vars/webserver.yml
http_port: 80
max_clients: 200
ssl_enabled: trueHost Variables
# host_vars/web1.example.de.yml
http_port: 8080
custom_setting: trueVariablen-Hierarchie
1. Extra vars (-e)
2. Task vars
3. Block vars
4. Role vars
5. Play vars
6. Host facts
7. Host vars
8. Group vars
9. Inventory vars
10. Role defaultsTemplates (Jinja2)
Template-Datei
# templates/nginx.conf.j2
server {
listen {{ http_port }};
server_name {{ ansible_hostname }};
{% if ssl_enabled %}
listen 443 ssl;
ssl_certificate /etc/ssl/{{ domain }}.crt;
ssl_certificate_key /etc/ssl/{{ domain }}.key;
{% endif %}
location / {
root /var/www/{{ app_name }};
index index.html;
}
{% for backend in backends %}
upstream {{ backend.name }} {
server {{ backend.host }}:{{ backend.port }};
}
{% endfor %}
}Im Playbook
- name: Nginx-Konfiguration
template:
src: templates/nginx.conf.j2
dest: /etc/nginx/sites-available/default
owner: root
group: root
mode: '0644'Conditionals und Loops
When (Bedingungen)
tasks:
- name: Nur auf Debian
apt:
name: nginx
when: ansible_os_family == "Debian"
- name: Nur auf RedHat
yum:
name: nginx
when: ansible_os_family == "RedHat"
- name: Wenn Variable gesetzt
debug:
msg: "SSL ist aktiviert"
when: ssl_enabled | boolLoops
tasks:
- name: Mehrere Pakete installieren
apt:
name: "{{ item }}"
state: present
loop:
- nginx
- php-fpm
- php-mysql
- name: Benutzer anlegen
user:
name: "{{ item.name }}"
groups: "{{ item.groups }}"
loop:
- { name: 'deploy', groups: 'www-data' }
- { name: 'backup', groups: 'root' }Rollen
Struktur erstellen
ansible-galaxy init roles/webserver
roles/webserver/
├── defaults/
│ └── main.yml
├── files/
├── handlers/
│ └── main.yml
├── meta/
│ └── main.yml
├── tasks/
│ └── main.yml
├── templates/
├── tests/
└── vars/
└── main.ymlRolle verwenden
# site.yml
- hosts: webserver
roles:
- common
- webserver
- { role: database, when: db_server | bool }Roles von Galaxy
# Rolle installieren
ansible-galaxy install geerlingguy.docker
# requirements.yml
- src: geerlingguy.docker
version: 6.1.0
ansible-galaxy install -r requirements.ymlWichtige Module
Dateien
# Kopieren
- copy:
src: file.txt
dest: /path/file.txt
owner: root
mode: '0644'
# Template
- template:
src: config.j2
dest: /etc/app/config.conf
# Datei erstellen
- file:
path: /var/log/app
state: directory
mode: '0755'
# Zeile in Datei
- lineinfile:
path: /etc/hosts
line: "192.168.1.1 server.local"Pakete
# apt
- apt:
name: nginx
state: present
update_cache: yes
# yum/dnf
- dnf:
name: httpd
state: present
# pip
- pip:
name: django
version: 4.0Services
- service:
name: nginx
state: started
enabled: yes
- systemd:
name: myapp
state: restarted
daemon_reload: yesBenutzer
- user:
name: deploy
groups: www-data
shell: /bin/bash
generate_ssh_key: yesShell/Command
# Befehl
- command: /opt/script.sh
# Shell (für Pipes, Redirects)
- shell: cat /etc/passwd | grep deploy
# Mit Bedingung
- command: /opt/install.sh
args:
creates: /opt/installed.flagHandlers
tasks:
- name: Nginx-Config ändern
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify:
- Reload Nginx
- Check Config
handlers:
- name: Check Config
command: nginx -t
listen: "Check Config"
- name: Reload Nginx
service:
name: nginx
state: reloaded
listen: "Reload Nginx"Vault (Secrets)
Datei verschlüsseln
# Erstellen
ansible-vault create secrets.yml
# Bearbeiten
ansible-vault edit secrets.yml
# Verschlüsseln
ansible-vault encrypt vars.yml
# Entschlüsseln
ansible-vault decrypt vars.ymlPlaybook mit Vault
ansible-playbook site.yml --ask-vault-pass
# Oder mit Passwort-Datei
ansible-playbook site.yml --vault-password-file ~/.vault_passVariablen im Vault
# secrets.yml (verschlüsselt)
db_password: geheim123
api_key: abc123xyz# Playbook
- hosts: database
vars_files:
- secrets.yml
tasks:
- name: DB-Passwort setzen
mysql_user:
name: app
password: "{{ db_password }}"ansible.cfg
# ansible.cfg
[defaults]
inventory = inventory.ini
remote_user = deploy
private_key_file = ~/.ssh/deploy_key
host_key_checking = False
retry_files_enabled = False
gathering = smart
fact_caching = jsonfile
fact_caching_connection = /tmp/ansible_facts
[privilege_escalation]
become = True
become_method = sudo
become_user = root
become_ask_pass = FalseZusammenfassung
| Befehl | Funktion | |--------|----------| | ansible all -m ping | Connectivity-Test | | ansible-playbook site.yml | Playbook ausführen | | ansible-galaxy init | Rolle erstellen | | ansible-vault encrypt | Datei verschlüsseln |
| Verzeichnis | Inhalt | |-------------|--------| | group_vars/ | Gruppen-Variablen | | host_vars/ | Host-Variablen | | roles/ | Rollen | | templates/ | Jinja2-Templates |
| Modul | Funktion | |-------|----------| | apt/yum | Paketmanagement | | copy/template | Dateien | | service/systemd | Dienste | | user/group | Benutzer | | file/lineinfile | Dateisystem |
Fazit
Ansible ist das ideale Tool für Server-Automatisierung ohne komplexe Infrastruktur. Die agentenlose Architektur macht den Einstieg einfach. YAML-basierte Playbooks sind lesbar und versionierbar. Mit Rollen lässt sich wiederverwendbarer Code erstellen. Vault schützt sensible Daten. Für Infrastructure as Code ist Ansible eine hervorragende Wahl.