L
Cloud Architecture & Serverless • Literally Web ID

Arsitektur Serverless Berbasis Event-Driven di AWS Lambda dan EventBridge

⏱️ 18 menit baca • 📅 13 Oct 2026 • 👁️ 1 views
Arsitektur Serverless Berbasis Event-Driven di AWS Lambda dan EventBridge

1. Konteks Industri & Analisis Akar Masalah

Dalam lanskap arsitektur web modern, sistem berbasis monolitik atau bahkan mikroservis berbasis server tradisional (seperti EC2, droplet VPS, atau instance on-premise yang menjalankan Nginx, Apache, PHP-FPM, atau Node.js) sering kali menghadapi bottleneck struktural yang parah saat menghadapi lonjakan traffic yang tidak terduga. Masalah klasik ini berkisar dari kehabisan alokasi koneksi database, overhead memori dari proses worker yang idle, hingga inefisiensi biaya operasional karena infrastruktur harus selalu menyala (provisioned capacity) 24/7 meskipun beban trafik berada di titik terendah (misalnya pada tengah malam).

Sebelum adopsi arsitektur Event-Driven berbasis serverless di AWS Lambda dan EventBridge, sistem backend tradisional memerlukan pengelolaan infrastruktur yang kompleks. Sebagai contoh, sebuah platform e-commerce yang memproses ribuan transaksi per detik harus mengonfigurasi Load Balancer (ALB), autoscaling group, penyesuaian parameter pm.max_children pada PHP-FPM, pengelolaan antrean (queue) menggunakan Redis atau RabbitMQ dengan Supervisor yang berjalan di atas sistem operasi Linux, hingga pemantauan file log secara manual menggunakan Fail2ban dan rotasi log kustom.

[Sebelum: Arsitektur Tradisional Berbasis Server]
Client -> Cloudflare (CDN) -> Nginx/ALB -> Node.js/PHP-FPM Cluster -> MySQL/Redis Cluster
(Masalah: Bottleneck koneksi, Idle compute cost, Kompleksitas autoscaling)

[Sesudah: Arsitektur Event-Driven Serverless]
Client -> Cloudflare -> API Gateway / S3 -> AWS Lambda -> Amazon EventBridge -> Consumer Lambdas / SQS -> Aurora Serverless / DynamoDB
(Keunggulan: True pay-as-you-go, Zero idle cost, Otomatis scale-to-zero, Loosely coupled)

Analisis akar masalah dari arsitektur tradisional adalah keterikatan waktu nyata (synchronous coupling) dan pemborosan kapasitas yang disProvisioning. Ketika terjadi lonjakan trafik, antrean permintaan menumpuk di web server, mengakibatkan latency melonjak tajam, memori server habis (OOM Killer triggered), dan kegagalan sistem secara keseluruhan (cascading failure).

Dengan beralih ke arsitektur Event-Driven menggunakan AWS Lambda dan Amazon EventBridge, paradigma bergeser dari penanganan permintaan sinkron menjadi pemrosesan event asinkron yang terdistribusi. Setiap komponen tidak saling mengenal secara langsung (loosely coupled), melainkan berkomunikasi melalui bus event terpusat. Hal ini memangkas biaya infrastruktur hingga 70% dan memberikan elastisitas tanpa batas (infinite scaling) tanpa intervensi manual dari DevOps engineer.

2. Konsep Inti & Deep Dive Arsitektur

Arsitektur Event-Driven (EDA) berfokus pada produksi, deteksi, konsumsi, dan reaksi terhadap event—yakni perubahan signifikan dalam keadaan suatu sistem. Dalam ekosistem AWS, komponen utama yang bertindak sebagai saraf pusat adalah Amazon EventBridge (sebelumnya dikenal sebagai CloudWatch Events), sementara AWS Lambda berfungsi sebagai unit komputasi stateless yang mengeksekusi logika bisnis.

