I föregående inlägg gick vi igenom grunderna i Ansible — inventory, playbooks och modules. Du kan nu automatisera uppgifter på dina maskiner. Men vad händer när din site.yml växer sig till 300 rader och du vill återanvända samma nginx-konfiguration i tre olika projekt? Då är det dags för Roles.

En Ansible Role är ett strukturerat sätt att paketera relaterade tasks, variabler, filer och mallar i en återanvändbar enhet. Tänk på det som ett npm-paket eller ett Python-bibliotek — fast för din infrastruktur.

"En playbook berättar vad som ska hända. En role berättar hur det ska gå till — och kan användas om och om igen."
Varför Roles? Problemet med långa playbooks
När det börjar skava

Utan roles tenderar playbooks att växa sig stora och svårhanterliga. Du kopierar och klistrar in tasks mellan filer. Du hittar inte var du definierade den där variabeln. En kollega (eller du själv om tre månader) förstår ingenting.

Roles löser det genom att tvinga dig att strukturera din kod i väldefinierade mappar med tydliga ansvarsområden. En role för nginx. En för Docker. En för grundläggande serverkonfiguration. Kombinera dem sedan som byggklossar i dina playbooks.

💡 Tumregel: Om du skriver samma tasks i mer än en playbook — gör om dem till en role. Det betalar sig direkt.
Mappstrukturen — hjärtat i en Role
Konvention framför konfiguration

En Role är i grunden bara en mapp med en specifik struktur som Ansible känner igen automatiskt. Du behöver inte ange sökvägar — Ansible hittar allt självt så länge du följer konventionen.

roles/ └── nginx/ # Rolens namn ├── tasks/ │ └── main.yml # Här är tasks:en — startpunkten ├── handlers/ │ └── main.yml # Handlers (t.ex. "restart nginx") ├── templates/ │ └── nginx.conf.j2 # Jinja2-mallar för konfigfiler ├── files/ │ └── index.html # Statiska filer att kopiera ├── vars/ │ └── main.yml # Variabler (hög prioritet) ├── defaults/ │ └── main.yml # Standardvärden (låg prioritet) └── meta/ └── main.yml # Metadata och beroenden
💡 Du behöver inte ha alla mappar. Ansible ignorerar de som saknas. Börja med bara tasks/main.yml — lägg till resten när du behöver det.
Skapa din första Role — steg för steg
Ett praktiskt exempel: nginx-installation
STEG 1 — Skapa mappstrukturen

Ansible har ett inbyggt kommando som skapar hela strukturen åt dig:

ansible-galaxy init roles/nginx
STEG 2 — Skriv dina tasks

Öppna roles/nginx/tasks/main.yml och fyll i dina uppgifter:

# roles/nginx/tasks/main.yml --- - name: Installera nginx apt: name: nginx state: present update_cache: yes - name: Kopiera nginx-konfiguration template: src: nginx.conf.j2 dest: /etc/nginx/nginx.conf owner: root mode: '0644' notify: Starta om nginx - name: Se till att nginx är igång service: name: nginx state: started enabled: yes
STEG 3 — Lägg till en handler

Handlers körs bara när en task triggar dem — perfekt för omstarter:

# roles/nginx/handlers/main.yml --- - name: Starta om nginx service: name: nginx state: restarted
STEG 4 — Definiera standardvärden
# roles/nginx/defaults/main.yml --- nginx_port: 80 nginx_worker_processes: auto nginx_server_name: _
STEG 5 — Använd rolen i din playbook
# site.yml --- - name: Konfigurera webbservrar hosts: webservers become: yes roles: - nginx
💡 Rolen hittas automatiskt om den ligger i en mapp som heter roles/ bredvid din playbook, eller i ~/.ansible/roles/ globalt.
Defaults vs Vars — vad är skillnaden?
Prioritetsordning i variabler

Det här förvirrar många i början. Ansible har en tydlig prioritetsordning för variabler, och defaults och vars spelar olika roller i den:

defaults/main.yml — Lägsta prioritet. Dessa värden används om inget annat anges. Det är dina "inbyggda standardvärden" som du tänker dig ska gå att överskriva utifrån.

vars/main.yml — Högre prioritet. Dessa är mer "fasta" värden för rolen som du inte vill att andra ska råka överskriva av misstag.

# Överskrid defaults när du anropar rolen: - name: Konfigurera webbservrar hosts: webservers become: yes roles: - role: nginx vars: nginx_port: 8080 # Överskriver default-värdet 80 nginx_server_name: min.server.se
💡 Generell regel: Lägg saker du vill ska gå att ändra utifrån i defaults/. Lägg interna konstanter i vars/.
Templates med Jinja2 — dynamiska konfigfiler
Mallen som anpassar sig efter variablerna

En av de kraftfullaste funktionerna i Roles är templates. Istället för att kopiera en statisk konfigfil kan du använda en Jinja2-mall som fylls i med dina variabler vid körning. Filer i templates/ har ändelsen .j2.

# roles/nginx/templates/nginx.conf.j2 worker_processes {{ nginx_worker_processes }}; events { worker_connections 1024; } http { server { listen {{ nginx_port }}; server_name {{ nginx_server_name }}; location / { root /var/www/html; index index.html; } } }

