โ† Semua pembelajaran / Astro Nol โ†’ Portal Berita
Fase 11 ยท Performa & Capstone

Biaya & runbook insiden

Dua hal yang menutup proyek ini: angka yang membuktikan migrasinya sepadan, dan dokumen yang dibaca orang saat panik.

Intisari

  • Ukur biaya sebelum dan sesudah dengan tag yang sama, supaya bisa dibandingkan.
  • Penghematan terbesar biasanya egress, bukan komputasi.
  • Runbook per gejala, bukan per komponen โ€” orang mencari berdasarkan apa yang mereka lihat.
  • Setiap runbook harus punya langkah pertama yang aman yang tidak memperburuk keadaan.
  • Tulis post-mortem tanpa menyalahkan orang; yang dicari adalah sistem yang membiarkannya terjadi.

Memberi tag supaya bisa diukur

# Tag semua sumber daya dengan skema yang sama
aws ecs tag-resource --resource-arn <arn> \
  --tags key=Proyek,value=portal key=Lingkungan,value=produksi key=Komponen,value=web

# Aktifkan tag sebagai kategori biaya
aws ce update-cost-allocation-tags-status \
  --cost-allocation-tags-status TagKey=Proyek,Status=Active

Perbandingan sebelum-sesudah

KomponenCI3 (sebelum)Astro (sesudah)Penyebab perubahan
KomputasiEC2 untuk PHP-FPMECS FargateLebih sedikit request ke origin
Egress~10,8 TB/bulan~1,6 TB/bulanCache hit 60% โ†’ 93%
RDSSamaSama atau lebih kecilBeban baca turun drastis
Penyimpanan gambarS3 + egressR2, egress nolPindah penyedia
NAT GatewayAdaLebih rendahVPC Endpoint
ALBAdaNol kalau pakai TunnelCloudflare Tunnel
CloudWatchRendahNaikLog terstruktur lebih banyak

Penghematan terbesar datang dari egress, dan itu konsekuensi langsung dari Fase 8. Dengan asumsi respons rata-rata 30 KB dan tarif egress standar, memangkas 500 ribu request/jam jadi ~87 ribu memindahkan sekitar 9 TB per bulan dari tagihan AWS-mu โ€” nilainya biasanya beberapa ratus dolar, sebelum menghitung apa pun yang lain. Ukur ukuran respons rata-ratamu yang sebenarnya untuk angka yang tepat; jangan pakai angka contoh ini di presentasi.

# Biaya per layanan bulan ini
aws ce get-cost-and-usage \
  --time-period Start=2026-08-01,End=2026-09-01 \
  --granularity MONTHLY --metrics UnblendedCost \
  --group-by Type=DIMENSION,Key=SERVICE \
  --filter '{"Tags":{"Key":"Proyek","Values":["portal"]}}' \
  --query 'ResultsByTime[0].Groups[?Metrics.UnblendedCost.Amount>`10`].
           {layanan:Keys[0],biaya:Metrics.UnblendedCost.Amount}' \
  --output table

Alarm anggaran

aws budgets create-budget --account-id 123456789012 --budget '{
  "BudgetName": "portal-bulanan",
  "BudgetLimit": {"Amount": "1200", "Unit": "USD"},
  "TimeUnit": "MONTHLY",
  "BudgetType": "COST",
  "CostFilters": {"TagKeyValue": ["user:Proyek$portal"]}
}' --notifications-with-subscribers '[{
  "Notification": {"NotificationType":"FORECASTED","ComparisonOperator":"GREATER_THAN",
                   "Threshold":110,"ThresholdType":"PERCENTAGE"},
  "Subscribers": [{"SubscriptionType":"EMAIL","Address":"[email protected]"}]
}]'

Pakai FORECASTED, bukan ACTUAL: kamu ingin tahu bahwa kamu akan melewati anggaran, bukan bahwa kamu sudah melewatinya.

Runbook per gejala

GejalaLangkah pertamaTersangka
Situs lambat, semua halamanPeriksa cache hit ratio CloudflareCache Rule berubah, purge everything, origin jenuh
5xx melonjakPeriksa jumlah task & log errorDeploy buruk, OOM, database
Halaman artikel 502Periksa health check ECSkeepAliveTimeout < ALB, task berputar
Member tidak bisa loginPeriksa koneksi database & tabel sesiPool habis, replica lag
Pembayaran tidak masukPeriksa log webhook & Security Events CloudflareWAF memblokir webhook, tanda tangan salah
Paywall bocorPurge cache seluruh artikel premiumCache Rule salah, halaman menyetel cookie
Trafik Google turunPeriksa Search ConsoleRedirect rusak, kanonik salah, noindex nyasar
Iklan tidak munculPeriksa CSP & ClientRouterCSP terlalu ketat, skrip tidak dijalankan ulang
Artikel baru tidak munculPeriksa purge cache tagToken API kedaluwarsa, TTL terlalu panjang
Task ECS berputar terusLihat stoppedReasonSecret hilang, OOM, health check