Alur Kerja di Balik Layar (Under the Hood)

  1. Event Producer: Sumber event (bisa berupa layanan AWS seperti S3, DynamoDB Streams, API Gateway, kustom aplikasi, atau SaaS pihak ketiga) memancarkan sebuah objek JSON yang merepresentasikan event ke Amazon EventBridge Bus.
  2. EventBridge Rules: Event Bus menerima event tersebut dan membandingkannya dengan Event Patterns yang telah didefinisikan. Aturan ini bertindak sebagai filter cerdas (misalnya, hanya meneruskan event dengan detail-type: 'OrderPlaced' dan region: 'ap-southeast-1').
  3. Targets Dispatcher: Event yang cocok diteruskan ke Target yang terikat pada aturan tersebut. Target dapat berupa fungsi AWS Lambda, antrean SQS, Step Functions, atau SNS topic.
  4. Lambda Execution Environment Initialization:
    • Cold Start: Jika belum ada wadah (container) yang siap, AWS Lambda harus mengalokasikan instance baru, mengunduh kode deployment dari S3, menginisialisasi runtime (Node.js, Python, Go), dan menjalankan kode inisialisasi di luar fungsi handler (handler initialization).
    • Warm Start: Jika wadah masih aktif dari eksekusi sebelumnya, fungsi langsung mengeksekusi kode handler, menghasilkan latensi milidetik.
  5. Asynchronous Execution & Retry: EventBridge menangani pengiriman event dengan jaminan pengiriman setidaknya sekali (at-least-once delivery). Jika fungsi Lambda gagal, EventBridge dapat dikonfigurasi untuk melakukan retry secara otomatis atau mengirimkan pesan yang gagal ke Dead Letter Queue (DLQ) SQS.
+----------------+       +-------------------------+       +----------------------+
| Event Producer | ----> | Amazon EventBridge Bus  | ----> | EventBridge Rules    |
+----------------+       +-------------------------+       +----------------------+
                                                                      |
                                                                      v
+----------------+       +-------------------------+       +----------------------+
| Database / S3  | <---- | AWS Lambda (Handler)    | <---- | Target Dispatcher    |
+----------------+       +-------------------------+       +----------------------+

3. Perbandingan Komparatif / Analisis Pendekatan

Untuk memahami nilai strategis dari arsitektur serverless Event-Driven, mari kita lakukan analisis komparatif mendalam terhadap pendekatan tradisional berbasis server (EC2/VPS).

Parameter Komparasi Server Tradisional (EC2 + Nginx + Node.js) Serverless Event-Driven (Lambda + EventBridge)
Model Biaya Provisioned Capacity (Bayar per jam/bulan, selalu aktif) Pay-as-you-go (Bayar per milidetik eksekusi dan jumlah pemanggilan)
Skalabilitas Manual atau berbasis Auto Scaling Group (latensi 3-5 menit) Otomatis instan (instant scaling, skala dari 0 hingga ribuan dalam detik)
Maintenance & Patching Tanggung jawab penuh engineer (OS updates, security hardening) Fully managed oleh AWS (Zero server management)
Cold Start Latency Tidak ada (selalu warm, kecuali server reboot) Ada (berkisar antara 100ms hingga beberapa detik tergantung runtime)
Batas Eksekusi Tanpa batas waktu ketat (long-running process didukung) Maksimal 15 menit per eksekusi fungsi Lambda
Kompleksitas Jaringan Memerlukan konfigurasi Nginx, reverse proxy, SSL, firewall Dikelola secara abstrak oleh API Gateway & EventBridge
Debugging & Tracing Akses SSH langsung, tail log file /var/log/nginx/ Bergantung pada AWS CloudWatch Logs, X-Ray, dan distributed tracing
Resource Overhead Tinggi (RAM & CPU terpakai saat idle) Nol saat idle (Scale-to-zero)

[!TIP] Gunakan pendekatan hibrida jika aplikasi Anda memiliki proses long-running yang memakan waktu >15 menit (seperti enkoding video masif atau training model AI). Pindahkan proses tersebut ke AWS ECS dengan Fargate, sementara logika berbasis event tetap ditangani oleh AWS Lambda.

4. Prasyarat Sistem & Persiapan Lingkungan

Sebelum mulai mengonfigurasi infrastruktur kode, pastikan lingkungan pengembangan lokal Anda memiliki dependensi berikut:

  1. AWS CLI (v2) terinstal dan dikonfigurasi dengan kredensial IAM yang memiliki hak akses administrator atau deployment yang memadai (aws configure).
  2. Terraform (v1.5+) atau AWS CDK untuk implementasi Infrastructure as Code (IaC).
  3. Node.js (v20.x LTS) atau Go (v1.22+) sebagai runtime backend untuk fungsi Lambda.
  4. jq untuk pemrosesan JSON di terminal Linux/macOS.

Verifikasi instalasi AWS CLI:

aws --version
aws sts get-caller-identity

Pastikan variabel lingkungan dasar telah disetel pada sistem Anda:

export AWS_REGION="ap-southeast-1"
export ENVIRONMENT="production"

5. Panduan Implementasi Langkah demi Langkah

Berikut adalah implementasi lengkap menggunakan Terraform untuk menyiapkan infrastruktur EventBridge Custom Bus, IAM Role yang menerapkan prinsip Least Privilege, dan fungsi AWS Lambda berbasis Node.js yang memproses event pesanan masuk.

Struktur Direktori Proyek

. |-- main.tf |-- variables.tf |-- outputs.tf `-- src/     `-- handler.js

1. Kode Fungsi Lambda (src/handler.js)

'use strict';

/**
 * Lambda Handler untuk memproses Event dari EventBridge
 */
exports.handler = async (event, context) => {
    console.log('Event diterima:', JSON.stringify(event, null, 2));
    
    const {
        source,
        'detail-type': detailType,
        detail
    } = event;

    try {
        if (detailType === 'OrderPlaced') {
            const { orderId, customerId, amount } = detail;
            
            // Validasi payload event
            if (!orderId || !amount) {
                throw new Error('Payload event tidak valid: orderId dan amount wajib diisi.');
            }

            console.log(`Memproses pesanan ID: ${orderId} untuk Customer: ${customerId} dengan nominal: ${amount}`);
            
            // Simulasi pemrosesan bisnis (misalnya integrasi pembayaran atau simpan ke database)
            await processPayment({ orderId, customerId, amount });

            return {
                statusCode: 200,
                body: JSON.stringify({ message: `Pesanan ${orderId} berhasil diproses.` })
            };
        } else {
            console.log(`Detail-type tidak dikenali: ${detailType}`);
            return {
                statusCode: 400,
                body: JSON.stringify({ message: `Unsupported detail-type: ${detailType}` })
            };
        }
    } catch (error) {
        console.error('Error saat memproses event:', error);
        // Lempar error agar EventBridge dapat melakukan retry atau meneruskan ke DLQ
        throw error;
    }
};

async function processPayment(orderData) {
    // Simulasi latensi jaringan database/payment gateway
    return new Promise((resolve) => setTimeout(resolve, 250));
}

2. Konfigurasi Terraform (main.tf)

terraform {
  required_version = ">= 1.5.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
    archive = {
      source  = "hashicorp/archive"
      version = "~> 2.4"
    }
  }
}

provider "aws" {
  region = var.aws_region
}

variable "aws_region" {
  type    = string
  default = "ap-southeast-1"
}

variable "environment" {
  type    = string
  default = "production"
}

# 1. IAM Role untuk Lambda dengan Least Privilege
resource "aws_iam_role" "lambda_exec" {
  name = "order_processor_lambda_role_${var.environment}"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Principal = {
          Service = "lambda.amazonaws.com"
        }
      }
    ]
  })
}

# 2. Kebijakan CloudWatch Logs untuk Lambda
resource "aws_iam_policy" "lambda_logging" {
  name         = "lambda_logging_${var.environment}"
  description = "IAM policy untuk menulis log ke CloudWatch"

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow"
        Action = [
          "logs:CreateLogGroup",
          "logs:CreateLogStream",
          "logs:PutLogEvents"
        ]
        Resource = "arn:aws:logs:*:*:*"
      }
    ]
  })
}

resource "aws_iam_role_policy_attachment" "lambda_logs_attach" {
  role       = aws_iam_role.lambda_exec.name
  policy_arn = aws_iam_policy.lambda_logging.arn
}

# 3. Arsipkan Kode Sumber Lambda
data "archive_file" "lambda_zip" {
  type        = "zip"
  source_dir  = "${path.module}/src"
  output_path = "${path.module}/lambda_function.zip"
}

# 4. AWS Lambda Function
resource "aws_lambda_function" "order_processor" {
  filename         = data.archive_file.lambda_zip.output_path
  function_name    = "order-processor-${var.environment}"
  role             = aws_iam_role.lambda_exec.arn
  handler          = "handler.handler"
  source_code_hash = data.archive_file.lambda_zip.output_base64sha256
  runtime          = "nodejs20.x"
  memory_size      = 512
  timeout          = 30

  environment {
    variables = {
      ENV = var.environment
    }
  }
}

# 5. Amazon EventBridge Custom Bus
resource "aws_cloudwatch_event_bus" "custom_bus" {
  name = "ecommerce-event-bus-${var.environment}"
}

# 6. EventBridge Rule untuk menyaring OrderPlaced
resource "aws_cloudwatch_event_rule" "order_rule" {
  name           = "capture-order-placed-${var.environment}"
  description    = "Tangkap event pesanan baru masuk"
  event_bus_name = aws_cloudwatch_event_bus.custom_bus.name

  event_pattern = jsonencode({
    source      = ["com.ecommerce.orders"]
    detail-type = ["OrderPlaced"]
  })
}

# 7. Target EventBridge ke Lambda
resource "aws_cloudwatch_event_target" "lambda_target" {
  rule           = aws_cloudwatch_event_rule.order_rule.name
  event_bus_name = aws_cloudwatch_event_bus.custom_bus.name
  target_id      = "OrderProcessorLambdaTarget"
  arn            = aws_lambda_function.order_processor.arn
}

# 8. Izin Lambda agar dapat dipanggil oleh EventBridge
resource "aws_lambda_permission" "allow_eventbridge" {
  statement_id  = "AllowExecutionFromEventBridge"
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.order_processor.function_name
  principal     = "events.amazonaws.com"
  source_arn    = aws_cloudwatch_event_rule.order_rule.arn
}

Perintah Eksekusi Terminal

# Inisialisasi Terraform
terraform init

# Validasi konfigurasi
terraform validate

# Rencanakan penerapan infrastruktur
terraform plan -out=tfplan

# Terapkan infrastruktur ke AWS
terraform apply tfplan

6. Bedah Kode & Penjelasan Detail Baris Kunci

