Back to Blog
ansible automation best-practices

Ansible Roles: Wiederverwendbare Konfiguration

Playbooks werden schnell unübersichtlich. Roles sind die Lösung.

Was ist eine Role?

Eine Role ist ein wiederverwendbares Ansible-Paket:

  • Eigene Tasks
  • Eigene Templates
  • Eigene Variablen
  • Eigene Handler

Struktur einer Role

roles/
└── docker/
    ├── tasks/
    │   └── main.yml
    ├── handlers/
    │   └── main.yml
    ├── templates/
    │   └── daemon.json.j2
    ├── files/
    │   └── ...
    ├── vars/
    │   └── main.yml
    ├── defaults/
    │   └── main.yml
    └── meta/
        └── main.yml

Erste Role erstellen

mkdir -p roles/docker/{tasks,handlers,templates,defaults}

defaults/main.yml

Standard-Variablen (können überschrieben werden):

docker_users: []
docker_compose_version: "2.24.0"
docker_log_driver: "json-file"
docker_log_max_size: "10m"
docker_log_max_file: "3"

tasks/main.yml

Die eigentlichen Aufgaben:

---
- name: Install required packages
  apt:
    name:
      - curl
      - gnupg
    state: present
    update_cache: true

- name: Check if Docker is installed
  command: docker --version
  register: docker_check
  ignore_errors: true
  changed_when: false

- name: Install Docker
  shell: curl -fsSL https://get.docker.com | bash
  when: docker_check.rc != 0

- name: Configure Docker daemon
  template:
    src: daemon.json.j2
    dest: /etc/docker/daemon.json
    mode: '0644'
  notify: restart docker

- name: Add users to docker group
  user:
    name: "{{ item }}"
    groups: docker
    append: true
  loop: "{{ docker_users }}"
  when: docker_users | length > 0

- name: Ensure Docker is started
  systemd:
    name: docker
    state: started
    enabled: true

handlers/main.yml

Reaktionen auf Änderungen:

---
- name: restart docker
  systemd:
    name: docker
    state: restarted

templates/daemon.json.j2

Jinja2 Template:

{
  "log-driver": "{{ docker_log_driver }}",
  "log-opts": {
    "max-size": "{{ docker_log_max_size }}",
    "max-file": "{{ docker_log_max_file }}"
  }
}

Role nutzen

Im Playbook

---
- name: Setup webservers
  hosts: webservers
  become: true

  roles:
    - docker
    - nginx
    - certbot

Mit Variablen

- name: Setup webservers
  hosts: webservers
  become: true

  roles:
    - role: docker
      vars:
        docker_users:
          - deploy
          - daniel
        docker_log_max_size: "50m"

Mehrere Roles

Typischer Server-Setup:

- name: Full server setup
  hosts: all
  become: true

  roles:
    - common          # Basis-Pakete, User, SSH
    - security        # UFW, Fail2ban
    - docker          # Docker installieren
    - traefik         # Reverse Proxy
    - monitoring      # Node Exporter, Promtail

Role Dependencies

In meta/main.yml:

dependencies:
  - role: common
  - role: docker

Wenn du traefik role nutzt, werden common und docker automatisch vorher ausgeführt.

Ansible Galaxy

Community Roles nutzen:

# Role installieren
ansible-galaxy install geerlingguy.docker

# Requirements file
cat requirements.yml
---
roles:
  - name: geerlingguy.docker
  - name: geerlingguy.nginx

ansible-galaxy install -r requirements.yml

Meine Role-Struktur

ansible/
├── ansible.cfg
├── inventory/
├── group_vars/
├── playbooks/
│   ├── site.yml           # Alles
│   ├── webservers.yml     # Nur Webserver
│   └── databases.yml      # Nur DBs
├── roles/
│   ├── common/
│   ├── security/
│   ├── docker/
│   ├── nginx/
│   ├── postgres/
│   └── monitoring/
└── requirements.yml

playbooks/site.yml:

---
- import_playbook: webservers.yml
- import_playbook: databases.yml

Tipps

  1. Eine Aufgabe pro Role: docker macht nur Docker
  2. Sinnvolle Defaults: Role sollte ohne Variablen funktionieren
  3. Dokumentation: README.md pro Role
  4. Versionierung: Tags für stabile Versionen
  5. Galaxy nutzen: Rad nicht neu erfinden

Fazit

Roles sind das Herzstück von gutem Ansible. Einmal geschrieben, hundertmal genutzt. Investiere Zeit in saubere Roles - es zahlt sich aus.

Made with by Daniel Hiller

|