Belajar UFW - Automation & IaC (Ansible & Scripting)
Series/Belajar UFW/Episode 20
Episode 20 of 23

Belajar UFW - Automation & IaC (Ansible & Scripting)

Mengotomasi pengelolaan firewall: menggunakan module community.general. ufw di Ansible untuk provisioning aturan allow, deny, dan policy, menulis bash script setup firewall yang idempotent, serta menerapkan ruleset ke banyak server secara konsisten

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

Sepanjang series ini kalian mengetik perintah ufw satu per satu. Di dunia nyata, kalian tidak akan melakukannya di 50 server — dan bahkan di satu server, mengulang perintah manual adalah sumber inkonsistensi. Episode 20 membawa UFW ke ranah Infrastructure as Code (IaC): mengelola ruleset sebagai kode yang bisa di-review, di-version, dan diterapkan ulang kapan saja.

Mengapa ini penting? Karena aturan firewall yang diketik manual tidak bisa diaudit (apakah server 5 sudah update?), tidak bisa direplikasi, dan mudah "jauh dari yang diharapkan". Sebagai kode, ruleset bisa diuji, di-commit ke git, dan diterapkan identik di mana-mana — ini fondasi untuk episode 21.

Ansible dan Module community.general.ufw

Ansible punya module khusus UFW: community.general.ufw. Module ini menangani hampir semua operasi yang kita pelajari — allow, deny, limit, delete, hingga default policy.

Persyaratan

Module ini membutuhkan paket community.general di koleksi Ansible:

Install koleksi community.general
ansible-galaxy collection install community.general

Playbook Dasar

Contoh playbook untuk server web produksi:

ufw.yml
- name: Konfigurasi firewall UFW
  hosts: webservers
  become: true
  tasks:
    - name: Install ufw
      ansible.builtin.apt:
        name: ufw
        state: present
 
    - name: Default policy deny incoming
      community.general.ufw:
        default: deny
        direction: incoming
 
    - name: Default policy allow outgoing
      community.general.ufw:
        default: allow
        direction: outgoing
 
    - name: Izinkan SSH
      community.general.ufw:
        rule: allow
        port: "22"
        proto: tcp
 
    - name: Izinkan HTTP dan HTTPS
      community.general.ufw:
        rule: allow
        port: "{{ item.port }}"
        proto: tcp
      loop:
        - port: "80"
        - port: "443"
 
    - name: Aktifkan UFW
      community.general.ufw:
        state: enabled

Perhatikan struktur tugasnya — setiap blok community.general.ufw setara dengan satu perintah UFW yang sudah kita pelajari:

Parameter ModulePerintah UFW Setara
rule: allow, port: 22, proto: tcpufw allow 22/tcp
rule: deny, from_ip: 203.0.113.66ufw deny from 203.0.113.66
rule: limit, port: 22ufw limit 22/tcp
default: deny, direction: incomingufw default deny incoming
state: enabledufw enable
delete: yesufw delete ...

Rule yang Lebih Kompleks

IP/subnet spesifik (episode 6) juga didukung penuh:

ufw-rules-lanjut.yml (potongan)
    - name: Izinkan subnet kantor ke SSH
      community.general.ufw:
        rule: allow
        from_ip: 203.0.113.0/24
        to_port: "22"
        proto: tcp
 
    - name: Deny IP mencurigakan
      community.general.ufw:
        rule: deny
        from_ip: 198.51.100.99

Note

Module community.general.ufw bersifat idempotent: menjalankan playbook dua kali menghasilkan state yang sama, tanpa mengubah apa pun di eksekusi kedua. Ini janji utama IaC — ruleset server selalu sama dengan definisi kode, apa pun yang terjadi di antara dua eksekusi.

Bash Scripting Idempotent

Tanpa Ansible, kalian bisa menulis bash script yang juga idempotent. Triknya: selalu cek state sebelum menambah/mengubah:

setup-ufw.sh
#!/usr/bin/env bash
set -euo pipefail
 
echo "==> Memastikan SSH diizinkan"
if ! sudo ufw status | grep -q "22/tcp.*ALLOW"; then
    sudo ufw allow 22/tcp
fi
 
echo "==> Default policies"
sudo ufw default deny incoming
sudo ufw default allow outgoing
 
echo "==> Layanan publik"
for port in 80/tcp 443/tcp; do
    if ! sudo ufw status | grep -q "$port"; then
        sudo ufw allow "$port"
    fi
done
 
echo "==> Rate limit SSH"
if ! sudo ufw status | grep -q "22/tcp.*LIMIT"; then
    sudo ufw limit 22/tcp
fi
 
echo "==> Aktifkan UFW"
sudo ufw enable
 
echo "==> Status akhir"
sudo ufw status verbose

Kunci idempotensinya: sebelum menambah aturan, periksa dengan ufw status; hanya tambah jika belum ada. Dengan set -euo pipefail, script berhenti segera saat ada error — tidak ada setup separuh jalan.

Jadikan executable dan jalankan:

Jalankan setup firewall
chmod +x setup-ufw.sh
./setup-ufw.sh

Menjalankan script dua kali berturut-turut seharusnya menghasilkan output yang sama dan tanpa error — itulah uji idempotensi.

Mengelola Profile dan File Rules via Kode

Application profiles (episode 7) juga bisa menjadi kode. Salin file profil ke repo kalian dan deploy dengan Ansible:

deploy-profiles.yml (potongan)
    - name: Deploy application profiles
      ansible.builtin.copy:
        src: "files/ufw/applications.d/{{ item }}"
        dest: "/etc/ufw/applications.d/{{ item }}"
        mode: "0644"
      loop:
        - app-internal
      notify: update ufw apps
 
  handlers:
    - name: update ufw apps
      ansible.builtin.command: ufw app update AppInternal
      changed_when: false

Dengan pola ini, profil, aturan, dan kebijakan semuanya hidup di repo — satu sumber kebenaran.

Workflow Tim yang Sehat

  1. Tulis ruleset sebagai kode (Ansible playbook atau bash script) di repository.
  2. Review via pull request — anggota tim lain membaca sebelum diterapkan.
  3. Terapkan di staging dulu — jalankan playbook di server uji, verifikasi.
  4. Terapkan ke produksi — playbook yang sama, identik.
  5. Audit otomatis — bandingkan state server dengan definisi kode (episode 21).

Tip

Mulai sederhana: bahkan satu setup-ufw.sh di git sudah jauh lebih baik daripada nol dokumentasi. Naik ke Ansible saat kalian mengelola beberapa server. Prinsipnya sama — ruleset adalah kode, dan kode harus di-version.

Common Pitfalls

  1. Playbook/script tidak idempotent: menambah aturan tanpa cek akan mengakumulasi duplikat setiap eksekusi. Selalu cek sebelum tambah.
  2. state: enabled tanpa rule SSH: playbook yang salah urutan (enable sebelum allow SSH) = server terkunci setelah deploy.
  3. Lupa become: true: module UFW butuh root; tanpa privilege, semua tugas gagal.
  4. Script dengan set -e yang tidak sengaja mati: guard setiap perintah yang berisiko gagal saat state sudah benar.
  5. Mendokumentasikan aturan tanpa menguji: jalankan playbook di server uji dulu — "berhasil di laptop" bukan bukti.

Penutup

Pada episode 20 ini, kalian telah mengotomasi UFW.

Inti yang harus dibawa pulang:

  • Module community.general.ufw memetakan semua operasi UFW ke YAML yang idempotent.
  • Bash script idempotent: cek ufw status sebelum menambah aturan.
  • Profil dan ruleset bisa dikelola sebagai kode di repository.
  • Workflow sehat: kode → review → staging → produksi → audit.
  • Uji playbook di staging; jangan langsung ke produksi.

Di episode 21 selanjutnya, kita perbesar skala: Manajemen Banyak Server & Audit — policy rule terpusat berbasis inventory, mendeteksi drift antara server dan definisi kode, mengekspor ruleset untuk backup, serta menyusun compliance checklist. Sampai jumpa di episode 21!

Belajar UFW - Automation & IaC (Ansible & Scripting) | Belajar UFW