Menambah satu worker baru ke armada pemecahan CAPTCHA Anda seharusnya tidak berarti login SSH manual ke setiap server, menyalin skrip Python satu per satu, lalu mengatur systemd service dengan tangan. Itulah yang dihapus oleh Ansible playbook di panduan ini: satu perintah ansible-playbook menerapkan worker yang sama persis — kode, konfigurasi, service systemd — ke tiga server atau tiga puluh server sekaligus, lalu memperbaruinya lewat rolling update tanpa mematikan seluruh armada.
Terraform menyediakan server dan jaringannya; Ansible masuk setelah itu untuk mengisi server tersebut. Role captcha-worker di bawah ini mencakup instalasi dependensi, deployment kode worker, template konfigurasi, dan service systemd dalam satu paket yang idempotent — jalankan ulang kapan saja tanpa efek samping. Susunan ini juga cocok untuk tim yang men-deploy worker di beberapa region sekaligus, misalnya AWS ap-southeast-1 (Singapura) untuk trafik regional dan ap-southeast-3 (Jakarta) untuk latensi lokal — cukup tambahkan host baru ke inventory, tidak perlu menulis ulang playbook-nya.
Struktur Proyek Ansible untuk Worker CaptchaAI
Playbook ini mengikuti struktur role standar Ansible — satu role captcha-worker yang dipakai ulang oleh tiga playbook berbeda (deploy, rolling update, health check):
ansible/
├── inventory/
│ ├── production.yml
│ └── staging.yml
├── roles/
│ └── captcha-worker/
│ ├── tasks/
│ │ └── main.yml
│ ├── templates/
│ │ ├── captcha-worker.service.j2
│ │ └── config.yaml.j2
│ ├── handlers/
│ │ └── main.yml
│ └── defaults/
│ └── main.yml
├── playbooks/
│ ├── deploy.yml
│ ├── rolling-update.yml
│ └── health-check.yml
└── ansible.cfg
Inventory: Staging vs Production
Inventory memisahkan host staging dari production, dan variabelnya sengaja dibuat berbeda. Worker staging memakai captchaai_log_level: debug dan versi release candidate supaya mudah dipantau saat diuji; worker production memakai warning dan concurrency yang lebih tinggi (20 dibanding 5) karena menangani trafik nyata:
# inventory/production.yml
all:
children:
captcha_workers:
hosts:
worker-1:
ansible_host: 10.0.1.10
worker-2:
ansible_host: 10.0.1.11
worker-3:
ansible_host: 10.0.1.12
vars:
captchaai_concurrency: 20
captchaai_poll_interval: 3
captchaai_log_level: warning
worker_version: "1.3.0"
# inventory/staging.yml
all:
children:
captcha_workers:
hosts:
staging-worker-1:
ansible_host: 10.0.2.10
vars:
captchaai_concurrency: 5
captchaai_poll_interval: 5
captchaai_log_level: debug
worker_version: "1.4.0-rc1"
Angka captchaai_concurrency di sini menentukan berapa banyak task yang dikirim tiap worker ke API CaptchaAI secara paralel — ini yang perlu Anda selaraskan dengan alokasi thread pada paket CaptchaAI Anda, bukan sekadar dinaikkan asal-asalan (lihat catatan skala di bagian playbook di bawah).
Role captcha-worker: Konfigurasi Inti
Role ini punya empat bagian — variabel default, task, template, dan handler — yang bersama-sama menginstal dependensi, men-deploy kode worker, dan mendaftarkannya sebagai systemd service.
Variabel Default
# roles/captcha-worker/defaults/main.yml
captchaai_concurrency: 10
captchaai_poll_interval: 5
captchaai_log_level: info
captchaai_timeout: 300
captchaai_retries: 3
worker_version: "latest"
worker_user: captcha
worker_dir: /opt/captcha-worker
worker_venv: /opt/captcha-worker/venv
Task: Instalasi dan Deploy
Task-nya idempotent — menjalankan ulang playbook yang sama tidak membuat user, virtualenv, atau dependensi duplikat, karena Ansible mengecek state saat ini sebelum mengubah apa pun:
# roles/captcha-worker/tasks/main.yml
---
- name: Create worker user
ansible.builtin.user:
name: "{{ worker_user }}"
system: true
shell: /usr/sbin/nologin
home: "{{ worker_dir }}"
- name: Create worker directory
ansible.builtin.file:
path: "{{ worker_dir }}"
state: directory
owner: "{{ worker_user }}"
mode: "0755"
- name: Install system dependencies
ansible.builtin.apt:
name:
- python3
- python3-venv
- python3-pip
state: present
update_cache: true
- name: Create Python virtual environment
ansible.builtin.command:
cmd: python3 -m venv {{ worker_venv }}
creates: "{{ worker_venv }}/bin/activate"
- name: Install Python dependencies
ansible.builtin.pip:
name:
- requests>=2.31.0
- pyyaml>=6.0
virtualenv: "{{ worker_venv }}"
- name: Deploy worker application
ansible.builtin.copy:
src: captcha_worker.py
dest: "{{ worker_dir }}/captcha_worker.py"
owner: "{{ worker_user }}"
mode: "0644"
notify: restart captcha-worker
- name: Deploy configuration
ansible.builtin.template:
src: config.yaml.j2
dest: "{{ worker_dir }}/config.yaml"
owner: "{{ worker_user }}"
mode: "0600"
notify: restart captcha-worker
- name: Deploy systemd service
ansible.builtin.template:
src: captcha-worker.service.j2
dest: /etc/systemd/system/captcha-worker.service
mode: "0644"
notify:
- reload systemd
- restart captcha-worker
- name: Enable and start service
ansible.builtin.systemd:
name: captcha-worker
enabled: true
state: started
Template Konfigurasi dan Service
# roles/captcha-worker/templates/config.yaml.j2
# CaptchaAI Worker Configuration
# Managed by Ansible — do not edit manually
concurrency: {{ captchaai_concurrency }}
poll_interval: {{ captchaai_poll_interval }}
timeout: {{ captchaai_timeout }}
retries: {{ captchaai_retries }}
log_level: {{ captchaai_log_level }}
Template service systemd-nya menambahkan hardening dasar (NoNewPrivileges, ProtectSystem: strict) supaya worker berjalan dengan privilege minimum yang benar-benar dibutuhkan:
# roles/captcha-worker/templates/captcha-worker.service.j2
[Unit]
Description=CaptchaAI CAPTCHA Solving Worker
After=network.target
Wants=network-online.target
[Service]
Type=simple
User={{ worker_user }}
WorkingDirectory={{ worker_dir }}
ExecStart={{ worker_venv }}/bin/python {{ worker_dir }}/captcha_worker.py
Environment=CAPTCHAAI_API_KEY={{ captchaai_api_key }}
Restart=always
RestartSec=10
TimeoutStopSec=30
# Security hardening
NoNewPrivileges=true
ProtectSystem=strict
ReadWritePaths={{ worker_dir }}
[Install]
WantedBy=multi-user.target
Handler Restart
Task Deploy worker application, Deploy configuration, dan Deploy systemd service di atas semuanya memicu handler ini lewat notify — restart hanya terjadi kalau ada file yang benar-benar berubah, bukan di setiap run:
# roles/captcha-worker/handlers/main.yml
---
- name: reload systemd
ansible.builtin.systemd:
daemon_reload: true
- name: restart captcha-worker
ansible.builtin.systemd:
name: captcha-worker
state: restarted
Playbook: Deploy, Rolling Update, dan Health Check
Tiga playbook di atas role yang sama ini menangani tiga skenario operasional yang berbeda.
Deploy
Playbook ini meminta API key lewat vars_prompt saat dijalankan (jangan hardcode di file), mengecek konektivitas dulu sebelum apply, lalu memverifikasi status service setelahnya:
# playbooks/deploy.yml
---
- name: Deploy CaptchaAI Workers
hosts: captcha_workers
become: true
vars_prompt:
- name: captchaai_api_key
prompt: "Enter CaptchaAI API key"
private: true
pre_tasks:
- name: Verify connectivity
ansible.builtin.ping:
roles:
- captcha-worker
post_tasks:
- name: Wait for worker to start
ansible.builtin.wait_for:
port: 8080
timeout: 30
ignore_errors: true
- name: Check worker status
ansible.builtin.systemd:
name: captcha-worker
register: worker_status
- name: Report status
ansible.builtin.debug:
msg: "Worker {{ inventory_hostname }}: {{ worker_status.status.ActiveState }}"
Rolling Update
serial: 1 memastikan hanya satu host yang diperbarui pada satu waktu, dan max_fail_percentage: 0 menghentikan seluruh rollout begitu satu host gagal — armada tetap melayani task dari host lain selama proses berjalan:
# playbooks/rolling-update.yml
---
- name: Rolling Update CaptchaAI Workers
hosts: captcha_workers
become: true
serial: 1 # Update one host at a time
max_fail_percentage: 0
tasks:
- name: Drain current tasks
ansible.builtin.command:
cmd: "{{ worker_venv }}/bin/python {{ worker_dir }}/drain.py"
timeout: 120
ignore_errors: true
- name: Stop worker
ansible.builtin.systemd:
name: captcha-worker
state: stopped
- name: Deploy new version
ansible.builtin.copy:
src: "captcha_worker.py"
dest: "{{ worker_dir }}/captcha_worker.py"
owner: "{{ worker_user }}"
mode: "0644"
- name: Update dependencies
ansible.builtin.pip:
requirements: "{{ worker_dir }}/requirements.txt"
virtualenv: "{{ worker_venv }}"
- name: Start worker
ansible.builtin.systemd:
name: captcha-worker
state: started
- name: Verify worker health
ansible.builtin.uri:
url: "http://localhost:8080/health"
return_content: true
register: health
until: health.status == 200
retries: 6
delay: 10
- name: Report update result
ansible.builtin.debug:
msg: "{{ inventory_hostname }} updated — {{ health.content }}"
Health Check
Playbook ini dijalankan tanpa become untuk cek API (task Check API connectivity berjalan lewat delegate_to: localhost, bukan di server worker), lalu menampilkan saldo akun lewat res.php:
# playbooks/health-check.yml
---
- name: Check CaptchaAI Worker Health
hosts: captcha_workers
become: false
gather_facts: false
tasks:
- name: Check systemd service
ansible.builtin.systemd:
name: captcha-worker
register: service_status
become: true
- name: Check API connectivity
ansible.builtin.uri:
url: "https://ocr.captchaai.com/res.php?key={{ captchaai_api_key }}&action=getbalance&json=1"
return_content: true
register: api_check
delegate_to: localhost
run_once: true
- name: Summary
ansible.builtin.debug:
msg: |
Host: {{ inventory_hostname }}
Service: {{ service_status.status.ActiveState }}
API Balance: {{ (api_check.content | from_json).request }}
Sebelum menambah worker baru lewat inventory, cek dulu alokasi thread paket CaptchaAI Anda — captchaai_concurrency di atas hanya berguna kalau paket API-nya menampung angka itu. Tiga worker dengan concurrency 20 berarti sampai 60 task berjalan paralel; paket ADVANCE ($90/bulan, 50 thread) sudah mepet di titik itu, sementara CORPORATE ($240/bulan, 150 thread) memberi ruang untuk worker keempat dan kelima tanpa task tertahan di antrean. Ini pertimbangan nyata untuk tim scraping dan automation Indonesia yang biasanya menambah worker bertahap sesuai volume klien, bukan sekaligus di awal.
Menjalankan Playbook Ansible
# Deploy to staging
ansible-playbook -i inventory/staging.yml playbooks/deploy.yml
# Rolling update in production
ansible-playbook -i inventory/production.yml playbooks/rolling-update.yml
# Health check
ansible-playbook -i inventory/production.yml playbooks/health-check.yml
# Limit to specific hosts
ansible-playbook -i inventory/production.yml playbooks/deploy.yml --limit worker-1
Jalankan --limit worker-1 dulu setiap kali Anda mengubah role — memvalidasi perubahan di satu host sebelum menyebar ke seluruh armada jauh lebih murah daripada memperbaiki tiga puluh host sekaligus.
Mengatasi Masalah Umum
Sebagian besar kegagalan playbook ada di empat pola berikut:
| Masalah | Penyebab | Solusi |
|---|---|---|
| Host tidak dapat dijangkau | Kunci SSH tidak dikonfigurasi | Tambahkan kunci SSH: ssh-copy-id user@host |
| Service tidak mau start | Env var API key tidak ada | Periksa vars_prompt atau gunakan Ansible Vault |
| Rolling update terhenti | Health check gagal | Periksa journalctl -u captcha-worker; tambah retries |
| Konfigurasi tidak diterapkan | Handler tidak terpicu | Jalankan dengan --force-handlers atau tambahkan changed_when: true |
Pertanyaan Umum
Bagaimana cara menyimpan API key CaptchaAI dengan aman di Ansible?
Jangan taruh API key polos di file inventory. Enkripsi dengan Ansible Vault: ansible-vault encrypt_string 'YOUR_API_KEY' --name 'captchaai_api_key', lalu referensikan variabel terenkripsi itu di group_vars atau saat menjalankan playbook.
Berapa banyak worker yang bisa ditangani satu playbook sekaligus?
Tidak ada batas dari sisi Ansible — struktur inventory ini sudah teruji untuk puluhan host dalam satu file. Batas praktisnya ada di alokasi thread paket CaptchaAI Anda dan kapasitas jaringan server, bukan di Ansible itu sendiri.
Apakah rolling update ini menyebabkan downtime pada task yang sedang berjalan?
Task Drain current tasks dijalankan lebih dulu supaya worker menyelesaikan task yang sedang jalan sebelum service dihentikan, dan serial: 1 memastikan hanya satu host yang update di satu waktu — armada tetap menerima task dari host lain selama proses berlangsung.
Bisakah inventory ini menampung worker di beberapa region sekaligus, misalnya Singapura dan Jakarta?
Bisa. Tambahkan grup host baru di inventory/production.yml dengan ansible_host masing-masing region — misalnya AWS ap-southeast-1 untuk Singapura atau ap-southeast-3 untuk Jakarta — lalu jalankan playbook yang sama dengan --limit kalau Anda hanya ingin menargetkan satu region dulu.
Apa bedanya Ansible dengan Terraform untuk deployment worker CaptchaAI?
Terraform menyediakan infrastrukturnya — membuat server dan jaringan. Ansible mengonfigurasi isi server yang sudah ada — instal dependensi, deploy kode, atur service. Keduanya dipakai berurutan: Terraform membuat armada, Ansible yang mengisinya.
Langkah Selanjutnya
Anda sudah punya playbook untuk deploy dan mengelola armada worker CaptchaAI — yang belum adalah API key-nya. Ambil API key CaptchaAI Anda dan jalankan deploy.yml ke server pertama hari ini.
Panduan terkait: