AWS EventBridge ile Olay Tabanlı Mimari Nasıl Kurulur?
Bulut mimarisinde “her şey birbirine bağlı ama birbirinden bağımsız olmalı” ilkesi kulağa çelişkili geliyor, değil mi? İşte tam burada olay tabanlı mimari devreye giriyor. AWS EventBridge, bu felsefeyi pratiğe döken, servisler arası gevşek bağlı iletişimi mümkün kılan güçlü bir araç. Klasik polling yaklaşımından ya da sıkı entegrasyonlardan sıkıldıysanız, EventBridge size farklı bir bakış açısı sunacak.
EventBridge Nedir ve Neden Önemlidir
AWS EventBridge, esasen bulut üzerindeki bir olay otobüsüdür. Lambda, SNS veya SQS ile basit entegrasyonlar yapıyor olabilirsiniz, ancak EventBridge bunları bir üst seviyeye taşır. Kendi hesabınızdaki AWS servisleri, üçüncü parti SaaS uygulamaları ve kendi uygulamalarınız arasında olay akışlarını yönetmenizi sağlar.
Klasik bir Lambda tetikleyici düşünün: S3’e dosya gelince Lambda çalışır. Bu işe yarar, ama ölçeklendiğinde karmaşıklaşır. Şimdi o olayı onlarca servise iletmeniz gerektiğinde, her birini tek tek bağlamak zorunda kalırsınız. EventBridge bu sorunu çözer: olayı bir kez alır, kurallara göre doğru hedeflere iletir.
Temel kavramlar şunlardır:
- Event Bus (Olay Otobüsü): Olayların iletildiği kanal. Default, custom ve partner event bus olmak üzere üç türü var
- Event (Olay): JSON formatında bir mesaj. Kaynak, detay tipi ve içerik barındırır
- Rule (Kural): Hangi olayların hangi hedeflere gideceğini belirleyen mantık
- Target (Hedef): Olayı alan servis. Lambda, SQS, SNS, Step Functions, Kinesis ve daha fazlası
- Event Archive: Olayları saklayıp ileride tekrar oynatma imkanı sunar
- Schema Registry: Olay yapılarını keşfetmenizi ve kaydetmenizi sağlar
İlk Event Bus ve Kural Oluşturma
Hemen pratiğe geçelim. AWS CLI ile custom bir event bus oluşturalım:
# Custom event bus oluştur
aws events create-event-bus
--name "production-events"
--region eu-west-1
# Oluşturulan bus'ı listele
aws events list-event-buses
--region eu-west-1
--query 'EventBuses[*].{Name:Name,Arn:Arn}'
--output table
Şimdi bu bus üzerine bir kural ekleyelim. Diyelim ki e-ticaret sistemimizde sipariş tamamlandığında tetiklenecek bir kural istiyoruz:
# Kural oluştur - sipariş tamamlanma olayı
aws events put-rule
--name "order-completed-rule"
--event-bus-name "production-events"
--event-pattern '{
"source": ["ecommerce.orders"],
"detail-type": ["OrderCompleted"],
"detail": {
"status": ["COMPLETED"],
"amount": [{"numeric": [">=", 100]}]
}
}'
--state ENABLED
--description "100 TL ve uzeri tamamlanan siparisler"
--region eu-west-1
Bu kural yalnızca 100 TL ve üzeri tamamlanan siparişleri yakalar. EventBridge’in content filtering özelliği sayesinde gereksiz olayların hedeflere ulaşmasını engelliyoruz. Bu hem maliyet hem de performans açısından kritik.
Gerçek Dünya Senaryosu: E-Ticaret Sipariş Yönetimi
Bir e-ticaret platformu düşünün. Sipariş tamamlandığında şunların yapılması gerekiyor:
- Muhasebe servisine bildirim gönder
- Kargo servisini tetikle
- Kullanıcıya e-posta ve SMS gönder
- Analitik sistemine veri aktar
- Stok sistemini güncelle
Eski yaklaşımda sipariş servisi bu beş servisi tek tek çağırırdı. Birinde hata olursa? Ya o servis down ise? EventBridge ile sipariş servisi sadece olayı yayar, geri kalanını EventBridge halleder.
Önce olayı gönderelim:
# Olay gönderme - uygulama kodundan ya da CLI ile test
aws events put-events
--entries '[
{
"Source": "ecommerce.orders",
"DetailType": "OrderCompleted",
"Detail": "{"orderId": "ORD-2024-001", "customerId": "USR-456", "amount": 350.00, "status": "COMPLETED", "items": [{"sku": "PROD-789", "quantity": 2}], "timestamp": "2024-01-15T10:30:00Z"}",
"EventBusName": "production-events"
}
]'
--region eu-west-1
Başarılı bir gönderimde FailedEntryCount: 0 görmeniz gerekir. Herhangi bir entry başarısız olduysa, o entry’nin ErrorCode ve ErrorMessage alanlarını inceleyin.
Lambda Hedefi Bağlama ve IAM Yapılandırması
EventBridge kurallarına Lambda fonksiyonu bağlamak yaygın kullanım senaryolarından biri. Ancak IAM izinlerini doğru yapılandırmak şart:
# Lambda'ya EventBridge'in invoke izni vermek için resource-based policy
aws lambda add-permission
--function-name "order-notification-handler"
--statement-id "EventBridgeInvoke"
--action "lambda:InvokeFunction"
--principal "events.amazonaws.com"
--source-arn "arn:aws:events:eu-west-1:123456789012:rule/production-events/order-completed-rule"
--region eu-west-1
# Lambda'yı rule'a target olarak ekle
aws events put-targets
--rule "order-completed-rule"
--event-bus-name "production-events"
--targets '[
{
"Id": "NotificationLambda",
"Arn": "arn:aws:lambda:eu-west-1:123456789012:function:order-notification-handler"
},
{
"Id": "KargoSQS",
"Arn": "arn:aws:sqs:eu-west-1:123456789012:kargo-queue",
"SqsParameters": {
"MessageGroupId": "kargo-orders"
}
}
]'
--region eu-west-1
Tek bir kurala birden fazla hedef ekleyebildiğimize dikkat edin. EventBridge bir olayı aynı anda 5 hedefin hepsine iletebilir. Bu paralel işleme capability’si güçlü bir özellik.
Terraform ile EventBridge Altyapısını Kod Olarak Yönetme
Production ortamında CLI ile uğraşmak yerine Infrastructure as Code kullanmak zorundasınız. İşte Terraform ile eksiksiz bir EventBridge kurulumu:
# main.tf - EventBridge yapılandırması
# Önce providers.tf dosyasını oluşturun
cat > eventbridge-setup.tf << 'EOF'
resource "aws_cloudwatch_event_bus" "production" {
name = "production-events"
tags = {
Environment = "production"
Team = "platform"
ManagedBy = "terraform"
}
}
resource "aws_cloudwatch_event_rule" "order_completed" {
name = "order-completed-rule"
event_bus_name = aws_cloudwatch_event_bus.production.name
description = "100 TL ve uzeri tamamlanan siparisler"
event_pattern = jsonencode({
source = ["ecommerce.orders"]
detail-type = ["OrderCompleted"]
detail = {
status = ["COMPLETED"]
amount = [{ numeric = [">=", 100] }]
}
})
state = "ENABLED"
}
resource "aws_cloudwatch_event_target" "lambda_target" {
rule = aws_cloudwatch_event_rule.order_completed.name
event_bus_name = aws_cloudwatch_event_bus.production.name
target_id = "NotificationLambda"
arn = aws_lambda_function.notification.arn
}
resource "aws_lambda_permission" "eventbridge_invoke" {
statement_id = "EventBridgeInvoke"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.notification.function_name
principal = "events.amazonaws.com"
source_arn = aws_cloudwatch_event_rule.order_completed.arn
}
# Dead Letter Queue - basarisiz olaylari yakala
resource "aws_sqs_queue" "dlq" {
name = "eventbridge-dlq"
message_retention_seconds = 1209600 # 14 gun
}
resource "aws_cloudwatch_event_archive" "production_archive" {
name = "production-events-archive"
event_source_arn = aws_cloudwatch_event_bus.production.arn
retention_days = 90
event_pattern = jsonencode({
source = ["ecommerce.orders", "ecommerce.users", "ecommerce.inventory"]
})
}
EOF
# Terraform planı çalıştır
terraform init
terraform plan -out=tfplan
terraform apply tfplan
Cross-Account Event Paylaşımı
Büyük organizasyonlarda farklı AWS hesapları arasında olay paylaşımı gerekir. Merkezi bir event bus üzerinden tüm hesapların olay göndermesine izin verebilirsiniz:
# Merkezi hesapta (hub) event bus policy güncelle
# Bu hesap: 111111111111 (hub)
# Kaynak hesap: 222222222222 (spoke)
aws events put-permission
--action "events:PutEvents"
--principal "222222222222"
--statement-id "AllowSpokeAccount"
--event-bus-name "central-event-bus"
--region eu-west-1
# Organizasyon genelinde izin vermek icin (daha kullanisli)
aws events put-permission
--action "events:PutEvents"
--principal "*"
--statement-id "AllowOrganization"
--condition '{"Type":"StringEquals","Key":"aws:PrincipalOrgID","Value":"o-xxxxxxxxxxxx"}'
--event-bus-name "central-event-bus"
--region eu-west-1
Bu yapıyla spoke hesabındaki mikro servisler, hub hesabındaki merkezi event bus’a olay gönderebilir. Log aggregation, güvenlik monitoring ve compliance raporlama için mükemmel bir pattern.
Event Archive ve Replay Özelliği
Production’da yaşadığınız bir sorundan sonra, “keşke o olayları tekrar çalıştırabilseydim” dediğiniz oluyor mu? EventBridge Archive ve Replay bunun için:
# Mevcut arşivleri listele
aws events list-archives
--region eu-west-1
# Belirli bir zaman aralığındaki olayları replay et
aws events start-replay
--replay-name "incident-2024-01-15-replay"
--source-arn "arn:aws:events:eu-west-1:123456789012:archive/production-events-archive"
--event-start-time "2024-01-15T08:00:00Z"
--event-end-time "2024-01-15T12:00:00Z"
--destination '{
"Arn": "arn:aws:events:eu-west-1:123456789012:event-bus/production-events",
"FilterArns": [
"arn:aws:events:eu-west-1:123456789012:rule/production-events/order-completed-rule"
]
}'
--region eu-west-1
# Replay durumunu kontrol et
aws events describe-replay
--replay-name "incident-2024-01-15-replay"
--region eu-west-1
Bu özellik özellikle yeni bir downstream servisi devreye aldığınızda çok işe yarar. Servisi bağlayıp geçmişteki olayları replay ederek “backfill” yapabilirsiniz.
CloudWatch ile EventBridge Monitoring
EventBridge’i kör çalıştırmak istemezsiniz. Metrikleri izlemek şart:
# EventBridge metriklerini sorgula
aws cloudwatch get-metric-statistics
--namespace "AWS/Events"
--metric-name "FailedInvocations"
--dimensions Name=EventBusName,Value=production-events
--start-time "2024-01-15T00:00:00Z"
--end-time "2024-01-15T23:59:59Z"
--period 3600
--statistics Sum
--region eu-west-1
# Alarm kur - basarisiz invocation'lar icin
aws cloudwatch put-metric-alarm
--alarm-name "EventBridge-FailedInvocations-High"
--alarm-description "EventBridge basarisiz invocation sayisi esigi asti"
--metric-name "FailedInvocations"
--namespace "AWS/Events"
--statistic Sum
--period 300
--evaluation-periods 2
--threshold 10
--comparison-operator GreaterThanThreshold
--dimensions Name=EventBusName,Value=production-events
--alarm-actions "arn:aws:sns:eu-west-1:123456789012:ops-alerts"
--region eu-west-1
İzlemeniz gereken kritik metrikler:
- MatchedEvents: Kural eşleşen olay sayısı
- FailedInvocations: Hedef invocation hataları
- InvocationsFailedToBeSentToDlq: DLQ’ya gönderilemeyen hatalı olaylar
- ThrottledRules: Rate limit aşımı
- Latency: Olay iletim gecikmesi
Input Transformer ile Olay Dönüşümü
Her hedef, olayı farklı bir formatta bekliyorsa ne yaparsınız? Input transformer ile olayı hedefe iletmeden önce dönüştürebilirsiniz:
# Input transformer ile olayi donustur
aws events put-targets
--rule "order-completed-rule"
--event-bus-name "production-events"
--targets '[
{
"Id": "SlackNotification",
"Arn": "arn:aws:lambda:eu-west-1:123456789012:function:slack-notifier",
"InputTransformer": {
"InputPathsMap": {
"orderId": "$.detail.orderId",
"amount": "$.detail.amount",
"customerId": "$.detail.customerId",
"timestamp": "$.time"
},
"InputTemplate": "{"text": "Yeni siparis tamamlandi!", "blocks": [{"type": "section", "text": {"type": "mrkdwn", "text": "*Siparis ID:* <orderId>\n*Musteri:* <customerId>\n*Tutar:* <amount> TL\n*Zaman:* <timestamp>"}}]}"
}
}
]'
--region eu-west-1
Input transformer’ın güzelliği şu: aynı olay, farklı hedeflere farklı formatlarda iletilebilir. Lambda’ya tam JSON, Slack’e mesaj formatı, SQS’e minimal veri gönderebilirsiniz.
Scheduler ile Zamanlanmış Olaylar
EventBridge sadece reaktif değil, proaktif de çalışabilir. EventBridge Scheduler ile cron benzeri görevler tanımlayabilirsiniz:
# Her gun saat 02:00'de rapor olusturan schedule
aws scheduler create-schedule
--name "daily-report-generator"
--schedule-expression "cron(0 2 * * ? *)"
--schedule-expression-timezone "Europe/Istanbul"
--target '{
"Arn": "arn:aws:lambda:eu-west-1:123456789012:function:daily-report",
"RoleArn": "arn:aws:iam::123456789012:role/scheduler-execution-role",
"Input": "{"reportType": "daily", "format": "pdf"}"
}'
--flexible-time-window '{
"Mode": "FLEXIBLE",
"MaximumWindowInMinutes": 15
}'
--region eu-west-1
# Tek seferlik gelecek tarihli schedule
aws scheduler create-schedule
--name "one-time-migration-2024-02-01"
--schedule-expression "at(2024-02-01T03:00:00)"
--schedule-expression-timezone "Europe/Istanbul"
--target '{
"Arn": "arn:aws:states:eu-west-1:123456789012:stateMachine:data-migration",
"RoleArn": "arn:aws:iam::123456789012:role/scheduler-execution-role",
"Input": "{"migrationVersion": "v2.0", "dryRun": false}"
}'
--flexible-time-window '{"Mode": "OFF"}'
--region eu-west-1
Klasik cron’dan farkı şu: Flexible Time Window özelliği ile belirttiğiniz süre içinde rastgele bir anda çalıştırarak “thundering herd” problemini önleyebilirsiniz. Yüzlerce Lambda’nın tam aynı anda tetiklenmesi yerine 15 dakikalık pencereye yayılır.
Best Practices ve Dikkat Edilecekler
Olay tasarımında dikkat edin:
- Olaylar immutable olmalı: Gönderilen olayı asla değiştirmeyin, yeni bir olay gönderin
- Detay tipi anlamlı olsun: “OrderCompleted” yerine “ecommerce.order.completed.v1” gibi versiyonlu kullanın
- Boyut sınırı: Tek bir olay maksimum 256 KB olabilir, büyük veriyi S3’e koyun, referansını iletin
Güvenlik için:
- Event bus’lara resource-based policy uygulayın
- Cross-account erişimlerde Organization ID condition kullanın
- Hassas verileri olaylara koymayın, referans ID ile S3 veya SSM Parameter Store’dan çekin
Maliyet optimizasyonu:
- Custom event bus kullanmak ücretsiz, olaylar için ücretlendirme yapılır (milyonda 1 USD civarı)
- Schema discovery açıkken ek maliyet oluşur, production’da ihtiyacınıza göre ayarlayın
- Event archive retention süresini gereksiz yere uzun tutmayın
Hata yönetimi:
- Kritik kurallar için DLQ mutlaka tanımlayın
- Retry politikasını hedef servisinize göre ayarlayın
- Dead letter olayları işlemek için ayrı bir süreç kurun
Yaygın Sorunlar ve Çözümleri
Olay hedeflere ulaşmıyor: İlk kontrol noktası IAM permissions. EventBridge’in hedefe yazma izni, hedefin EventBridge’den okuma izni. Lambda için lambda:InvokeFunction, SQS için sqs:SendMessage gerekir.
Event pattern eşleşmiyor: EventBridge’in test özelliğini kullanın. AWS Console’dan “Test event pattern” seçeneği ile JSON olayınızı pattern’e karşı test edebilirsiniz. CLI’dan da yapılabilir:
# Event pattern'i test et
aws events test-event-pattern
--event-pattern '{
"source": ["ecommerce.orders"],
"detail": {
"status": ["COMPLETED"]
}
}'
--event '{"source": "ecommerce.orders", "detail-type": "OrderCompleted", "detail": {"status": "COMPLETED", "amount": 250}}'
--region eu-west-1
Yüksek gecikme: Default event bus üzerinde çok fazla kural varsa, custom event bus kullanın. Kaynağa göre ayrı bus’lar, performansı artırır.
Sonuç
EventBridge, AWS ekosistemindeki en hafife alınan servislerden biri. Çoğu ekip hala Lambda’yı doğrudan tetikliyor ya da SNS/SQS ile karmaşık fan-out yapıları kuruyor. Oysa EventBridge bu karmaşıklığı ortadan kaldırıyor.
Olay tabanlı mimariye geçiş tek seferde olmuyor. Küçük başlayın: mevcut bir entegrasyonu EventBridge üzerine taşıyın, archive ve replay özelliklerini keşfedin, sonra yavaş yavaş diğer servisleri entegre edin. Schema Registry kullanmaya başlayın, olay sözlüğünüzü oluşturun.
En büyük kazanım servisler arası bağımlılığın azalmasıdır. Bir servis down olduğunda diğerleri etkilenmez, yeni bir servis eklemek için mevcut kodu değiştirmek gerekmez. Bu esneklik, özellikle büyüyen ekiplerde ve mikro servis mimarilerinde kritik bir avantaja dönüşür.
EventBridge’i production’a almadan önce monitoring alarmlarınızı, DLQ yapılandırmanızı ve cross-account izinlerinizi mutlaka gözden geçirin. İyi yapılandırılmış bir EventBridge kurulumu, gecenin üçünde sizi uyandıracak olayları ciddi ölçüde azaltır.
