Dynamic Inventory

Dynamic Inventory #

Static inventory dalam bentuk hosts.ini atau file YAML bekerja baik untuk infrastruktur yang kecil dan stabil. Namun begitu kita mengelola cloud environment dengan ratusan instance yang spin up dan terminate setiap hari, atau hybrid infrastructure yang sebagian hostnya berada di AWS, sebagian di on-premise, sebagian di CMDB — memelihara file inventory secara manual menjadi pekerjaan yang mustahil dan rentan kesalahan. Dynamic inventory memecahkan masalah ini: Ansible mengambil daftar host dari sumber yang authoritative — AWS API, GCP Compute, Azure ARM, vCenter, atau CMDB internal — setiap kali playbook dijalankan, sehingga inventory selalu mencerminkan state infrastruktur saat ini.

Artikel ini membahas tiga bentuk dynamic inventory di Ansible: inventory plugin (cara modern, YAML-based, paling direkomendasikan), inventory script (legacy, executable yang return JSON), dan cara menggabungkan banyak sumber inventory menjadi satu ekosistem yang terkoordinasi.

Mengapa Dynamic Inventory Penting #

Bayangkan skenario ini: tim SRE deploy 50 EC2 instance baru untuk auto-scaling group, menghapus 30 instance lama, dan mengubah tag Environment pada 20 instance yang sudah ada. Dengan static inventory, kita harus memperbarui file hosts.ini secara manual — pekerjaan yang tidak skalabel dan rentan salah. Dengan dynamic inventory, Ansible memanggil AWS API setiap kali playbook dijalankan dan mendapatkan state terbaru secara real-time.

flowchart LR
    A["Playbook: ansible-playbook -i aws_ec2.yml"] --> B["Ansible baca inventory file"]
    B --> C{"YAML atau executable?"}
    C -->|YAML| D["Inventory plugin"]
    C -->|Executable| E["Inventory script"]
    D --> F["AWS API / GCP API / Azure API"]
    E --> F
    F --> G["JSON host data"]
    G --> H["Ansible populate inventory"]
    H --> I["keyed_groups & compose"]
    I --> J["Groups: role_webserver, env_production, dll."]
    J --> K["Playbook berjalan dengan host yang benar"]

Keuntungan dynamic inventory dibanding static:

  • Selalu up-to-date — Ansible melihat state infrastruktur saat playbook dijalankan, bukan saat file di-edit terakhir.
  • Self-service — developer bisa deploy instance baru tanpa harus memberitahu SRE untuk update inventory.
  • Tag-based grouping — group dibuat otomatis dari tag cloud (e.g., tag:Role=webserver → group role_webserver).
  • Skala besar — ratusan hingga ribuan host ditangani tanpa intervensi manual.
  • Hybrid-ready — gabungkan inventory dari AWS, GCP, dan CMDB dalam satu direktori.

Inventory Plugin: Cara Modern #

Inventory plugin adalah cara paling direkomendasikan untuk dynamic inventory. Plugin berbasis YAML, terinstal via collection, dan punya fitur bawaan seperti caching, keyed_groups, compose, dan filter. Ansible otomatis memanggil plugin yang tepat berdasarkan nama file dan konfigurasi plugin: di baris pertama.

AWS EC2 dengan amazon.aws.aws_ec2 #

Collection amazon.aws menyediakan plugin aws_ec2 yang mengambil instance langsung dari AWS API:

# Install dependency
ansible-galaxy collection install amazon.aws
pip install boto3
# inventory/aws_ec2.yml
# Nama file HARUS diakhiri dengan aws_ec2.yml atau aws_ec2.yaml

plugin: amazon.aws.aws_ec2

# Region yang akan di-scan
regions:
  - ap-southeast-1      # Singapura
  - ap-southeast-3      # Jakarta
  - us-east-1           # Virginia

# Filter instance yang akan diambil
filters:
  instance-state-name: running
  "tag:Environment": production

# Field yang digunakan sebagai hostname Ansible
hostnames:
  - private-ip-address

# Group otomatis berdasarkan tag
keyed_groups:
  - prefix: role
    key: tags.Role          # Group: role_webserver, role_database, dll.
  - prefix: env
    key: tags.Environment   # Group: env_production, env_staging
  - prefix: az
    key: placement.availability_zone

# Group berdasarkan kondisi custom
groups:
  singapore: "'ap-southeast-1' in placement.region"
  jakarta: "'ap-southeast-3' in placement.region"
  high_memory: "instance_type.startswith('r5') or instance_type.startswith('r6')"

# Map field AWS ke variabel Ansible
compose:
  ansible_host: private_ip_address
  ansible_user: "'ec2-user' if 'Windows' not in image_id else 'Administrator'"
  instance_type: instance_type
  availability_zone: placement.availability_zone
  vpc_id: vpc_id

# Variable untuk semua host
groups:
  aws_production:
    vars:
      ansible_ssh_private_key_file: /opt/keys/aws-prod.pem
# Test inventory sebelum digunakan
ansible-inventory -i inventory/aws_ec2.yml --list
ansible-inventory -i inventory/aws_ec2.yml --graph

# Output --graph:
# @all:
#   |--@aws_production:
#   |   |--@env_production:
#   |   |   |--@ap_southeast_1:
#   |   |   |   |--ip-10-0-1-10.ap-southeast-1.compute.internal
#   |   |   |   |--ip-10-0-1-11.ap-southeast-1.compute.internal
#   |   |   |--@ap_southeast_3:
#   |   |   |   |--ip-10-0-2-5.ap-southeast-3.compute.internal
#   |   |--@role_webserver:
#   |   |   |--ip-10-0-1-10.ap-southeast-1.compute.internal

# Gunakan dalam playbook
ansible-playbook -i inventory/aws_ec2.yml site.yml

GCP Compute dengan google.cloud.gcp_compute #

# inventory/gcp_compute.yml
plugin: google.cloud.gcp_compute

projects:
  - my-production-project
  - my-shared-services-project

zones:
  - asia-southeast2-a    # Jakarta
  - asia-southeast2-b
  - asia-southeast2-c

# Filter instance — pakai sintaks JMESPath GCP
filters:
  - status = RUNNING
  - labels.environment = production
  - labels.managed_by = ansible

# Group otomatis
keyed_groups:
  - prefix: role
    key: labels.role
  - prefix: zone
    key: zone
  - prefix: env
    key: labels.environment

# Map field GCP ke variabel Ansible
compose:
  ansible_host: networkInterfaces[0].networkIP
  ansible_user: "'ubuntu' if 'debian' in labels.base_os else 'centos'"
  machine_type: machineType
  project: project

Azure dengan azure.azcollection.azure_rm #

# inventory/azure_rm.yml
plugin: azure.azcollection.azure_rm

include_vm_resource_groups:
  - production-rg
  - staging-rg

# Filter
filters:
  - power_state == 'running'
  - tags.environment == 'production'

# Group
keyed_groups:
  - prefix: role
    key: tags.role
  - prefix: env
    key: tags.environment

# Compose
compose:
  ansible_host: properties.networkProfile.networkInterfaces[0].properties.ipConfigurations[0].properties.privateIPAddress

Tabel Perbandingan Sumber Inventory #

Aspek Inventory Plugin (AWS/GCP/Azure) Inventory Script (Python) Static File (YAML/INI)
Format YAML Executable yang return JSON YAML atau INI
Caching Built-in, configurable Manual, harus implement sendiri Tidak perlu
keyed_groups Native Harus di-generate manual Manual
compose Native Harus di-handle manual Manual
Filter Native (JMESPath/YAML) Logika Python penuh Tidak berlaku
Performance (1000 host) 1 API call (cached) 1 API call per run Instant
Reusability Sharing via collection Sharing via repo internal One project
Testing ansible-inventory --list Manual script execution Lihat file
Direkomendasikan untuk Cloud, hybrid, modern CMDB custom, legacy systems < 50 host stabil

Alur Kerja ansible-inventory #

Setiap kali kita menjalankan ansible-playbook -i inventory/, Ansible memanggil ansible-inventory di belakang layar. Plugin atau script kita dieksekusi untuk menghasilkan representasi JSON dari inventory. Diagram berikut menunjukkan alur lengkapnya:

sequenceDiagram
    participant User
    participant AP as "ansible-playbook"
    participant AI as "ansible-inventory"
    participant Plugin as "aws_ec2 plugin"
    participant AWS as "AWS EC2 API"
    participant Cache as "JSON Cache"

    User->>AP: "ansible-playbook -i aws_ec2.yml site.yml"
    AP->>AI: "Load inventory"
    AI->>Plugin: "parse(config)"
    Plugin->>Cache: "Cek cache valid?"
    alt Cache valid
        Cache-->>Plugin: "Return cached data"
    else Cache expired/missing
        Plugin->>AWS: "DescribeInstances(filters)"
        AWS-->>Plugin: "List of instances"
        Plugin->>Cache: "Write cache"
    end
    Plugin->>Plugin: "Apply keyed_groups"
    Plugin->>Plugin: "Apply compose"
    Plugin-->>AI: "Inventory dict"
    AI-->>AP: "Populated inventory"
    AP->>AP: "Run tasks on matched hosts"

Caching adalah fitur penting untuk inventory plugin: tanpa caching, setiap ansible-playbook call akan memicu API call ke AWS, yang bisa kena rate limit jika playbook dijalankan dari CI setiap push. Aktifkan caching di ansible.cfg:

# ansible.cfg
[inventory]
cache = true
cache_plugin = jsonfile
cache_connection = /tmp/ansible_inventory_cache
cache_timeout = 300   # Cache berlaku 5 menit

Untuk sumber inventory yang tidak memiliki plugin bawaan — CMDB internal, database legacy, sistem monitoring yang mengekspos data host — kita bisa menulis inventory script Python yang mengembalikan JSON dalam format yang diharapkan Ansible. Script ini menerima flag --list (semua host) dan --host <hostname> (variabel untuk satu host).

Anatomi Script #

#!/usr/bin/env python3
# inventory/cmdb_inventory.py
# Ambil inventory dari CMDB internal perusahaan

import json
import sys
import argparse
import os

try:
    import requests
except ImportError:
    print(json.dumps({"_meta": {"hostvars": {}}}))
    sys.exit(0)

CMDB_URL = os.environ.get(
    'CMDB_URL', 'https://cmdb.company.internal/api'
)
CMDB_TOKEN = os.environ.get('CMDB_API_TOKEN', '')


def get_inventory():
    """Ambil semua server dari CMDB dan kelompokkan."""
    if not CMDB_TOKEN:
        sys.stderr.write(
            "ERROR: Environment variable CMDB_API_TOKEN belum di-set.\n"
        )
        return {"_meta": {"hostvars": {}}}

    headers = {"Authorization": f"Bearer {CMDB_TOKEN}"}

    try:
        response = requests.get(
            f"{CMDB_URL}/servers",
            params={"status": "active"},
            headers=headers,
            timeout=15
        )
        response.raise_for_status()
        servers = response.json()
    except requests.exceptions.RequestException as e:
        sys.stderr.write(f"Error mengambil inventory dari CMDB: {e}\n")
        return {"_meta": {"hostvars": {}}}

    inventory = {
        "_meta": {"hostvars": {}},
        "all": {"children": []},
    }

    for server in servers:
        hostname = server["hostname"]
        env = server.get("environment", "unknown")
        role = server.get("role", "unknown")
        datacenter = server.get("datacenter", "unknown")

        # Host variables
        inventory["_meta"]["hostvars"][hostname] = {
            "ansible_host": server.get("ip_address", hostname),
            "server_id": server.get("id"),
            "datacenter": datacenter,
            "os": server.get("os"),
            "ansible_user": "ubuntu" if "ubuntu" in server.get("os", "") else "centos",
        }

        # Group by environment
        env_group = f"env_{env}"
        if env_group not in inventory:
            inventory[env_group] = {
                "hosts": [],
                "vars": {"env": env},
            }
            inventory["all"]["children"].append(env_group)
        inventory[env_group]["hosts"].append(hostname)

        # Group by role
        role_group = f"role_{role}"
        if role_group not in inventory:
            inventory[role_group] = {"hosts": []}
            inventory["all"]["children"].append(role_group)
        inventory[role_group]["hosts"].append(hostname)

        # Group by datacenter
        dc_group = f"dc_{datacenter}"
        if dc_group not in inventory:
            inventory[dc_group] = {"hosts": []}
            inventory["all"]["children"].append(dc_group)
        inventory[dc_group]["hosts"].append(hostname)

    return inventory


def get_host(hostname):
    """Ambil variabel untuk satu host."""
    headers = {"Authorization": f"Bearer {CMDB_TOKEN}"}
    try:
        response = requests.get(
            f"{CMDB_URL}/servers/{hostname}",
            headers=headers,
            timeout=10
        )
        response.raise_for_status()
        server = response.json()
        return {
            "ansible_host": server.get("ip_address", hostname),
            "server_id": server.get("id"),
            "datacenter": server.get("datacenter"),
            "os": server.get("os"),
        }
    except requests.exceptions.RequestException:
        return {}


def main():
    parser = argparse.ArgumentParser(description='CMDB Inventory Script')
    parser.add_argument('--list', action='store_true',
                        help='Tampilkan semua inventory')
    parser.add_argument('--host', type=str,
                        help='Tampilkan variabel untuk host tertentu')
    args = parser.parse_args()

    if args.list:
        print(json.dumps(get_inventory(), indent=2))
    elif args.host:
        print(json.dumps(get_host(args.host), indent=2))
    else:
        print(json.dumps({}))


if __name__ == '__main__':
    main()
# Beri permission executable
chmod +x inventory/cmdb_inventory.py

# Test manual
./inventory/cmdb_inventory.py --list
./inventory/cmdb_inventory.py --host web-01.company.com

# Gunakan dalam playbook
ansible-playbook -i inventory/cmdb_inventory.py site.yml

Tip — Selalu keluar dengan JSON yang valid, bahkan saat terjadi error. Jika script kita crash dengan stack trace Python, Ansible akan memunculkan error cryptic. Lebih baik mengembalikan {"_meta": {"hostvars": {}}} kosong dan menulis error ke stderr agar playbook bisa menentukan apakah lanjut atau stop.


Anti-Pattern: Inventory Script yang Mengembalikan Semua Host Tanpa Filter #

# ANTI-PATTERN: ambil semua host, biarkan playbook filter
def get_inventory():
    response = requests.get(f"{CMDB_URL}/servers")  # 5000 host!
    servers = response.json()
    inventory = {"_meta": {"hostvars": {}}, "all": {"hosts": []}}
    for s in servers:
        inventory["all"]["hosts"].append(s["hostname"])
    return inventory
# BENAR: filter di source, expose hanya host yang relevan
def get_inventory():
    params = {"status": "active", "managed_by": "ansible"}
    response = requests.get(f"{CMDB_URL}/servers", params=params)
    servers = response.json()
    # ... build inventory dengan group yang bermakna
    return inventory
# Pemakaian: gunakan --limit untuk filter tambahan
ansible-playbook -i inventory/cmdb_inventory.py site.yml --limit env_production

Konsekuensi anti-pattern di atas: playbook memuat 5000 host ke memory hanya untuk menjalankan task pada 50 host di production. Group all jadi membengkak, --list output tidak informatif, dan filter harus dilakukan di playbook layer (yang seharusnya bisa lebih awal).

Warning — Inventory script yang return semua host tanpa filter bisa menyebabkan playbook hang atau kehabisan memory di infrastruktur besar. Selalu filter di source (CMDB/API) dan expose group yang sudah relevan. Gunakan --limit untuk filter tambahan saat run, tapi jangan andalkan itu sebagai strategi utama.


Anti-Pattern: Hard-code Inventory di Playbook #

# ANTI-PATTERN: hard-code host di playbook
- name: "Deploy web app"
  hosts: web-01.company.com,web-02.company.com,web-03.company.com
  tasks: [...]
# BENAR: pakai group dari dynamic inventory
- name: "Deploy web app"
  hosts: role_webserver
  tasks: [...]

Hard-code host di playbook mengikat playbook ke state infrastruktur saat ini. Saat instance baru ditambahkan atau dihapus, playbook harus diedit ulang — pola yang tidak skalabel. Dynamic inventory + group-based selection membuat playbook agnostic terhadap jumlah host: jalankan untuk 3 host hari ini, 30 host besok, tanpa edit satu baris pun.


Menggabungkan Banyak Sumber Inventory #

Ansible bisa menggabungkan inventory dari beberapa sumber sekaligus. Cukup arahkan -i ke sebuah direktori, dan Ansible akan otomatis memuat semua file yang sesuai pola *.yml, *.yaml, *.ini, atau executable yang diakhiri tanpa ekstensi:

inventory/
├── aws_ec2.yml              # Server di AWS
├── gcp_compute.yml          # Server di GCP
├── cmdb_inventory.py        # Server on-premise dari CMDB
├── static_hosts.ini         # Server khusus yang tidak ada di cloud/CMDB
└── group_vars/
    ├── all.yml              # Variabel untuk semua host
    ├── role_webserver.yml   # Variabel untuk group role_webserver
    ├── role_database.yml    # Variabel untuk group role_database
    └── env_production.yml   # Variabel untuk group env_production
# Ansible otomatis gabungkan semua sumber
ansible-playbook -i inventory/ site.yml

# Lihat inventory gabungan
ansible-inventory -i inventory/ --graph

# Output:
# @all:
#   |--@env_production:
#   |   |--@role_database:
#   |   |   |--db-01.aws.internal
#   |   |   |--db-gcp-01.c.internal
#   |   |   |--db-onprem.cmp.internal
#   |   |--@role_webserver:
#   |   |   |--web-01.aws.internal
#   |   |   |--web-02.aws.internal

Urutan Loading dan Precedence #

flowchart TD
    A["Ansible scan direktori inventory/"] --> B["Load file *.yml"]
    A --> C["Load file *.yaml"]
    A --> D["Load file *.ini"]
    A --> E["Load executable files"]
    B --> F["Merge ke inventory global"]
    C --> F
    D --> F
    E --> F
    F --> G["Apply group_vars/*.yml per group"]
    G --> H["Apply host_vars/*.yml per host"]
    H --> I["Final inventory siap dipakai"]

Precedence aturan (dari tertinggi ke terendah):

  1. host_vars/<hostname>.yml — variabel per host
  2. group_vars/<groupname>.yml — variabel per group
  3. group_vars/all.yml — variabel untuk semua host
  4. compose: di inventory plugin — variabel dinamis
  5. hostvars: di inventory script — variabel dinamis
  6. Variabel inline di playbook (vars:)

Info — File di group_vars/ otomatis diasosiasikan dengan group berdasarkan nama file. group_vars/role_webserver.yml otomatis di-apply ke group role_webserver tanpa perlu konfigurasi tambahan. Ini adalah pattern powerful yang membuat inventory + konfigurasi tetap rapi di satu tempat.


Caching untuk Inventory Besar #

Untuk infrastruktur dengan ratusan hingga ribuan host, memanggil AWS API setiap kali playbook dijalankan lambat dan bisa kena rate limit. Aktifkan caching di ansible.cfg:

# ansible.cfg
[inventory]
cache = true
cache_plugin = jsonfile
cache_connection = /tmp/ansible_inventory_cache
cache_timeout = 300   # Cache berlaku 5 menit

# Optional: cache hanya untuk plugin tertentu
cache_plugin_omit = ['hostfile']  # Skip caching untuk static file
# Refresh cache manual saat diperlukan
ansible-inventory -i inventory/ --list --flush-cache

# Lihat isi cache
ls -la /tmp/ansible_inventory_cache/
cat /tmp/ansible_inventory_cache/aws_ec2_*.json | python -m json.tool | head -30

Strategi Caching yang Tepat #

Skenario Cache TTL Alasan
Dev environment, sering berubah 60 detik Ingin perubahan cepat terlihat
Staging, deploy setiap jam 300 detik (5 menit) Balance antara freshness dan API call
Production, jarang berubah 3600 detik (1 jam) Minimalkan API call
On-call incident, butuh fresh data 0 (off) atau manual flush Jangan andalkan cache saat troubleshoot
CI/CD pipeline Disabled Setiap run butuh data fresh

Tip — Untuk CI/CD, nonaktifkan cache atau set TTL sangat rendah. Cache yang expired bisa menyebabkan playbook deploy ke host yang sudah di-terminate, atau skip host yang baru di-provision. Selalu flush-cache di awal CI job yang critical.


Pattern Lanjutan: Multi-Region dan Multi-Account #

Untuk organisasi yang punya beberapa AWS account atau region, pattern inventory berikut membantu:

# inventory/aws_production.yml
plugin: amazon.aws.aws_ec2
regions:
  - ap-southeast-1
  - ap-southeast-3
  - us-east-1
filters:
  instance-state-name: running
  "tag:Environment": production
  "tag:ManagedBy": ansible
keyed_groups:
  - prefix: role
    key: tags.Role
  - prefix: env
    key: tags.Environment
  - prefix: account
    key: tags.Account
compose:
  ansible_host: private_ip_address
  aws_account_id: tags.Account

# inventory/aws_staging.yml
plugin: amazon.aws.aws_ec2
regions:
  - ap-southeast-1
filters:
  instance-state-name: running
  "tag:Environment": staging
keyed_groups:
  - prefix: role
    key: tags.Role
groups:
  staging: true
# Pilih environment dengan -i
ansible-playbook -i inventory/aws_production.yml site.yml   # Production
ansible-playbook -i inventory/aws_staging.yml site.yml      # Staging

Atau gabungkan semua dalam satu direktori dan filter dengan --limit:

ansible-playbook -i inventory/ site.yml --limit env_production
ansible-playbook -i inventory/ site.yml --limit env_staging

Pattern Lanjutan: Inventory untuk Kubernetes #

Untuk cluster Kubernetes, inventory plugin kubernetes.core.k8s menghasilkan inventory dari object K8s (pod, service, node):

# inventory/k8s.yml
plugin: kubernetes.core.k8s

connections:
  - kubeconfig: ~/.kube/config
    name: production-cluster

# Ambil node dari cluster
# Filter berdasarkan label

Penggunaan umum: orchestrating workload di K8s dan VM secara bersamaan dalam satu playbook.


Testing dan Validasi Inventory #

Sebelum pakai inventory di production, selalu test dulu:

# Lihat inventory sebagai JSON
ansible-inventory -i inventory/aws_ec2.yml --list | jq 'keys'

# Lihat host di group tertentu
ansible-inventory -i inventory/aws_ec2.yml --list | \
  jq '._meta.hostvars | keys'

# Lihat host di group env_production
ansible-inventory -i inventory/aws_ec2.yml --list | \
  jq '.env_production.hosts'

# Lihat variable untuk satu host
ansible-inventory -i inventory/aws_ec2.yml --host web-01.internal

# Test koneksi ke semua host di group
ansible all -i inventory/aws_ec2.yml -m ping --limit env_production

# Dry-run playbook (--check) untuk validasi tanpa eksekusi
ansible-playbook -i inventory/aws_ec2.yml site.yml --check --diff
# Simpan inventory ke file untuk inspeksi offline
ansible-inventory -i inventory/aws_ec2.yml --list > /tmp/inv_dump.json

# Bandingkan inventory antara dua waktu
diff <(jq -S . /tmp/inv_dump.json) <(ansible-inventory -i inventory/aws_ec2.yml --list | jq -S .)

Kapan Pakai Static vs Dynamic #

Jumlah host < 20 dan jarang berubah?
  → Static inventory (YAML/INI) cukup
    Contoh: lab environment, 5 VPS pribadi

20-100 host, berubah beberapa kali sebulan?
  → Semi-dynamic: inventory script sederhana atau hybrid

100+ host, auto-scaling, multi-cloud?
  → Dynamic inventory plugin dengan caching
    Contoh: production AWS + GCP + on-premise

Host dari banyak sumber (cloud + CMDB + file)?
  → Direktori inventory dengan multiple file

Butuh testing/development tanpa real infrastructure?
  → Static inventory dengan mock host
    Contoh: localhost, Vagrant, Docker

Ringkasan #

  • Inventory plugin (AWS EC2, GCP Compute, Azure ARM) adalah cara paling direkomendasikan untuk dynamic inventory — berbasis YAML, support caching, keyed_groups, dan compose secara native.
  • Gunakan keyed_groups untuk otomatis membuat grup dari tag cloud — tag:Role=webserver → group role_webserver tanpa konfigurasi tambahan per host.
  • compose memetakan field API ke variabel Ansible — ansible_host: private_ip_address memastikan Ansible pakai private IP, bukan public.
  • Inventory script Python harus support --list (semua host) dan --host <hostname> (variabel host) — ini adalah interface yang diharapkan Ansible untuk executable.
  • Gabungkan banyak sumber dengan -i inventory/dir/ — Ansible otomatis load semua file di direktori tersebut, lalu merge ke satu inventory.
  • Aktifkan caching untuk inventory besar — tanpa cache, setiap ansible-playbook call memicu API call ke cloud, lambat dan rentan rate limit.
  • Filter di source, bukan di playbook — inventory script yang return semua host tanpa filter akan membengkakan memory dan membuat output --list tidak informatif.
  • Jangan hard-code host di playbook — pakai group (hosts: role_webserver) agar playbook agnostic terhadap jumlah host.
  • Selalu test inventory dengan ansible-inventory -i <inv> --list dan ansible all -m ping --limit <group> sebelum menjalankan playbook yang mengubah state.
  • Untuk multi-environment, pakai direktori inventory + filter dengan --limit atau file inventory terpisah per environment.

← Sebelumnya: Custom Plugin   Berikutnya: Collection →

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