Compute dan storage platform data TokoKita kini tersebar di banyak layanan: API ingestion, worker ETL, database, dan object storage. Semua komponen tersebut harus saling terhubung, tetapi tidak semuanya boleh dijangkau dari internet publik. Database pesanan yang terbuka ke publik adalah resep insiden keamanan, dan sayangnya kesalahan seperti ini masih sering terjadi di dunia nyata. Chapter ini membahas cara merancang jaringan cloud yang benar: VPC, subnet, security group, network ACL, hingga private endpoint.

VPC, Subnet, dan Availability Zone #

VPC (Virtual Private Cloud) adalah jaringan IP privat yang terisolasi di dalam akun cloud kita. TokoKita memakai blok CIDR 10.0.0.0/16, yang menyediakan 65.536 alamat IP untuk seluruh komponen platform. Batas VPC adalah batas kepercayaan pertama kita: layanan di dalam VPC tidak otomatis bisa dijangkau dari luar, sehingga permukaan serangan mengecil drastis.

Subnet adalah potongan VPC yang berada di satu Availability Zone (AZ). Dua jenis subnet menentukan arsitektur kita:

  • Public subnet: punya route ke internet gateway, sehingga bisa menerima koneksi masuk dari internet (misalnya load balancer).
  • Private subnet: tanpa route ke internet gateway; komponen di dalamnya bisa memulai koneksi keluar lewat NAT gateway, tetapi tidak bisa dijangkau dari luar.

Database dan worker ETL milik TokoKita menempati private subnet. Pemisahan ini penting: kebocoran alamat IP publik tidak serta-merta membuka akses ke data pelanggan.

Arsitektur Jaringan TokoKita #

Diagram berikut merangkum topologi jaringan yang kita bangun. Perhatikan bahwa hanya load balancer yang berdiri di subnet public; seluruh jalur data berada di private subnet.

Alurnya berlapis: pembeli hanya menyentuh internet gateway dan load balancer; API ingestion menerima permintaan lalu menulis ke database di subnet data; worker ETL membaca database, menulis ke object storage lewat VPC endpoint, dan mengunduh dependensi lewat NAT gateway.

Simulasi Validator Jaringan #

Konfigurasi jaringan cloud pada dasarnya adalah matematika CIDR dan aturan allow/deny — dua hal yang bisa kita modelkan dengan modul ipaddress dari standard library. Skrip berikut memeriksa tiga hal: klasifikasi subnet dari tabel route, validasi usulan subnet baru terhadap blok VPC, dan evaluasi aturan network ACL untuk lalu lintas masuk.

python
"""Validator jaringan mini untuk VPC TokoKita: klasifikasi subnet,
containment subnet baru di dalam VPC, dan evaluasi aturan network ACL."""
import ipaddress

VPC = ipaddress.ip_network("10.0.0.0/16")
SUBNET = {  # nama -> (jaringan, tujuan route keluar)
    "app-public":  (ipaddress.ip_network("10.0.1.0/24"), ["igw"]),
    "etl-private": (ipaddress.ip_network("10.0.2.0/24"), ["nat"]),
    "db-private":  (ipaddress.ip_network("10.0.3.0/24"), ["nat"]),
}
ATURAN = [  # (nomor, cidr sumber, port awal, port akhir, aksi) -- urutan nomor
    (80,  ipaddress.ip_network("203.0.113.0/24"), 22, 22, "deny"),
    (90,  ipaddress.ip_network("10.0.0.0/16"), 22, 22, "allow"),
    (100, ipaddress.ip_network("10.0.2.0/24"), 5432, 5432, "allow"),
    (120, ipaddress.ip_network("0.0.0.0/0"), 443, 443, "allow"),
]
DEFAULT = "deny"  # tanpa aturan yang cocok, lalu lintas ditolak


def evaluasi(sumber, port):
    """Cari keputusan ACL untuk ip sumber -> port tujuan."""
    src = ipaddress.ip_address(sumber)
    for nomor, cidr, p_awal, p_akhir, aksi in ATURAN:
        if src in cidr and p_awal <= port <= p_akhir:
            return aksi, f"aturan #{nomor}"
    return DEFAULT, "default"


print("[1] Klasifikasi subnet (public bila route-nya lewat igw)")
for nama, (net, rute) in SUBNET.items():
    jenis = "public" if "igw" in rute else "private"
    print(f"  {nama:<12} {net}  -> {jenis}")

print("\n[2] Usulan subnet baru untuk layanan streaming")
for kandidat in ("10.1.0.0/24", "10.0.4.0/24"):
    net = ipaddress.ip_network(kandidat)
    dalam = net.subnet_of(VPC)
    bentrok = [n for n, (s, _) in SUBNET.items() if s.overlaps(net)]
    status = "DITERIMA" if dalam and not bentrok else "DITOLAK"
    print(f"  {kandidat}: {status} (di dalam VPC={dalam}, bentrok={bentrok or 'tidak ada'})")

