Dependency

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: true untuk menonaktifkan ini jika diperlukan.
  • Circular dependency harus dihindari — ekstrak logika bersama ke role independen ketiga.
  • Gunakan requirements.yml untuk mendokumentasikan dan menginstal dependency dari Ansible Galaxy atau Git.
  • Selalu pin versi dependency di requirements.yml untuk menghindari perubahan tidak terduga saat dependency diupdate.

← Sebelumnya: Struktur   Berikutnya: Reusability →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact