Agentless

Agentless #

Salah satu keputusan desain paling fundamental dalam pengembangan Ansible adalah arsitektur agentless (tanpa agen). Konsep ini bukan sekadar fitur pembeda, melainkan filosofi dasar yang memengaruhi cara kita merancang, mengoperasikan, dan melakukan pemecahan masalah (troubleshooting) terhadap otomatisasi infrastruktur kita setiap hari. Dengan memahami cara kerja arsitektur agentless, protokol koneksi yang digunakan, serta kelebihan dan trade-off yang menyertainya, kita dapat memanfaatkan potensi penuh Ansible secara aman dan efisien di lingkungan produksi.

Konsep Dasar Arsitektur Tanpa Agen #

Pada perkakas manajemen konfigurasi tradisional berbasis agen (seperti Chef atau Puppet), kita wajib memasang perangkat lunak agen (daemon) di setiap server yang akan dikelola. Agen lokal ini harus terus berjalan di background, menggunakan memori sistem, dan secara berkala mengirimkan permintaan (pull model) ke server master pusat untuk menanyakan apakah ada pembaruan konfigurasi.

Ansible mengambil pendekatan yang berlawanan dengan menerapkan model agentless. Dalam arsitektur ini, tidak ada perangkat lunak khusus Ansible yang perlu kita pasang, konfigurasikan, atau perbarui di server target (Managed Nodes). Kontrol sepenuhnya berada di tangan mesin pengirim (Control Node) yang mendorong konfigurasi (push model) secara terpusat.

Mari kita perhatikan perbedaan visual alur komunikasi antara arsitektur berbasis agen dan arsitektur agentless:

flowchart TD
    subgraph "Arsitektur Berbasis Agen"
        ChefMaster["Chef Server (Pusat)"]
        ChefAgent1["Managed Node 1\n(Chef Agent Daemon berjalan)"]
        ChefAgent2["Managed Node 2\n(Chef Agent Daemon berjalan)"]
        ChefAgent1 -->|"1. Tarik Konfigurasi berkala (Pull)"| ChefMaster
        ChefAgent2 -->|"1. Tarik Konfigurasi berkala (Pull)"| ChefMaster
    end

    subgraph "Arsitektur Agentless (Ansible)"
        AnsibleControl["Ansible Control Node\n(Tanpa Master Server)"]
        TargetNode1["Managed Node 1\n(Hanya butuh SSH + Python)"]
        TargetNode2["Managed Node 2\n(Hanya butuh SSH + Python)"]
        AnsibleControl -->|"1. Dorong Konfigurasi via SSH (Push)"| TargetNode1
        AnsibleControl -->|"1. Dorong Konfigurasi via SSH (Push)"| TargetNode2
    end

Dengan meniadakan agen, kita memotong seluruh birokrasi administratif manajemen software agen. Kita tidak perlu lagi mengurusi registrasi sertifikat SSL untuk mengamankan komunikasi agen-master, dan kita tidak perlu khawatir agen crash di server target yang dapat menghentikan otomatisasi kita tanpa peringatan.


Mekanisme Transportasi dan Koneksi SSH #

Sebagai ganti dari perangkat lunak agen, Ansible memanfaatkan protokol transportasi standar industri yang sudah pasti terpasang di hampir seluruh sistem operasi Unix-like: OpenSSH. Untuk server target berbasis Windows, Ansible menggunakan WinRM atau OpenSSH for Windows.

Ketika kita menjalankan tugas otomatisasi, Ansible bertindak sebagai klien SSH yang melakukan negosiasi koneksi aman dengan server SSH di managed node. Agar proses ini berjalan lancar pada skala produksi, Ansible menerapkan beberapa optimasi koneksi SSH berikut:

1. SSH Multiplexing (ControlPersist) #

Secara default, setiap koneksi SSH baru membutuhkan proses jabat tangan (handshake) keamanan yang memakan waktu (sekitar 0.5 hingga 2 detik). Jika sebuah playbook memiliki 50 tugas yang harus dijalankan di 100 server, overhead waktu koneksi akan sangat besar.

Ansible mengatasi ini dengan mengaktifkan fitur ControlPersist pada OpenSSH. Fitur ini memungkinkan Ansible untuk membuat soket koneksi SSH pertama kali, lalu menjaga soket tersebut tetap aktif dan terbuka di latar belakang untuk durasi tertentu. Tugas-tugas berikutnya akan menggunakan kembali soket yang sudah terbuka tersebut tanpa perlu melakukan proses handshake ulang, mempercepat eksekusi hingga 10 kali lipat.

2. Pipelining #

