Dependency #
Role jarang berdiri sendiri. Role postgresql mungkin bergantung pada role common yang menyiapkan user dan direktori dasar. Role myapp mungkin bergantung pada nginx dan postgresql yang harus sudah terkonfigurasi lebih dulu. Ansible menyediakan mekanisme untuk mendefinisikan dependency ini secara eksplisit, sehingga kamu tidak perlu mengingat urutan yang benar setiap kali menulis playbook.
Mendefinisikan Dependency di meta/main.yml #
Dependency role didefinisikan di meta/main.yml menggunakan key dependencies:
# roles/myapp/meta/main.yml
---
dependencies:
- role: common # Role ini dijalankan sebelum myapp
- role: nginx # nginx juga dijalankan sebelum myapp
- role: postgresql # postgresql juga dijalankan sebelum myapp
Saat playbook menggunakan role myapp, Ansible otomatis menjalankan common, nginx, dan postgresql terlebih dahulu — dalam urutan tersebut — sebelum menjalankan task dari myapp itu sendiri.
Dependency dengan Variabel #
Dependency bisa dipass variabel untuk mengkustomisasi perilaku role yang dijalankan sebagai dependency:
# roles/myapp/meta/main.yml
---
dependencies:
- role: common
vars:
create_deploy_user: true
deploy_user_name: "{{ app_user }}"
- role: nginx
vars:
nginx_port: "{{ app_port }}"
nginx_ssl_enabled: true
nginx_ssl_cert: "{{ ssl_cert_path }}"
- role: postgresql
vars:
postgresql_version: "15"
postgresql_databases:
- name: "{{ db_name }}"
owner: "{{ db_user }}"
Variabel yang dipass ke dependency ini hanya berlaku dalam konteks eksekusi dependency tersebut — tidak mempengaruhi penggunaan role yang sama di tempat lain.
Urutan Eksekusi #
Ansible menyelesaikan dependency secara rekursif sebelum menjalankan role yang mendefinisikannya. Jika role A bergantung pada role B, dan role B bergantung pada role C:
Playbook memanggil role A
│
└── A bergantung pada B
│
└── B bergantung pada C
│
▼
C dijalankan (tidak punya dependency)
│
▼
B dijalankan (dependency C sudah selesai)
│
▼
A dijalankan (dependency B sudah selesai)
Urutan ini dijamin oleh Ansible — kamu tidak perlu mengatur urutan secara manual di playbook selama dependency didefinisikan dengan benar di meta/main.yml.
Mencegah Eksekusi Duplikasi #
Secara default, Ansible menjalankan dependency yang sama hanya sekali meski beberapa role bergantung padanya. Ini disebut role deduplication:
Playbook:
roles:
- webapp # bergantung pada: common, nginx
- api # bergantung pada: common, postgresql
Urutan eksekusi:
1. common ← hanya sekali, meski dua role bergantung padanya
2. nginx
3. webapp
4. postgresql
5. api
Tapi ada situasi di mana kamu ingin role yang sama dijalankan beberapa kali dengan parameter berbeda. Nonaktifkan deduplication dengan mengatur allow_duplicates: true di meta/main.yml role yang bersangkutan:
# roles/vhost/meta/main.yml
---
allow_duplicates: true # Izinkan role ini dijalankan berkali-kali
dependencies: []
# playbook.yml — menggunakan role vhost dua kali dengan parameter berbeda
- hosts: webservers
roles:
- role: vhost
vars:
vhost_domain: app.example.com
vhost_port: 8080
- role: vhost # Dijalankan lagi (allow_duplicates: true)
vars:
vhost_domain: api.example.com
vhost_port: 8081
Circular Dependency #
Circular dependency terjadi saat role A bergantung pada role B, dan role B bergantung pada role A. Ansible akan mendeteksi ini dan memberikan error:
# ANTI-PATTERN: circular dependency
# roles/roleA/meta/main.yml
dependencies:
- role: roleB
# roles/roleB/meta/main.yml
dependencies:
- role: roleA # ← Circular! roleA butuh roleB, roleB butuh roleA
Solusinya biasanya adalah mengekstrak logika yang dibutuhkan bersama ke role ketiga:
# Solusi: buat role "common" yang berisi logika bersama
# roles/common/meta/main.yml
dependencies: [] # common tidak bergantung pada siapa pun
# roles/roleA/meta/main.yml
dependencies:
- role: common # A bergantung pada common
# roles/roleB/meta/main.yml
dependencies:
- role: common # B juga bergantung pada common, bukan pada A
requirements.yml: Dependency Eksternal #
Untuk dependency dari Ansible Galaxy atau repository Git eksternal, gunakan file requirements.yml di root project:
# requirements.yml
---
roles:
# Dari Ansible Galaxy
- name: geerlingguy.nginx
version: "3.2.0"
# Dari Git repository
- name: internal-common
src: https://gitlab.company.com/ansible/role-common.git
scm: git
version: "v2.1.0"
collections:
- name: community.postgresql
version: "3.1.0"
- name: amazon.aws
version: "7.0.0"
# Install semua dependency sebelum menjalankan playbook
ansible-galaxy role install -r requirements.yml
ansible-galaxy collection install -r requirements.yml
# Atau keduanya sekaligus
ansible-galaxy install -r requirements.yml
Selalu pin versi di requirements.yml dengan nomor versi yang eksplisit. Tanpa pin versi, update otomatis ke versi terbaru bisa membreak playbook yang sudah berjalan di production.Ringkasan #
- Dependency role didefinisikan di
meta/main.yml— Ansible otomatis menjalankan dependency dalam urutan yang benar sebelum role utama.- Dependency bisa menerima variabel untuk mengkustomisasi perilakunya dalam konteks eksekusi tersebut.
- Role deduplication mencegah role yang sama dijalankan dua kali meski beberapa role bergantung padanya — gunakan
allow_duplicates: trueuntuk menonaktifkan ini jika diperlukan.- Circular dependency harus dihindari — ekstrak logika bersama ke role independen ketiga.
- Gunakan
requirements.ymluntuk mendokumentasikan dan menginstal dependency dari Ansible Galaxy atau Git.- Selalu pin versi dependency di
requirements.ymluntuk menghindari perubahan tidak terduga saat dependency diupdate.