När Ansible kör template:-modulen ersätts {{ variabel }} med de faktiska värdena från dina defaults eller vars. Samma template — olika resultat beroende på miljö.

💡 Du kan använda if-satser och loopar i Jinja2-templates också: {% if nginx_ssl %} ... {% endif %}. Kraftfullt när konfigurationen ska skilja sig åt mellan servrar.
"Skriv rolen en gång. Använd den i tio projekt. Ändra på ett ställe — uppdateras överallt."
Kombinera flera Roles i en playbook
Byggklossar för din infrastruktur

Det riktiga värdet med Roles syns när du börjar kombinera dem. Här är ett mer realistiskt hemmalabb-exempel där en ny server sätts upp från grunden:

# site.yml — sätt upp en komplett server --- - name: Grundkonfiguration hosts: all become: yes roles: - common # Skapar användare, SSH-nycklar, brandvägg - fail2ban # Skyddar mot brute-force - ntp # Tidssynkronisering - name: Webbserver-setup hosts: webservers become: yes roles: - role: nginx vars: nginx_port: 443 - certbot # SSL-certifikat via Let's Encrypt - name: Docker-miljö hosts: docker_hosts become: yes roles: - docker - docker_compose
💡 Lägg alla dina roles i ett eget Git-repo. Sedan kan du inkludera dem som submoduler i dina projektrepos — eller ladda upp dem till Ansible Galaxy för att dela med världen.
Ansible Galaxy — färdiga Roles från communityn
Sluta uppfinna hjulet

Ansible Galaxy är ett community-nav med tusentals färdiga Roles som du kan ladda ner och använda direkt. Behöver du installera Docker, konfigurera UFW-brandvägg, eller sätta upp en Postfix-mailserver? Det finns troligtvis redan en vältestad role för det.

# Installera en role från Ansible Galaxy ansible-galaxy install geerlingguy.docker # Eller via en requirements.yml-fil (rekommenderas i projekt) ansible-galaxy install -r requirements.yml
# requirements.yml — lista dina beroenden --- roles: - name: geerlingguy.docker version: "6.1.0" - name: geerlingguy.nginx version: "3.2.0"

Jeff Geerling (geerlingguy) är en av de mest kända Ansible-bidragsgivarna — hans roles för Docker, nginx, PHP och MySQL håller hög kvalitet och underhålls aktivt. Ett bra ställe att börja titta.

💡 Kolla alltid starcount och senaste commit-datum på Galaxy innan du väljer en role. Välj roles som aktivt underhålls och har många stjärnor.
Role-beroenden med meta/main.yml
Roles som kräver andra roles

Ibland beror en role på en annan — din wordpress-role kräver kanske att både nginx och mysql är installerade först. Det kan du deklarera i meta/main.yml så att Ansible sköter ordningen automatiskt:

# roles/wordpress/meta/main.yml --- dependencies: - role: nginx vars: nginx_port: 80 - role: mysql vars: mysql_root_password: "{{ vault_mysql_root_pw }}"
💡 Kombinera gärna meta-beroenden med Ansible Vault för att lagra känsliga lösenord krypterat i ditt Git-repo — mer om det i ett kommande inlägg.
Praktiskt hemmalabb-exempel: en komplett common-role
Grundkonfiguration för alla nya servrar

Här är ett konkret exempel på en common-role som du kan köra mot varje ny server i ditt hemmalab för att säkerställa en konsekvent grundkonfiguration:

# roles/common/tasks/main.yml --- - name: Uppdatera apt-cache och uppgradera paket apt: update_cache: yes upgrade: dist - name: Installera baspaket apt: name: - vim - curl - htop - git - ufw - unattended-upgrades state: present - name: Skapa admin-användare user: name: "{{ admin_user }}" groups: sudo shell: /bin/bash state: present - name: Lägg till SSH-nyckel authorized_key: user: "{{ admin_user }}" key: "{{ admin_ssh_key }}" - name: Aktivera brandvägg och tillåt SSH ufw: rule: allow name: OpenSSH - name: Slå på UFW ufw: state: enabled policy: deny
💡 Lagra admin_user och admin_ssh_key i din defaults/main.yml eller i ett gruppvariabelfil under group_vars/all.yml i ditt projektrot.

// Snabbkoll: Vad har du lärt dig?

  • En Role är en strukturerad mapp med tasks, handlers, templates, vars och defaults
  • Skapa ny role-struktur snabbt med ansible-galaxy init
  • Defaults kan överskridas utifrån — vars är mer "interna" och har högre prioritet
  • Templates med Jinja2 skapar dynamiska konfigfiler från variabler
  • Kombinera flera roles i samma playbook som byggklossar
  • Ansible Galaxy har tusentals färdiga, välunderhållna roles att ladda ner
  • Deklarera Role-beroenden i meta/main.yml — Ansible sköter ordningen

Med Roles börjar din Ansible-kod likna riktig mjukvaru-arkitektur — modulär, testbar och återanvändbar. Det är det som skiljer en Ansible-nybörjare från någon som faktiskt kan underhålla sin infrastruktur på lång sikt.

Lägg allt i Git. Namnge dina roles tydligt. Dokumentera variablerna i defaults/main.yml med kommentarer. Sedan kan du (och andra) sätta upp en ny server på minuter, inte timmar.