print("\n[3] Evaluasi lalu lintas masuk (nomor aturan terkecil menang)")
UJI = [
    ("worker ETL -> database", "10.0.2.15", 5432),
    ("dashboard BI -> database", "10.0.1.40", 5432),
    ("pembeli internet -> web", "198.51.100.7", 443),
    ("internet -> SSH web", "198.51.100.7", 22),
    ("kantor cabang -> SSH web", "203.0.113.5", 22),
    ("internal VPC -> SSH web", "10.0.1.40", 22),
]
for nama, ip, port in UJI:
    aksi, sumber_aturan = evaluasi(ip, port)
    print(f"  {nama:<28} {ip:>13}:{port:<5} = {aksi.upper():<5} ({sumber_aturan})")

Output yang Dihasilkan:

text
[1] Klasifikasi subnet (public bila route-nya lewat igw)
  app-public   10.0.1.0/24  -> public
  etl-private  10.0.2.0/24  -> private
  db-private   10.0.3.0/24  -> private

[2] Usulan subnet baru untuk layanan streaming
  10.1.0.0/24: DITOLAK (di dalam VPC=False, bentrok=tidak ada)
  10.0.4.0/24: DITERIMA (di dalam VPC=True, bentrok=tidak ada)

[3] Evaluasi lalu lintas masuk (nomor aturan terkecil menang)
  worker ETL -> database           10.0.2.15:5432  = ALLOW (aturan #100)
  dashboard BI -> database         10.0.1.40:5432  = DENY  (default)
  pembeli internet -> web       198.51.100.7:443   = ALLOW (aturan #120)
  internet -> SSH web           198.51.100.7:22    = DENY  (default)
  kantor cabang -> SSH web       203.0.113.5:22    = DENY  (aturan #80)
  internal VPC -> SSH web          10.0.1.40:22    = ALLOW (aturan #90)

Mari kita telaah baris-baris kode di atas:

  1. Baris 6-10 (SUBNET): setiap subnet menyimpan jaringan CIDR dan daftar tujuan route. Kunci "igw" menandai subnet public karena satu-satunya perbedaan public/private memang ada di tabel route, bukan di subnetnya sendiri.
  2. Baris 11-17 (ATURAN): aturan ACL berupa tuple berurutan. Aturan #80 menolak SSH dari blok 203.0.113.0/24 sebelum aturan #90 yang lebih longgar mengizinkan SSH dari seluruh VPC — nomor kecil dievaluasi lebih dulu.
  3. Baris 20-26 (evaluasi): fungsi mengembalikan aksi dari aturan pertama yang cocok. Operator in pada objek ip_network memeriksa keanggotaan alamat di dalam CIDR.
  4. Baris 36-42 (validasi subnet): subnet_of() memeriksa containment dan overlaps() memeriksa tumpang tindih. Usulan 10.1.0.0/24 ditolak karena berada di luar blok VPC — perilaku yang sama dengan validasi penyedia cloud saat kita membuat subnet.

Perhatikan hasil evaluasi ketiga: dashboard BI dari subnet app tidak bisa mencapai database karena tidak ada aturan yang mengizinkannya. Perilaku ini disengaja — hanya worker ETL (subnet 10.0.2.0/24) yang boleh menulis ke database.

Security Group dan Network ACL #

Cloud menyediakan dua lapis filter. Keduanya bekerja pada prinsip default deny: semua lalu lintas ditolak kecuali secara eksplisit diizinkan.

AspekSecurity GroupNetwork ACL
Cakupantingkat instancetingkat subnet
Statefulya — balasan otomatis diizinkantidak — aturan inbound dan outbound terpisah
Jenis aturanhanya allowallow dan deny
Evaluasisemua aturan dipertimbangkannomor terkecil menang

Security group yang menempel di database TokoKita cukup satu aturan: izinkan port 5432 dari security group worker ETL. Referensi antar security group (bukan CIDR IP) membuat aturan tetap valid ketika IP worker berganti karena autoscaling.

Private Endpoint vs Public Internet #

Worker ETL perlu menulis ke object storage. Ada dua jalur: lewat internet publik (NAT gateway → internet gateway → endpoint publik layanan) atau lewat private endpoint di dalam VPC.

AspekLewat internet publikPrivate endpoint
Jalur lalu lintaskeluar VPC ke endpoint publiktetap di jaringan internal provider
Biayadikenai biaya pemrosesan NAT + egresstanpa NAT; umumnya tanpa biaya egress
Latensibergantung jalur internetlebih stabil dan umumnya lebih rendah
Enkripsi in transittetap TLS, tetapi IP tujuan publikIP privat dari jaringan VPC

Konsep ini adalah lanjutan langsung dari Chapter Object Storage yang membahas bucket dan access key. Referensi resmi lengkap ada di Amazon VPC User Guide dan Private Service Connect Google Cloud .

Dengan jaringan yang benar, komponen platform data kita aman dan saling terhubung. Pertanyaan berikutnya: apakah kita harus memasang dan mengelola sendiri database serta engine pemrosesan di atas jaringan ini, atau menyerahkan operasionalnya ke penyedia cloud? Chapter Managed Data Services membahas pertukarannya.