Gözlemlenebilirlik ve Service Mesh'ler Nereye Gidiyor
Access log çağıranı, route'u ve latency'yi zaten yazıyor. Route bazlı metrikler bedava değil, kullanıcı token'ı maskeleme istiyor ve AWS kendi mesh'ini kapatıyor.
Bir service mesh size üç şey vaat eder: kimlik, dayanıklılık ve gözlemlenebilirlik. Bu seri ilk ikisini hesapta zaten duran primitive’lerden kurdu: kimliği 104. bölümde, dayanıklılığı 106. bölümde. Üçüncüsü gözlemlenebilirlik ve insanların bedava geleceğini varsaydığı parça tam olarak bu. Yarısı gerçekten bedava geliyor. Tek satır uygulama kodu yazmadan, her çağrı tek bir JSON satırı yazıyor: çağıran servis, route, status ve latency. Ortada hiçbir sidecar yok.
Diğer yarısının faturası var. Route bazlı metrikler, fiyat etiketi olan bir opt-in. Üstelik size bütün bunları gösteren log pipeline’ı, 104. bölümün bir custom header’a binmek zorunda bıraktığı kullanıcı token’ını saklayabilecek pipeline’ın ta kendisi. İki yarı da burada: telemetri ve onun bir sızıntıya dönüşmesini engelleyen kontrol. Bu bölüm aynı zamanda serinin bittiği yer; son kısmı, bütün bunların içinde durduğu endüstri sorusuna bir adım geriden bakıyor. Serinin arkasındaki POC deploy edilmiş değil; aşağıdaki kurulum, ölçtüğüm sonuçlar değil, çalıştırmayı planladığım konfigürasyon.
Telemetri access log’un içinde
Access log’lar alan seçmeli çalışır ve güvenlik hikâyesinin tamamı bu özellikte. AWS mekanizmayı açıkça anlatıyor: “To specify the access details, you select $context variables, a log format, and a log group destination” (logging kurulumu). $context listesi kapalı bir isim kümesidir. REST access log’ları için $context.request.header.* diye bir değişken yoktur; dolayısıyla rastgele bir custom header, onu taşıyan bir alanı bilerek yazmadıkça access log’a düşemez. Bilmeye değer dar bir istisna var: $context.requestOverride.header.header_name, entegrasyon isteğindeki header override’ını log’lar. Kullanıcı iddiasını bir override içinde adlandırmayın.
Bunu mesh telemetrisine çeviren alanlar kimlik alanları ve onları AWS_IAM sizin yerinize dolduruyor (access-log değişkenleri). $context.identity.caller: “The principal identifier of the caller that signed the request. Supported for resources that use IAM authorization.” $context.identity.userArn: “The Amazon Resource Name (ARN) of the effective user identified after authentication.” $context.identity.principalOrgId: “The AWS organization ID.” Ve $context.identity.vpceId: “The VPC endpoint ID of the VPC endpoint making the request… Present only when you have a private API.” Bunları $context.resourcePath, $context.httpMethod, $context.status, $context.responseLatency ve $context.integrationLatency ile eşleyin. Bir alan zorunlu: “The access log format must include at least $context.requestId or $context.extendedRequestId.”
103. bölüm stage’e AccessLogFormat.jsonWithStandardFields() koymuştu; makul bir başlangıç ama işin ilginç yerine gelmiyor. Standart alanlar requestId, caller, resourcePath ve status taşır; userArn, principalOrgId, vpceId ve iki latency alanı dışarıda kalır. Onları açıkça yazın:
import * as cdk from 'aws-cdk-lib';
import * as apigateway from 'aws-cdk-lib/aws-apigateway';
import * as logs from 'aws-cdk-lib/aws-logs';
const accessLogs = new logs.LogGroup(this, 'OrdersAccessLogs', {
retention: logs.RetentionDays.ONE_MONTH,
});
// Yapısı gereği alan seçmeli. Yalnızca burada adı geçen $context değişkenleri
// yazılır ve REST access log'unda $context.request.header.* diye bir değişken
// yoktur; yani kullanıcı iddiası bu satıra kazara düşemez.
const accessLogFormat = apigateway.AccessLogFormat.custom(
JSON.stringify({
requestId: '$context.requestId', // zorunlu: bu ya da extendedRequestId
resourcePath: '$context.resourcePath',
httpMethod: '$context.httpMethod',
status: '$context.status',
responseLatency: '$context.responseLatency',
integrationLatency: '$context.integrationLatency',
// Kim çağırdı. Bunları AWS_IAM doldurur; handler'ın yapması gereken bir şey yok.
callerPrincipal: '$context.identity.caller',
callerArn: '$context.identity.userArn',
callerOrgId: '$context.identity.principalOrgId',
vpceId: '$context.identity.vpceId', // yalnızca private API'lerde
}),
);
this.api = new apigateway.RestApi(this, 'OrdersApi', {
restApiName: 'orders',
// endpointConfiguration ve defaultMethodOptions 103. bölümdeki gibi.
deployOptions: {
stageName: 'v1',
accessLogDestination: new apigateway.LogGroupLogDestination(accessLogs),
accessLogFormat,
},
});
Bunun ürettiği şeye bakın. Çağrı başına tek bir JSON satırı: hangi IAM principal’ı, hangi route’u, hangi VPC endpoint üzerinden, hangi organizasyonda, hangi status ve hangi latency ile çağırdı. Bir mesh’in vaat ettiği çağrı başına gözlemlenebilirlik budur ve onu bir stage konfigürasyonunda yazdınız. Sidecar yok, collector yok, agent yok. Satırda kullanıcı token’ı da yok, çünkü format sizin seçtiğiniz isimlerden ibaret.
Route bazlı metrikler bedava değil
Bedava hikâyesi metriklerde bitiyor ve çoğu yazının atladığı düzeltme bu. API Gateway AWS/ApiGateway namespace’ine yazar: Count, Latency (“The time between when API Gateway receives a request from a client and when it returns a response to the client”), IntegrationLatency (“The time between when API Gateway relays a request to the backend and when it receives a response from the backend”), 4XXError ve 5XXError (metrikler ve boyutlar). İlk iki latency arasındaki fark, çağrı başına gateway ek yüküdür; 101. bölümün izlemenizi söylediği sayı da odur.
İş boyutlarda düğümleniyor. Varsayılan olarak ApiName ve ApiName, Stage gelir. Asıl istediğiniz ApiName, Method, Resource, Stage satırının yanında iki cümle duruyor: “API Gateway will not send these metrics unless you have explicitly enabled detailed CloudWatch metrics.” ve “Enabling these metrics will incur additional charges to your account.” Yani route bazlı metrik, faturası olan bir opt-in. CloudFormation’da anahtar AWS::ApiGateway::Stage üzerindeki MethodSettings[].MetricsEnabled; CDK’da deployOptions içindeki metricsEnabled, ki 103. bölüm onu zaten açmıştı ve stage’deki her method’a uygulanır.
Maliyeti kardinalite belirler: method çarpı resource çarpı stage. On iki route’lu tek bir servis, iki stage ile sorun değil. Her biri on iki route’lu otuz servis başka bir konuşmadır ve fatura kaleminde API Gateway satırı olarak değil, custom metrics satırı olarak görünür; kimsenin geldiğini görememesinin sebebi de bu. Ucuz yol zaten elinizde. Her çağrıda access log’a $context.resourcePath ve $context.responseLatency yazıyorsunuz; yani route bazlı latency ve hata oranı, zaten ödediğiniz log ingest fiyatına, bir Logs Insights sorgusu uzaklıkta. Ödün gerçek ve söylenmeye değer: bir metriğe saniyeler içinde alarm bağlarsınız, bir log sorgusuna bağlayamazsınız. Detaylı metrikleri yalnızca nöbetçiyi uyandıracak route’lar için açın, gerisini log’dan okuyun.
Tracing ve servis haritası
Mesh düzeyindeki diğer özellik çağrı grafiği ve o da bir stage ayarı. AWS private API’lerin dışarıda bırakılmadığını açıkça yazıyor: “API Gateway supports X-Ray tracing for all API Gateway REST API endpoint types: Regional, edge-optimized, and private” (REST API’lerde X-Ray). Dahası, açmadığınız yerde bile taşıma çalışıyor: “If you call an API Gateway API from a service that’s already being traced, API Gateway passes the trace through, even if X-Ray tracing isn’t enabled on the API.” Tracing’i açık olan bir çağıran Lambda, trace’ini gateway adımının ötesine taşır.
Karşılığında aldığınız şey, insanların mesh alma sebebi olan resim. “For APIs integrating with AWS services such as AWS Lambda and Amazon DynamoDB, you will see more nodes providing performance metrics related to those services. There will be a service map for each API stage” (servis haritaları). Çağıran, gateway, çağrılan ve çağrılanın DynamoDB tablosu; tek bir grafikte, stage başına. CDK’da karşılığı deployOptions içindeki tracingEnabled: true ve onu da 103. bölüm koymuştu.
OpenTelemetry, servis sınırları arası izlemede oluşmakta olan sektör standardı ve bu bölümün son kısmı nedenine dönüyor; o hâlde Lambda tarafındaki seçim konusunda net olalım. ADOT şöyle tanımlanıyor: “A secure, production-ready, AWS-supported distribution of the OpenTelemetry (OTel) SDK” ve yönetilen layer’lar olarak geliyor: “ADOT provides fully managed Lambda layers that package everything you need to collect telemetry data using the OTel SDK. By consuming this layer, you can instrument your Lambda functions without having to modify any function code” (Lambda tracing). Ardından AWS ödünü kendisi söylüyor ve alışılmadık biçimde dürüst: “The X-Ray and Powertools for AWS Lambda SDKs are part of a tightly integrated instrumentation solution offered by AWS. The ADOT Lambda Layers are part of an industry-wide standard for tracing instrumentation that collect more data in general, but may not be suited for all use cases.” Bunu bir caydırma değil, maliyet ve cold start uyarısı olarak okuyun.
Bu katmanın varsayılanı X-Ray artı Powertools; çünkü yapı zaten baştan sona AWS ve servis haritası bir stage bayrağıyla geliyor. Taşınabilirlik açıkça hedefse ADOT’a geçin: bu bölümün son kısmının tarif ettiği taşınabilirlik-işletmesizlik takası budur, veri hacmi ve layer ağırlığıyla ödersiniz, karşılığında bir çıkış kapısı alırsınız. Bir paragrafı hak eden üçüncü bir seçenek daha var. CloudWatch Application Signals, “an application performance monitoring (APM) solution that enables developers and operators to monitor the health and performance of their serverless applications built using Lambda” olarak tanımlanıyor. Lambda konsolundan tek tıkla açılıyor, instrumentation kodu istemiyor, geliştirilmiş ADOT layer’ları üzerinde çalışıyor ve Node.js 22.x destekliyor (Application Signals). Yanında iki uyarı geliyor. “Using Application Signals for your Lambda functions incurs costs.” Ve elle yazılmış tracing ile yan yana durmuyor: “remove any existing X-Ray SDK instrumentation code from your function. Custom X-Ray SDK instrumentation code can interfere with the layer-provided instrumentation.”
Kullanmak zorunda kaldığınız header
Şimdi olumsuz yarı ve bu doğrudan kimlik tasarımından çıkıyor. AWS_IAM altında Authorization header’ı SigV4’ün; dolayısıyla taşınan kullanıcı iddiası x-user-assertion gibi bir custom header’a binmek zorunda. API Gateway’in redaction sözü şöyle: “API Gateway redacts authorization headers, API key values, and similar sensitive request parameters from the logged data” (logging kurulumu).
Bu cümlenin neye söz verdiği konusunda net olun, çünkü iki yönde de fazla iddiaya kaymak kolay. AWS authorization header’larını ve API key’leri adıyla anıyor, sonra “similar sensitive request parameters” ifadesini bilinçli olarak açık bırakıyor. Rastgele bir custom header’ın redaksiyona uğradığını hiçbir yerde yazmıyor; uğramadığını da yazmıyor. O hâlde dürüst ifade “JWT’niz log’lanıyor” değil. Dürüst ifade şu: AWS size log’lanmadığına dair hiçbir söz vermiyor. Yetkilendirme modelinin sizi kullanmak zorunda bıraktığı o tek header, AWS’in hakkında taahhüt vermeyi reddettiği tek header.
- bölüm buna konfigürasyon disipliniyle cevap vermişti: kullanıcı iddiası taşıyan hiçbir stage’de data tracing açmayın. Bu doğru bir tavsiye ve bir kontrol değil. Data tracing bir stage ayarıdır; stage ayarı ise bir insanın açabildiği şeydir. Gecenin ortasında bozulan bir route’u inceleyen mühendis onu açar, çünkü zaten bunun için vardır. Aynı şey daha sessiz ve daha yaygın olan ikinci sızıntı yolu için de geçerli: çağrılan servisteki bir
console.log(event), header’lar dâhil bütün event’i, kimsenin denetlemediği bir Lambda log group’una basar. İki deliği de bir kural kapatmıyor. İkisini de, adını bile koymadığınız log group’larında, ingest anında çalışan bir policy kapatıyor.
Tutunacak yeri olmayan bir token’ı maskelemek
CloudWatch Logs data protection tam olarak o policy ve hazır bir identifier JWT’yi kapsamıyor. Credentials kategorisi tam olarak beş tipten oluşuyor: AwsSecretKey, OpenSSHPrivateKey, PgpPrivateKey, PkcsPrivateKey ve PuttyPrivateKey (credentials veri tipleri). Bearer token veya JWT diye bir identifier yok. Geriye tek yol kalıyor: “Custom data identifiers (CDIs) let you define your own custom regular expressions that can be used in your data protection policy” (custom data identifier’lar).
Akla gelen regex, yazamayacağınız regex. "x-user-assertion":" gibi bir JSON anahtarına tutunmak istersiniz ve desteklenen karakter kümesi buna izin vermez. AWS tam olarak üç grup sayıyor: Alphanumeric: (a-zA-Z0-9), Symbols: ( '_' | '#' | '=' | '@' |'/' | ';' | ',' | '-' | ' ' ) ve RegEx reserved characters: ( '^' | '$' | '?' | '[' | ']' | '{' | '}' | '|' | '\' | '*' | '+' | '.' ). Listeyi eksiği için okuyun. İki nokta üst üste yok. Çift tırnak yok. Aklınıza gelecek her JSON anahtarı tutamağı ikisine birden ihtiyaç duyar.
Bunun yerine token’ın kendisine tutunun. Bir JWT’nin header segmenti, bir JSON nesnesinin base64url kodlamasıdır; yani her zaman {" karakterleriyle başlar ve bu ikili her zaman eyJ olarak kodlanır. Ortaya, tamamen CDI dilbilgisinin izin verdiği karakterlerden oluşan bir şekil çıkar:
eyJ[A-Za-z0-9_-]*\.eyJ[A-Za-z0-9_-]*\.[A-Za-z0-9_-]*
Üç base64url segmenti, ilk ikisi eyJ ile başlıyor, aralarında düz birer nokta. Bu ifade token’ı hangi header’ın taşıdığını, hangi log group’una düştüğünü, data tracing’den mi yoksa birinin console.log’undan mı geldiğini umursamaz. Policy’nin tamamı:
{
"Name": "user-assertion-protection",
"Version": "2021-06-01",
"Configuration": {
"CustomDataIdentifier": [
{
"Name": "JwtLikeToken",
"Regex": "eyJ[A-Za-z0-9_-]*\\.eyJ[A-Za-z0-9_-]*\\.[A-Za-z0-9_-]*"
}
]
},
"Statement": [
{
"Sid": "audit-findings",
"DataIdentifier": ["JwtLikeToken"],
"Operation": {
"Audit": {
"FindingsDestination": {
"CloudWatchLogs": { "LogGroup": "security/data-protection-findings" }
}
}
}
},
{
"Sid": "mask-in-place",
"DataIdentifier": ["JwtLikeToken"],
"Operation": { "Deidentify": { "MaskConfig": {} } }
}
]
}
İnsanın yarım gününü yiyen iki ayrıntı. Ters bölüler ikişer yazılıyor, çünkü policy dokümanı JSON; regex kaçışının parse’tan sağ çıkması gerekiyor. Sınırlar da dar: “A maximum of 10 custom data identifiers are supported for each data protection policy” ve her birinin uzunluğu en fazla 200 karakter. Bu, birkaç şekil için bir kontrol; bir veri kaybı önleme ürünü değil.
Hesap düzeyinde policy ve bedava alarm
Policy’yi log group’a değil, hesaba bağlayın. AWS: “You can create a data protection policy for all log groups in your account, and you can also create a data protection policies for individual log groups. When you create a policy for your entire account, it applies to both existing log groups and log groups that are created in the future.” (hassas log verisini maskeleme) İki seviye birbirini ezmiyor, üst üste biniyor: “custom data identifiers defined within an account-level policy work in combination with custom data identifiers defined in a log group-level policy” (custom data identifier’lar).
Burada hesap düzeyine çıkma sebebi genel değil, çok özel. API Gateway kendi execution log group’unu kendisi oluşturur ve adını deploy anında API-Gateway-Execution-Logs_{rest-api-id}/{stage_name} biçiminde koyar. Yeni bir servisin stack’ini yazarken o adı bilmiyorsunuz; dolayısıyla log group bazlı bir policy her zaman deploy’ların arkasından koşar. Aynı gerekçe yapıdaki her Lambda log group’u için de geçerli; console.log(event) yolu da oraya düşüyor. Hesap düzeyindeki bir policy, bir takımın gelecek hafta yaratacağı log group’u da korur; endişelendiğiniz log group tam olarak odur.
import * as logs from 'aws-cdk-lib/aws-logs';
// Hesap başına bir tane. Mevcut log group'larını da, sonradan yaratılan her log
// group'unu da kapsar; API Gateway'in deploy anında kendine verdiği adlar dâhil.
new logs.CfnAccountPolicy(this, 'UserAssertionProtection', {
policyName: 'user-assertion-protection',
policyType: 'DATA_PROTECTION_POLICY',
scope: 'ALL',
policyDocument: JSON.stringify(dataProtectionPolicy),
});
Şimdi bunun ne satın aldığı konusunda dürüst olalım, çünkü maskeleme silme demek değil. AWS net: “Sensitive data is detected and masked when it is ingested into the log group. When you set a data protection policy, log events ingested to the log group before that time are not masked.” Log group’larınızda hâlihazırda duran her şey olduğu gibi kalır. Ve token hâlâ saklanıyor. “Only users who have the logs:Unmask IAM permission can view unmasked data” ve CloudWatchLogsFullAccess içinde logs:Unmask var; bu da epeyce mühendisin zaten taşıdığı bir policy. Maskeleme token’ı sıradan bir okuyucudan gizler. Onu yok etmez ve token’ı hiç log’lamamanın yerine geçmez. Faturası da var. Data protection taranan GB başına ücretlendiriliyor: us-east-1’de GB başına $0,12 (CloudWatch fiyatlandırması, 2026-07-14’te okundu). Hesap geneli bir policy de ingest ettiğiniz her şeyi tarar.
Kendi bedelini ödeyen parçanın maske değil Audit statement’ı olmasının sebebi de bu. “A metric is emitted to CloudWatch when sensitive data is detected… This is the LogEventsWithFindings metric and it is emitted in the AWS/Logs namespace… Metrics emitted by data protection are vended metrics and are free of charge.” Eşiği sıfır olan bir alarm bağlayın. Maskeleme hasarı sınırlayan düzeltici kontroldür; alarm ise size bir kullanıcı token’ının bir log group’una hiç ulaşıp ulaşmadığını söyleyen tespit edici kontroldür ve asıl ihtiyacınız olan bilgi budur. Bir bulgu, bu katmandaki bir servisin hâlâ bir iddiayı olmaması gereken bir yere taşıdığı anlamına gelir; hiçbir maskeleme miktarı bunu düzeltmez. Yalnızca gizler.
Sık yapılan hatalar
- Kullanıcı iddiasını bir
$context.requestOverride.header.*alanında adlandırmak. Access log’un yapısı gereği güvenli olmasının tek sebebi, hiçbir$contextdeğişkeninin rastgele bir istek header’ını açmaması. Entegrasyon isteği override’ı, token’ı o satıra geri koymanın tek yolu. - Konsolda
CountveLatencygörüp route bazlı metriklerin açık olduğu sonucuna varmak. Onlar API ve stage seviyesindeki boyutlar.ApiName, Method, Resource, Stageiçin detaylı metrikler gerekir ve AWS bunun “will incur additional charges to your account” olduğunu yazıyor. - “Data tracing kapalı” ifadesini bir kontrol saymak. Bu, açma anahtarı olan bir stage ayarıdır ve insanlar tam da olay anında ona uzanır. Kontrol, ingest anında çalışan data protection policy’sidir.
- Custom data identifier’ı JSON anahtarına tutundurmaya çalışmak. İki nokta üst üste ve çift tırnak desteklenen karakter kümesinde yok; yani
"x-user-assertion":"ifade edilemez. Token’ın kendieyJşekline tutunun. - Maskelemeye silme demek. Event saklanır,
logs:Unmaskonu açar,CloudWatchLogsFullAccessbu yetkiyi verir ve policy’den önce ingest edilmiş event’ler zaten hiç maskelenmemiştir. - Fonksiyonda X-Ray SDK instrumentation’ı dururken Application Signals’ı açmak. AWS onu kaldırmanızı söylüyor: “Custom X-Ray SDK instrumentation code can interfere with the layer-provided instrumentation.”
Bütün bunlar nereye gidiyor
Bu seriyi bir serverless kaçamağı gibi okumak kolay olurdu: mesh yok, biz de idare ediyoruz. Bu okuma tersten. Mesh dünyası aynı sonuca öbür taraftan yürüyor ve AWS oraya çoktan vardı.
AWS kendi service mesh’ini emekliye ayırıyor. App Mesh kullanıcı rehberi her sayfasında şu uyarıyı taşıyor: “On September 30, 2026, AWS will discontinue support for AWS App Mesh. After September 30, 2026, you will no longer be able to access the AWS App Mesh console or AWS App Mesh resources” (App Mesh). Yeni müşteri alımı zaten Eylül 2024’te kapandı. AWS bir sidecar mesh kurdu, yıllarca işletti ve şimdi fişini çekiyor. Yönetilen doğu-batı bağlantısının nereye gittiğine dair küçük bir sinyal değil bu.
Yerine ne koyduğu konusunda net olun, çünkü akla ilk gelen özet yanlış. AWS proxy’yi ortadan kaldırmadı. ECS için müşterileri Service Connect’e yönlendiriyor ve orada, AWS’in kendi ifadesiyle, “the Envoy proxy, known as the Service Connect Proxy, is fully managed by AWS” (App Mesh’ten Service Connect’e); App Mesh’in kendi kendine yönetilen sidecar’ının aksine. Envoy hâlâ task’ın içinde. Sadece artık sizin derdiniz değil. Emekliye ayrılan fikir sidecar değil, sidecar’ı sizin işletmeniz.
Açık kaynak mesh de aynı yöne gidiyor. Istio’nun ambient mode’u Kasım 2024’te GA oldu ve vaadi per-pod proxy’siz bir mesh: L4 işleri per-node bir ztunnel’da, L7 proxy’lemesi opt-in ve ayrı ölçekleniyor (ambient mode). Istio’nun kendi gerekçesi sidecar aleyhine bir iddianame gibi okunuyor: proxy’ler pod spec’i yeniden yazılarak enjekte edilmek zorunda, yükseltmeler uygulama pod’larının yeniden başlatılması demek ve “the CPU and memory resources must be provisioned for worst case usage of each individual pod” (ambient mesh tanıtımı). Cilium da eBPF üzerinden aynı yere varıyor: per-pod değil, per-node Envoy.
Yine de abartmayın, çünkü oybirliği yok. Istio sidecar’ları desteklemeye devam ediyor ve ortadan kalkmayacaklarını söylüyor. CNCF’in diğer mezun mesh’i Linkerd ise açıkça tersini savunuyor ve proxy’yi kaldırmak yerine sidecar yaşam döngüsü sorunlarını çözüyor. Dürüst iddia “endüstri sidecar’ı terk etti” değil. Dürüst iddia şu: ağırlık merkezi, iş yükünün yanındaki proxy’den platforma kayıyor.
Zaten bütün mesele bu. Her iki dünya da aynı sonuca vardı: doğu-batı çağrılarında kimlik, yetkilendirme, şifreleme ve telemetri iş yüküne cıvatalanacak şeyler değil, platforma ait şeyler. Istio ambient, Kubernetes’in serverless’ta zaten yapısı gereği var olan bir özelliği edinme çabası. Lambda’nın kaldıracak bir sidecar’ı hiç olmadı. Gateway, IAM ve yönetilen ağ zaten o platform katmanı; bu seri de onları birbirine bağlamaktan ibaret.
Yakınsama gerçek ama implementasyonlar ayrışıyor ve imzaladığınız ödün tam olarak bu. Kubernetes, kendi işlettiğiniz taşınabilir ve tarafsız spesifikasyonlarda standartlaşıyor. Workload identity’yi SPIFFE ve SPIRE taşıyor (SPIFFE); 2022’den beri CNCF mezunu. Servis sınırları arası izlemeyi OpenTelemetry taşıyor (OpenTelemetry); Mayıs 2026’da mezun oldu. Serverless ise işletmediğiniz ve taşıyamadığınız bulut primitiflerinde standartlaşıyor: IAM SigV4, private API Gateway, EventBridge. SigV4 ile SPIFFE aynı soruyu cevaplıyor, hangi workload çağırıyor, ve cevabın şekli de aynı: kriptografik ve kısa ömürlü. Fark, güven kökünün kime ait olduğu. İşletmesiz bir platform satın alıyor, bedelini taşınabilirlikle ödüyorsunuz. Bu savunulabilir bir ödün ve bilinçli olmalı.
Üstünü örtmek yerine kabul edilmesi gereken bir boşluk var. Endüstri, iç çağrılarda kimlik için iki parçalı bir cevaba yerleşiyor ve bunun yalnızca yarısı oturdu. SPIFFE, hangi workload’ın çağırdığını kapsıyor. Diğer yarısı, yani kimin adına sorusu için IETF’in Transaction Tokens taslağı ikisinin birbirinin yerine geçemeyeceğini açıkça yazıyor: “A workload MUST NOT use a transaction token to authenticate itself to another workload, service or the TTS. Transaction tokens represents information relevant to authorization decisions and are not workload identity credentials” (Transaction Tokens). Bu, 104. bölümün AWS tarafından yürüyerek vardığı iki kontrol kuralının ta kendisi. Fark şu: standart hâlâ bir çalışma grubu taslağı, yani ikinci kontrolü şimdilik kendiniz kuruyorsunuz.
Serinin vardığı yer
Serinin argümanı kısa. Önce event: yanıtı bekleyen yoksa araya bir bus koyun ve bunların hiçbiri sizi ilgilendirmesin. Yanıt aynı çağrının içinde dönmek zorundaysa mesh deploy etmeyin. Zaten sahip olduğunuz primitive’lerden bir tane kurun. 101. bölüm katmanı VPC Lattice’e karşı seçti; kimlik cephesinde Lattice en kötü ihtimalle berabere, bir request header’ına göre yetkilendirmeniz gerektiğinde ise önde, yani kararı asıl veren şeyler maliyetin şekli ve API yönetimi. 102. bölüm wire format’ı karara bağladı: gRPC bir gateway kararı değil, compute kararıdır ve format hiçbir zaman sözleşme değildi. 103. bölüm onu kurdu: paylaşılan bir execute-api endpoint arkasında private REST API, route bazlı AWS_IAM. 104. bölüm çağrılan serviste iki kimlik kontrolünü ekledi, çünkü SigV4 servisi kanıtlar, kullanıcıyı asla. 105. bölüm ve 106. bölüm, tasarımın gerçek bir yapıyla karşılaştığı yer: hesaplar arası perimeter ve gerçek trafik altında nelerin bozulduğu. Gözlemlenebilirlik, yani mesh’in vaat ettiği üçüncü şey ise bir stage konfigürasyonu ile bir log group policy’sine çıkıyor.
Buradaki varsayılan, katmanın kendisinin geçerli olduğu her yerde geçerli: AWS_IAM ile private REST API kullanan, çok takımlı, tamamen Lambda’lı bir yapı. Kimlik alanlarını log’layın. Route bazlı latency’yi log’dan okuyun ve detaylı metrikleri yalnızca nöbetçiyi uyandıracak route’lar için açın. Hesaptaki her log group’un önüne hesap düzeyinde tek bir data protection policy’si koyun. Bunların hiçbiri henüz deploy edilmedi; baştan sona sayıları liste fiyatı, konfigürasyonu da plan olarak okuyun. İlk adım serinin en ucuz işi ve hiçbir geçiş gerektirmiyor: hesabınızda bugün takımlar arası kaç tane lambda:InvokeFunction yetkisi olduğunu sayın. O sayı, taşıdığınız bağımlılığın büyüklüğüdür ve onu sıfıra indirmek bütün bu katmanın amacıdır.
Kaynaklar
- API Gateway access logging değişkenleri - Log’lanabilir alanların kapalı kümesi,
AWS_IAM’in doldurduğu kimlik değişkenleri ve formatın$context.requestIdya da$context.extendedRequestIdtaşıma zorunluluğu. - Set up CloudWatch logging for a REST API - Authorization header’larını ve API key’leri adıyla anan, custom header hakkında hiçbir şey vaat etmeyen redaction cümlesi.
- API Gateway metrics and dimensions -
LatencyveIntegrationLatencytanımları ve “will incur additional charges to your account” diyen route bazlı boyut. - Tracing REST APIs with AWS X-Ray - X-Ray private dâhil bütün REST endpoint tiplerinde çalışır ve API’de kapalı olsa bile gelen trace’i geçirir.
- Using X-Ray service maps - Stage başına bir servis haritası ve route’un arkasındaki AWS servisleri için ayrı düğümler.
- Tracing Lambda functions in Node.js - ADOT yönetilen layer’ları ve AWS’nin X-Ray ile Powertools SDK’larına karşı kendi karşılaştırması.
- CloudWatch Application Signals for Lambda - Geliştirilmiş ADOT layer’ları üzerinde tek tıkla APM, maliyet notu ve mevcut X-Ray SDK instrumentation’ının önce kaldırılması şartı.
- Help protect sensitive log data with masking - Gelecekteki log group’ları da kapsayan hesap düzeyi policy, ingest anında maskeleme,
logs:Unmaskyetkisi ve bedavaLogEventsWithFindingsmetriği. - Custom data identifiers - Ne iki nokta üst üste ne de çift tırnak içeren desteklenen regex karakter kümesi, ayrıca 10 identifier ve 200 karakter sınırları.
- Managed data identifiers for credentials - AWS’nin sunduğu beş kimlik bilgisi tipi. JWT yok, bearer token yok; custom identifier’ın tek yol olmasının sebebi bu.
- Amazon CloudWatch pricing - Data protection’ın taranan GB başına faturalanması. Fiyatlar 2026-07-14’te, us-east-1 için okundu.
- AWS App Mesh - “On September 30, 2026, AWS will discontinue support for AWS App Mesh.” AWS kendi sidecar mesh’inin fişini çekiyor.
- Migrating from App Mesh to ECS Service Connect - Yerine gelen şey sidecar’sızlık değil, yönetilen sidecar: “the Envoy proxy, known as the Service Connect Proxy, is fully managed by AWS”. Doküman değil, AWS blogu.
- Introducing ambient mesh - Istio’nun sidecar’a kendi iddianamesi: pod spec’i yeniden yazarak enjeksiyon, yükseltmede yeniden başlatma ve pod başına en kötü durum kaynak ayırma.
- IETF: OAuth 2.0 Transaction Tokens - Kimlik cevabının diğer yarısı: “A workload MUST NOT use a transaction token to authenticate itself… are not workload identity credentials.” Hâlâ taslak.
Serverless İç Servis Katmanı: Kurmadığınız, Oluşturduğunuz Mesh
Çok takımlı bir serverless yapıda service mesh benzeri doğu-batı iletişimini private API Gateway üzerine kurmak. Kimlik, şifreleme, wire format'lar, maliyet ve endüstrinin gerçekte nereye gittiği.
Bu Serideki Tüm Yazılar
İlgili yazılar
İç servis katmanı kurmadan önce kurup kurmayacağınıza karar verin. Katmanın çağrı başına maliyeti, VPC Lattice'in kazandığı hacim ve direct invoke'un hâlâ kazandığı an.
Private REST API gRPC’yi yapısal olarak taşıyamaz ve gRPC konuşan her AWS yüzeyi Lambda hedeflerini dışlar. gRPC’den neyi tutmalı, neyi bırakmalı.
Private REST API, onu açan resource policy, route bazlı AWS_IAM yetkileri, iki CDK stack'i ve Node 22 Lambda'dan çağrıyı imzalamak.
SigV4 hangi servisin çağırdığını kanıtlar, kimin adına çağırdığını değil. Doğrulanmış özneyi nasıl taşırsınız ve taşıma katmanı gerçekte neyi şifreler.
Aynı hesapta resource policy ile çağıranın identity policy'si bir OR'dur. Hesaplar arası çağrıda AND'e döner ve sessizlik reddeder. Veri sınırında bunun sonuçları.