Perhatikan bahwa langkah pertama untuk "paywall bocor" adalah purge, bukan menyelidiki. Setiap detik kebocoran berlangsung berarti lebih banyak orang mendapat isi berbayar gratis dari cache edge. Hentikan pendarahannya dulu, cari penyebabnya kemudian. Untuk sebagian besar gejala lain, urutannya terbalik โ€” jangan restart apa pun sebelum tahu apa yang terjadi, karena restart menghapus bukti.

Contoh satu runbook

## Gejala: pembayaran tidak masuk

Dampak: pelanggan membayar tapi langganan tidak aktif. Prioritas TERTINGGI.

Langkah 1 โ€” apakah webhook sampai?
  Logs Insights, 1 jam terakhir:
    fields @timestamp, order_id, level
    | filter msg like /webhook/
    | stats count() by level

  Tidak ada baris sama sekali โ†’ webhook tidak sampai. Lanjut ke 2.
  Ada baris level=error                โ†’ lanjut ke 3.

Langkah 2 โ€” apakah Cloudflare memblokirnya?
  Dashboard โ†’ Security โ†’ Events, filter path = /api/midtrans-webhook
  Kalau ada yang diblokir: periksa aturan skip WAF (Fase 6).
  Perbaikan cepat: tambahkan aturan Skip untuk path itu.

Langkah 3 โ€” verifikasi tanda tangan gagal?
  Cek MIDTRANS_SERVER_KEY di task yang berjalan cocok dengan dashboard Midtrans.
  Cek gross_amount tidak dikonversi (Fase 6).

Langkah 4 โ€” pulihkan yang tertinggal
  Jalankan penyapu manual:
    aws ecs run-task --cluster portal --task-definition portal-tugas \
      --overrides '{"containerOverrides":[{"name":"tugas",
        "command":["node","tugas.mjs","sapu-pesanan"]}]}'

Langkah 5 โ€” verifikasi
  SELECT COUNT(*) FROM langganan
  WHERE status='menunggu' AND dibuat_pada < NOW() - INTERVAL 30 MINUTE;
  Harus mendekati nol.

Eskalasi: kalau belum selesai dalam 30 menit, hubungi dukungan Midtrans
dengan daftar order_id yang terpengaruh.

Post-mortem

BagianIsinya
RingkasanApa yang rusak, berapa lama, siapa terdampak
LinimasaWaktu demi waktu, termasuk kapan diketahui
Akar penyebabKenapa sistemnya mengizinkan ini terjadi
Kenapa tidak tertangkap lebih awalSering lebih berharga daripada akar penyebabnya
TindakanKonkret, ada pemiliknya, ada tenggatnya

Tanpa menyalahkan orang, dan itu bukan sekadar kesopanan. Post-mortem yang mencari siapa yang salah menghasilkan orang yang menyembunyikan kesalahan, dan insiden berikutnya jadi lebih lama ditemukan. Pertanyaannya bukan "siapa yang menghapus aturan itu" melainkan "kenapa satu orang bisa menghapus aturan itu tanpa review, dan kenapa tidak ada alarm yang menyala".

Baris "kenapa tidak tertangkap lebih awal" sering menghasilkan perbaikan yang lebih bernilai daripada memperbaiki penyebabnya. Insiden 5 menit dan insiden 5 jam bisa punya akar penyebab yang sama persis โ€” yang membedakan hanya apakah ada yang memberitahumu.

Yang harus ada sebelum kamu tidur nyenyak

ItemSudah?
Rollback deploy dalam satu perintahFase 10
Rollback platform dalam satu aturanFase 9
Cadangan database teruji pemulihannyaFase 10
Alarm untuk 5xx, webhook, koneksi DB, penyimpananFase 10
Uji asap otomatis tiap deployFase 9
Runbook per gejalaMateri ini
stale-if-error panjang di semua halaman publikFase 1
Origin tidak bisa dihubungi langsungFase 8

Baris ketujuh layak digarisbawahi: dengan stale-if-error sehari penuh, origin yang tumbang total tetap menyisakan portal yang menyajikan artikel dari edge. Pembaca melihat berita yang terlambat beberapa jam alih-alih halaman error โ€” dan kamu punya waktu memperbaiki tanpa tekanan.

Latihan: aktifkan tag alokasi biaya dan ambil rincian biaya bulan berjalan per layanan. Tulis runbook untuk tiga gejala teratas di tabel โ€” pilih yang paling mungkin terjadi di portalmu. Lalu uji satu runbook dengan benar-benar menjalankan langkahnya di lingkungan uji, dan perbaiki bagian yang ternyata tidak sesuai kenyataan.

Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.