Mari kita bedah beberapa komponen paling krusial dari implementasi di atas untuk memastikan pemahaman arsitektural yang mendalam:

  1. Prinsip Least Privilege pada IAM Role (aws_iam_role & aws_iam_policy): Perhatikan bahwa fungsi Lambda hanya diberikan izin untuk berinteraksi dengan AWS CloudWatch Logs (logs:CreateLogGroup, logs:PutLogEvents). Tidak ada izin liar seperti AdministratorAccess atau AmazonS3FullAccess. Jika fungsi Lambda disusupi melalui kerentanan Remote Code Execution, penyerang tidak memiliki akses ke sumber daya AWS lainnya.

  2. Event Pattern Filtering di EventBridge (aws_cloudwatch_event_rule):

    event_pattern = jsonencode({
      source      = ["com.ecommerce.orders"],
      detail-type = ["OrderPlaced"]
    })
    

    Penyaringan ini terjadi di tingkat infrastruktur AWS sebelum fungsi Lambda dipanggil. Artinya, event yang tidak sesuai dengan pola ini dibuang atau diabaikan oleh EventBridge, sehingga mencegah pemanggilan Lambda yang tidak perlu dan menghemat biaya komputasi secara signifikan.

  3. Lambda Permission (aws_lambda_permission): Baris ini adalah konfigurasi krusial yang sering dilupakan oleh pemula. Resource-based policy pada AWS Lambda harus secara eksplisit mengizinkan events.amazonaws.com untuk memanggil fungsi tersebut melalui aksi lambda:InvokeFunction. Tanpa izin ini, EventBridge akan gagal memicu Lambda meskipun aturan telah dibuat dengan benar.

7. Skenario Produksi & Studi Kasus Dunia Nyata

[!IMPORTANT] Dalam skenario high-concurrency (misalnya event Flash Sale dengan 50.000 request per detik), pengiriman event langsung dari EventBridge ke Lambda tanpa perantara dapat menyebabkan throttling atau lonjakan koneksi database hilir (downstream database exhaustion).

Untuk mengatasi hal ini, arsitektur produksi yang dianjurkan adalah menyisipkan Amazon SQS (Simple Queue Service) sebagai penyangga (buffer) di antara EventBridge dan AWS Lambda:

Event Producer -> EventBridge -> SQS Queue (Buffer) -> AWS Lambda (Batch Processing)

Keuntungan Pendekatan SQS Buffer:

  • Rate Limiting & Concurrency Control: SQS memungkinkan Anda membatasi jumlah konkurensi Lambda (Reserved Concurrent Executions) sehingga database tidak kebanjiran koneksi bersamaan.
  • Batching: Lambda dapat dikonfigurasi untuk membaca pesan dari SQS secara berkelompok (misalnya BatchSize = 10), meningkatkan efisiensi pemrosesan dan mengurangi jumlah eksekusi Lambda.
  • Built-in Dead Letter Queue (DLQ): Pesan yang gagal diproses setelah jumlah percobaan tertentu secara otomatis dipindahkan ke DLQ untuk analisis forensik tanpa menghentikan aliran transaksi utama.

8. Common Pitfalls, Anti-Patterns & Solusi

Berikut adalah jebakan umum dan anti-pola yang sering ditemukan pada arsitektur serverless di lingkungan produksi:

  1. Anti-Pattern: Menghubungkan RDS Database secara Langsung tanpa Connection Pooling

    • Masalah: Setiap kali fungsi Lambda melakukan Cold Start atau skala naik, fungsi tersebut membuka koneksi TCP baru ke database relasional (MySQL/PostgreSQL). Lonjakan 1.000 Lambda instan akan membuka 1.000 koneksi database, menyebabkan database langsung crash.
    • Solusi: Selalu gunakan AWS RDS Proxy di antara fungsi Lambda dan database relasional untuk mengelola, berbagi, dan melakukan pool koneksi database secara efisien.
  2. Pitfall: Mengabaikan Cold Start pada VPC Configuration

    • Masalah: Menempatkan fungsi Lambda di dalam VPC kustom tanpa konfigurasi Hyperplane ENI (pada arsitektur Lambda modern) dapat menambah latensi Cold Start hingga 10 detik karena proses alokasi Elastic Network Interface.
    • Solusi: Tempatkan Lambda di dalam VPC hanya jika mutlak diperlukan untuk mengakses sumber daya privat (seperti database internal). Pastikan menggunakan runtime modern (Node.js 20, Go) dan optimalkan ukuran paket deployment.
  3. Anti-Pattern: Synchronous Waiting di Event-Driven Architecture

    • Masalah: Mengirim event ke EventBridge, namun fungsi pengirim menunggu respons secara sinkron menggunakan HTTP polling.
    • Solusi: Rancang alur komunikasi secara asinkron murni. Gunakan WebSocket API Gateway atau notifikasi push (SNS/Firebase) untuk memberitahu klien di sisi frontend ketika proses backend telah selesai.

