Apa itu Role? #
Seiring playbook tumbuh, pola tertentu mulai terlihat: kamu menulis task untuk menginstal nginx, lalu di proyek lain kamu menulis task yang hampir sama untuk nginx lagi, lalu di proyek ketiga hal yang sama terjadi. Atau satu playbook mulai memiliki 200 task yang mencampur instalasi nginx, konfigurasi aplikasi, setup monitoring, dan deployment — semua dalam satu file yang hampir tidak mungkin dibaca. Role adalah solusi Ansible untuk kedua masalah ini: cara mengemas logika otomasi menjadi unit yang bisa digunakan ulang, dibagi antar proyek, dan dikontrol versinya secara independen.
Masalah yang Dipecahkan Role #
Tanpa role, playbook yang kompleks terlihat seperti ini:
# site.yml — semua task dalam satu file
- name: Setup semua server
hosts: all
tasks:
# Task nginx (50 baris)
- name: Install nginx
apt: ...
- name: Configure nginx
template: ...
# Task postgresql (60 baris)
- name: Install postgresql
apt: ...
- name: Configure postgresql
template: ...
# Task monitoring (40 baris)
- name: Install node_exporter
...
# Task aplikasi (80 baris)
- name: Deploy aplikasi
...
# Total: 230+ baris, sulit dibaca dan tidak bisa digunakan ulang
Dengan role:
# site.yml — bersih dan mudah dibaca
- name: Setup semua server
hosts: all
roles:
- common # Setup dasar semua server
- nginx # Web server
- postgresql # Database
- monitoring # Node exporter dan logging
- myapp # Aplikasi
Setiap role adalah unit yang berdiri sendiri, bisa diuji, dan bisa digunakan di proyek lain tanpa modifikasi.
Anatomi Role #
Role adalah konvensi direktori — Ansible mengenali sebuah direktori sebagai role jika ia mengikuti struktur tertentu:
roles/nginx/
├── tasks/
│ └── main.yml # Task utama role — wajib ada
├── handlers/
│ └── main.yml # Handler yang dipanggil task role ini
├── templates/
│ └── nginx.conf.j2 # Template Jinja2 yang digunakan task
├── files/
│ └── default.html # File statis yang disalin ke managed node
├── vars/
│ └── main.yml # Variabel internal role (prioritas tinggi)
├── defaults/
│ └── main.yml # Nilai default variabel (prioritas rendah, mudah di-override)
├── meta/
│ └── main.yml # Metadata role: dependencies, author, platform
└── README.md # Dokumentasi role
Tidak semua direktori harus ada — Ansible hanya memproses direktori yang eksis. Role paling minimal hanya butuh tasks/main.yml.
tasks/main.yml: Titik Masuk Role #
tasks/main.yml adalah file pertama yang dibaca Ansible saat role dijalankan. Dari sini, kamu bisa langsung menulis task atau mengimpor file task tambahan:
# roles/nginx/tasks/main.yml
---
- name: Import task instalasi nginx
import_tasks: install.yml
- name: Import task konfigurasi nginx
import_tasks: configure.yml
- name: Import task setup SSL (hanya jika ssl_enabled)
import_tasks: ssl.yml
when: ssl_enabled | default(false)
# roles/nginx/tasks/install.yml
---
- name: Install nginx
apt:
name: nginx
state: present
update_cache: true
- name: Pastikan nginx berjalan
systemd:
name: nginx
state: started
enabled: true
defaults/main.yml vs vars/main.yml #
Ini adalah perbedaan paling penting dalam role yang sering disalahpahami:
# roles/nginx/defaults/main.yml
# Nilai DEFAULT — dimaksudkan untuk di-override oleh pengguna role
nginx_port: 80
nginx_worker_processes: 4
nginx_client_max_body_size: "10m"
ssl_enabled: false
# roles/nginx/vars/main.yml
# Nilai INTERNAL — konstanta yang tidak dimaksudkan untuk di-override
nginx_config_dir: /etc/nginx
nginx_sites_available: /etc/nginx/sites-available
nginx_sites_enabled: /etc/nginx/sites-enabled
nginx_log_dir: /var/log/nginx
Pengguna role diharapkan mengoverride nilai di defaults/, tapi tidak nilai di vars/. Perbedaan ini bukan hanya konvensi — secara teknis vars/main.yml memiliki prioritas yang jauh lebih tinggi dari defaults/main.yml, sehingga lebih sulit di-override secara tidak sengaja.
Cara Menggunakan Role #
Ada beberapa cara memanggil role dari playbook:
# Cara 1: Daftar di bagian roles: (paling umum)
- name: Setup web server
hosts: webservers
roles:
- common
- nginx
- myapp
# Cara 2: include_role — dinamis, bisa digunakan di dalam tasks
- name: Setup web server
hosts: webservers
tasks:
- name: Setup common requirements
include_role:
name: common
- name: Setup nginx (dengan kondisi)
include_role:
name: nginx
when: install_nginx | default(true)
# Cara 3: import_role — statis, diproses saat playbook dimuat
- name: Setup web server
hosts: webservers
tasks:
- import_role:
name: nginx
Kapan Saatnya Membuat Role #
Tidak semua logika perlu dibungkus dalam role. Membuat role terlalu dini bisa menambah kompleksitas yang tidak perlu.
Buat role jika:
✓ Logika yang sama digunakan di lebih dari satu proyek
✓ Komponen bisa di-test secara independen
✓ Tim yang berbeda bertanggung jawab atas komponen ini
✓ Komponen memiliki variabel yang perlu dikustomisasi
✓ Komponen cukup kompleks untuk berdiri sendiri (>20 task)
Belum perlu role jika:
✗ Hanya digunakan di satu playbook dan satu proyek
✗ Logikanya sangat sederhana (< 5 task)
✗ Task sangat spesifik untuk satu konteks dan tidak mungkin reusable
Ringkasan #
- Role adalah cara mengemas logika otomasi Ansible menjadi unit yang reusable, terstruktur, dan bisa dikontrol versinya secara independen.
- Role mengikuti konvensi direktori standar —
tasks/,handlers/,templates/,files/,vars/,defaults/,meta/.defaults/main.yml: nilai default yang dimaksudkan untuk di-override pengguna.vars/main.yml: konstanta internal yang tidak boleh diubah sembarangan.tasks/main.ymladalah titik masuk — bisa langsung berisi task atau mengimpor file task tambahan denganimport_tasks.- Buat role saat logika digunakan di lebih dari satu proyek, atau saat komponen cukup kompleks untuk berdiri sendiri.
- Role membuat
site.ymllebih bersih dan mudah dibaca karena setiap role merepresentasikan satu tanggung jawab yang jelas.