Secara standar, Ansible menyalin file modul Python ke server target, mengeksekusinya, lalu menghapusnya kembali. Proses menyalin file (file transfer) via SFTP/SCP ini membutuhkan I/O disk tambahan di server target.

Dengan mengaktifkan Pipelining di file ansible.cfg, Ansible akan mengirimkan kode modul Python secara langsung ke interpreter Python target melalui pipa input standar (stdin) SSH tanpa menuliskan file fisik ke disk target terlebih dahulu. Ini meminimalkan proses transfer file dan operasi tulis disk yang mempercepat waktu eksekusi task.

# Contoh konfigurasi optimasi SSH di ansible.cfg
[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=60s
pipelining = True

Anatomi Eksekusi Task Tanpa Agen #

Bagaimana sebenarnya sebuah tugas dapat dieksekusi di server target tanpa adanya agen? Di balik layar, Ansible melakukan proses yang sangat terstruktur:

  1. Kompilasi Modul: Ansible mengambil modul yang dipanggil di playbook kita (misalnya modul file) beserta parameter input yang kita tentukan, lalu membungkusnya menjadi satu file script Python mandiri (self-contained ZIP payload wrapper).
  2. Transfer Payload: Ansible membuka koneksi SSH (atau menggunakan soket ControlPersist yang sudah ada) dan mengirimkan script Python tersebut ke direktori temporer server target (biasanya di bawah ~/.ansible/tmp/).
  3. Eksekusi Lokal: Ansible menjalankan script Python tersebut menggunakan interpreter Python di server target. Script ini akan membaca parameter input, memeriksa kondisi sistem target, melakukan modifikasi jika diperlukan untuk mencapai kondisi akhir (desired state), lalu mengembalikan output status dalam format JSON.
  4. Penangkapan Output: Control Node menangkap output JSON tersebut dari standard output (stdout) SSH, memilah status apakah terjadi perubahan (changed: true), sukses tanpa perubahan (ok), atau gagal (failed: true).
  5. Pembersihan (Cleanup): Ansible menghapus kembali script Python temporer yang dikirimkan tadi dari server target untuk menjaga kebersihan sistem, kemudian menutup koneksi jika tidak ada tugas lanjutan.

Kita dapat memverifikasi sifat bersih ini. Jika kita memeriksa daftar proses yang aktif di server target setelah playbook selesai dijalankan, kita tidak akan menemukan proses latar belakang Ansible apa pun:

# Jalankan pengecekan proses aktif pasca eksekusi playbook
ssh [email protected] "ps aux | grep -i ansible"

# Output hanya akan menampilkan proses grep kita sendiri:
# admin 12345 0.0 0.1 1234 567 pts/0 S+ 09:30 0:00 grep -i ansible

Persyaratan Sistem pada Managed Node #

Karena arsitektur agentless ini, persyaratan minimum agar sebuah server dapat dikelola oleh Ansible sangatlah ringan dan hampir selalu sudah terpenuhi secara default pada distribusi Linux modern.

Persyaratan Utama Deskripsi
SSH Server (OpenSSH) Layanan SSH harus berjalan di port 22 (atau port kustom yang kita tentukan) untuk menerima koneksi dari Control Node.
Interpreter Python Python versi 3.x harus terpasang di server target karena sebagian besar modul standar Ansible ditulis menggunakan Python.
Akses Akun Pengguna Akun pengguna SSH dengan kunci publik (SSH Public Key) kita terdaftar, serta hak sudo passwordless jika tugas memerlukan akses administrator.

Penanganan Masalah Bootstrapping (Ketiadaan Python) #

Meskipun jarang terjadi, terkadang kita menemukan server minimalis (seperti beberapa image Docker minimalis atau router jaringan) yang tidak memiliki Python terpasang secara bawaan. Karena Ansible membutuhkan Python untuk menjalankan modulnya, bagaimana kita menginstalnya jika kita belum bisa menggunakan modul Ansible?

Ansible menyediakan modul khusus bernama raw. Berbeda dari modul standar, modul raw tidak mengirimkan kode Python, melainkan langsung meneruskan perintah shell murni via koneksi SSH. Kita dapat menggunakan modul raw ini untuk melakukan instalasi Python pertama kali (bootstrapping):

# Contoh Playbook Bootstrapping Python menggunakan modul raw
- name: Skenario inisialisasi instalasi Python di target minimalis
  hosts: all
  gather_facts: false # Harus dinonaktifkan karena setup facts membutuhkan Python!
  become: true

  tasks:
    - name: Pasang Python secara paksa menggunakan perintah raw shell
      raw: test -e /usr/bin/python3 || (apt-get update && apt-get install -y python3)
      changed_when: true

Setelah tugas raw di atas selesai dijalankan, server target kini telah memiliki Python dan siap dikelola menggunakan modul-modul standar Ansible lainnya.


Keuntungan Pendekatan Agentless #

Meniadakan agen dari arsitektur otomatisasi memberikan banyak keuntungan praktis yang signifikan bagi efisiensi tim engineering:

  1. Reduksi Permukaan Serangan (Attack Surface): Setiap agen software yang berjalan sebagai root di server target adalah target empuk bagi eksploitasi keamanan baru. Dengan model agentless, satu-satunya gerbang masuk yang perlu kita amankan adalah port SSH, yang mana sudah dikelola secara ketat dengan standar keamanan industri.
  2. Nol Overhead Administrasi: Kita tidak perlu membuat pipeline khusus untuk memperbarui versi agen di ribuan server target ketika rilis Ansible baru diluncurkan. Kita cukup memperbarui versi Ansible di satu tempat: Control Node kita.
  3. Efisiensi Sumber Daya Server: Server database kita dapat mengonsumsi 100% kapasitas RAM dan CPU miliknya untuk melayani transaksi query pengguna tanpa perlu berbagi resource dengan proses daemon agen pemantau konfigurasi yang terus-menerus berjalan di background.
  4. Kecepatan Onboarding Infrastruktur: Saat kita meluncurkan server baru di cloud, server tersebut dapat langsung kita kelola menggunakan Ansible dalam hitungan detik setelah SSH aktif. Kita tidak perlu menunggu proses instalasi repositori agen selesai dijalankan.

Trade-off dan Mitigasi Pendekatan Agentless #

Meskipun memiliki banyak kelebihan, arsitektur agentless juga memiliki beberapa keterbatasan konsekuensial yang harus kita pahami agar kita dapat melakukan mitigasi secara tepat.

Ketiadaan Deteksi Pergeseran Konfigurasi Secara Kontinu #

Karena tidak ada agen yang terus memantau sistem di background, Ansible tidak dapat secara instan mengetahui jika ada seseorang yang mengubah file konfigurasi penting secara manual. Pergeseran konfigurasi (configuration drift) ini baru akan terdeteksi saat kita menjalankan playbook kembali.

Solusi Mitigasi: #

Kita dapat mengintegrasikan eksekusi Ansible ke dalam sistem penjadwalan terpusat. Misalnya, kita dapat membuat cron job harian pada Control Node, atau membuat pipeline terjadwal di Gitlab CI/CD / Jenkins yang menjalankan playbook secara berkala (misalnya setiap malam) untuk memastikan kondisi server selalu kembali ke kondisi yang dideklarasikan di kode kita.

Ketergantungan Terhadap Akses Jaringan Inbound SSH #

Model push agentless mengharuskan Control Node untuk dapat membuka koneksi inbound ke server target. Jika server target berada di belakang jaringan NAT yang ketat, firewall korporasi, atau memiliki IP dinamis tanpa akses inbound, Ansible tidak akan dapat menjangkau server tersebut.

Solusi Mitigasi: #

Pada skenario jaringan tertutup ini, kita dapat menerapkan arsitektur Pull-mode. Ansible menyediakan perkakas bernama ansible-pull yang dapat dipasang lokal di server target melalui cron job. Skrip ansible-pull ini akan berjalan lokal di target, mengunduh playbook terbaru dari repositori Git internal kita (outbound connection), lalu menjalankannya secara lokal pada dirinya sendiri.


Ringkasan #

  • Agentless berarti Ansible tidak memerlukan instalasi perangkat lunak agen latar belakang (daemon) di managed node, melainkan memanfaatkan SSH dan Python standar sistem.
  • SSH Optimizations — Penggunaan ControlPersist menjaga soket SSH tetap terbuka guna menghindari handshake berulang, sementara Pipelining mengirim modul langsung ke memori target.
  • Zero-Bootstrapping — Kita dapat langsung mengelola server baru secara instan. Jika target tidak memiliki Python, kita dapat menggunakan modul raw untuk menginstalnya terlebih dahulu.
  • Keamanan Lebih Kuat — Menghilangkan agen memperkecil permukaan serangan keamanan (attack surface) karena kita hanya bergantung pada gerbang SSH yang sudah terenkripsi ketat.
  • Mitigasi Drift — Ketiadaan pemantau background aktif dapat kita mitigasi dengan mengintegrasikan Ansible ke dalam sistem penjadwalan otomatis atau pipeline CI/CD berkala.

← Sebelumnya: Kapan Digunakan?   Berikutnya: Node →

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