9. Benchmark, Metrik Kinerja & Tuning Performa

Untuk mengukur kinerja sistem Event-Driven yang telah dibangun, gunakan tool pengujian beban seperti k6 atau Artillery untuk memancarkan event uji ke custom event bus melalui API Gateway.

Contoh Skrip Pengujian k6 (load-test.js)

import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = {
    stages: [
        { duration: '30s', target: 100 }, // Ramp-up ke 100 virtual users
        { duration: '1m', target: 500 },  // Beban puncak 500 virtual users
        { duration: '30s', target: 0 },   // Ramp-down
    ],
};

export default function () {
    const url = 'https://your-api-gateway-endpoint.amazonaws.com/prod/events';
    const payload = JSON.stringify({
        source: 'com.ecommerce.orders',
        'detail-type': 'OrderPlaced',
        detail: {
            orderId: `ORD-${Math.floor(Math.random() * 1000000)}`,
            customerId: 'CUST-998877',
            amount: 150.75
        }
    });

    const params = {
        headers: {
            'Content-Type': 'application/json',
            'X-Amz-Target': 'AWSEvents.PutEvents'
        },
    };

    const res = http.post(url, payload, params);
    check(res, {
        'status adalah 200': (r) => r.status === 200,
        'latensi di bawah 200ms': (r) => r.timings.duration < 200,
    });

    sleep(1);
}

Metrik Utama CloudWatch yang Wajib Dipantau:

  • Invocations: Total jumlah pemanggilan fungsi Lambda.
  • Errors: Jumlah eksekusi yang menghasilkan pengecualian unhandled (unhandled exceptions).
  • Throttles: Jumlah pemanggilan yang ditolak karena melebihi batas konkurensi akun AWS.
  • Duration: Waktu eksekusi rata-rata, persentil p95, dan p99.
  • EventBridge FailedInvocations: Jumlah event yang gagal dikirim ke target akibat kesalahan konfigurasi IAM atau timeout target.

10. Checklist Penerapan Produksi & Kesimpulan

Sebelum meluncurkan arsitektur ini ke lingkungan produksi, pastikan seluruh item dalam checklist berikut telah terpenuhi:

  • Keamanan IAM: Apakah semua fungsi Lambda menggunakan IAM Role terpisah dengan kebijakan Least Privilege?
  • Error Handling & DLQ: Apakah Amazon SQS Dead Letter Queue atau EventBridge DLQ telah dikonfigurasi untuk menangkap event yang gagal?
  • Database Connection Management: Jika menggunakan RDS, apakah AWS RDS Proxy telah diaktifkan untuk mencegah lonjakan koneksi?
  • Concurrency Limits: Apakah parameter Reserved Concurrent Executions telah diset pada fungsi Lambda untuk melindungi layanan hilir dari kelebihan beban?
  • Monitoring & Alarms: Apakah alarm CloudWatch telah dibuat untuk memantau metrik Errors dan Throttles yang mengirimkan notifikasi ke PagerDuty atau Slack?
  • Infrastructure as Code: Apakah seluruh infrastruktur didefinisikan menggunakan Terraform/CDK dan dikontrol melalui pipeline CI/CD?

Dengan mengimplementasikan arsitektur Event-Driven berbasis AWS Lambda dan Amazon EventBridge secara disiplin sesuai panduan ini, Anda telah membangun sistem terdistribusi yang tidak hanya sangat skalabel dan tangguh terhadap lonjakan traffic ekstrem, tetapi juga sangat efisien dari segi biaya operasional.

🏷️ Tags: #Aws #Serverless #Lambda #Cloud Architecture #Eventbridge