2025-12-25
AWS ile Edge Computing: CloudFront Functions vs Lambda@Edge
Global uygulamalar için AWS edge computing çözümlerini seçme ve uygulama üzerine pratik örnekler ve maliyet optimizasyonu stratejileri içeren kapsamlı teknik rehber.
Edge computing, kod yürütmeyi merkezi data center’lardan kullanıcılara yakın konumlara taşıyor. AWS CloudFront dünya çapında 1600+ edge location ile çalışıyor ve iki farklı edge computing çözümü sunuyor: CloudFront Functions ve Lambda@Edge. Her iki servis ile çalışmak bana doğru seçimin maliyet, performans ve implementasyon karmaşıklığı üzerinde önemli etkisi olduğunu öğretti.
AWS ile edge computing çözümleri geliştirirken öğrendiklerim.
CloudFront Edge Computing’i Anlamak
CloudFront ile edge computing, kodu kullanıcılara yakın edge location’larda çalıştırarak yürütmeyi mümkün kılıyor. Her iki servis de request’leri edge’de işleyerek latency sorunlarını çözüyor, ancak farklı kullanım senaryolarına hitap ediyorlar.
CloudFront Functions, cache key normalizasyonu ve header manipülasyonu gibi yüksek hacimli, basit dönüşümlerde Lambda@Edge’e göre 1/6 maliyetle mükemmel çalışıyor. Lambda@Edge ise network erişimi, harici API’ler veya karmaşık business logic gerektiren operasyonları ele alıyor.
Execution Point’leri
CloudFront, edge function’ların çalışabileceği dört execution point sağlıyor:
- Viewer Request: CloudFront request’i aldıktan sonra, cache’i kontrol etmeden önce
- Viewer Response: Viewer’a response dönmeden önce
- Origin Request: Origin’e forward etmeden önce (sadece cache miss) - Sadece Lambda@Edge
- Origin Response: Origin’den response alındıktan sonra - Sadece Lambda@Edge
Servis Karşılaştırması: Doğru Seçimi Yapmak
CloudFront Functions ve Lambda@Edge arasındaki farkları anlamak, maliyet-etkin mimari kararlar almak için önemli.
Özellik Karşılaştırması
| Özellik | CloudFront Functions | Lambda@Edge |
|---|---|---|
| Execution Location | 1600+ edge location | 1600+ edge location |
| Runtime | Sadece JavaScript | Node.js 22.x, Python 3.13 |
| Execution Time | < 1 milisaniye | 5s (viewer), 30s (origin) |
| Memory | 2 MB | 128 MB - 10 GB |
| Max Package Size | 10 KB | 1 MB (viewer), 50 MB (origin) |
| Network Access | Hayır | Evet |
| Event Type’ları | Viewer request/response | Tüm 4 event type |
| Request Body Access | Hayır | Evet (origin event’lerde) |
| Response Size | 40 KB | 1 MB |
| Fiyatlandırma (1M başına) | $0.10 invocation | $0.60 invocation + compute |
| Cold Start | Yok | 1-3 saniye |
| KeyValueStore | Evet | Hayır |
Maliyet Etkisi
Aylık 10 milyar request için maliyet farkı önemli:
- CloudFront Functions: 10,000M × 1,000
- Lambda@Edge: 10,000M × 6,000-$8,000
CloudFront Functions basit kullanım senaryolarında 5-8x daha ucuz.
Karar Çerçevesi
CloudFront Functions: Hız İçin Optimize
CloudFront Functions tüm 1600+ edge location’da sub-milisaniye latency ile çalışıyor. Network erişimi gerektirmeyen yüksek hacimli, basit operasyonlar için ideal.
Kullanım Senaryosu 1: Cache Key Normalizasyonu
Query parameter’ları normalize ederek cache hit ratio’yu optimize etmek, origin load’u önemli ölçüde azaltabilir.
// Cache key normalizasyonu için CloudFront Function
function handler(event) {
var request = event.request;
var querystring = request.querystring;
// Device indicator'larını standart formata normalize et
if (querystring.device) {
var deviceValue = querystring.device.value.toLowerCase();
if (deviceValue === 'm' || deviceValue === 'mobile') {
querystring.device.value = 'mobile';
} else if (deviceValue === 'd' || deviceValue === 'desktop') {
querystring.device.value = 'desktop';
}
}
// Query parameter'ları alfabetik sırala - tutarlı cache key için
var sortedQuerystring = {};
Object.keys(querystring)
.sort()
.forEach(function(key) {
sortedQuerystring[key] = querystring[key];
});
request.querystring = sortedQuerystring;
// Accept-Encoding header'ını normalize et
if (request.headers['accept-encoding']) {
var acceptEncoding = request.headers['accept-encoding'].value;
if (acceptEncoding.includes('br')) {
request.headers['accept-encoding'].value = 'br,gzip';
} else if (acceptEncoding.includes('gzip')) {
request.headers['accept-encoding'].value = 'gzip';
}
}
return request;
}
Bu normalizasyon production sistemde cache hit ratio’yu %45’ten %78’e çıkardı ve origin request’leri %60 azalttı.
Kullanım Senaryosu 2: Security Header’ları
Security header’ları eklemek için CloudFront Functions kullanmak Lambda@Edge’den daha maliyet-etkin.
// Security header'ları için CloudFront Function (viewer response)
function handler(event) {
var response = event.response;
var headers = response.headers;
// Strict-Transport-Security (HSTS)
headers['strict-transport-security'] = {
value: 'max-age=31536000; includeSubDomains; preload'
};
// Content-Security-Policy (CSP)
headers['content-security-policy'] = {
value: "default-src 'self'; img-src 'self' https: data:; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';"
};
// X-Content-Type-Options
headers['x-content-type-options'] = {
value: 'nosniff'
};
// X-Frame-Options
headers['x-frame-options'] = {
value: 'DENY'
};
// X-XSS-Protection
headers['x-xss-protection'] = {
value: '1; mode=block'
};
// Referrer-Policy
headers['referrer-policy'] = {
value: 'strict-origin-when-cross-origin'
};
// Permissions-Policy
headers['permissions-policy'] = {
value: 'geolocation=(), microphone=(), camera=()'
};
return response;
}
Aylık 5 milyar request için bu CloudFront Functions ile 3,000+ tutabiliyor.
Kullanım Senaryosu 3: KeyValueStore ile A/B Testing
CloudFront Functions, yeniden deploy olmadan dinamik konfigürasyon için KeyValueStore’u destekliyor.
// A/B testing için KeyValueStore kullanan CloudFront Function
import cf from 'cloudfront';
const kvsId = 'a1b2c3d4-5678-90ab-cdef-example12345';
const kvsHandle = cf.kvs(kvsId);
async function handler(event) {
var request = event.request;
var uri = request.uri;
// Kullanıcının zaten experiment ataması var mı kontrol et
var cookies = request.cookies;
var experimentCookie = cookies['experiment_variant'];
var variant;
if (experimentCookie) {
variant = experimentCookie.value;
} else {
// Experiment konfigürasyonunu KeyValueStore'dan al
var experimentConfig = await kvsHandle.get('experiment_homepage');
var config = JSON.parse(experimentConfig);
// Traffic split'e göre variant ata
var random = Math.random() * 100;
if (random < config.variantA_percentage) {
variant = 'A';
} else if (random < (config.variantA_percentage + config.variantB_percentage)) {
variant = 'B';
} else {
variant = 'C';
}
// Gelecekteki request'ler için cookie set et
request.cookies['experiment_variant'] = { value: variant };
}
// URL'i variant'a göre yeniden yaz
if (uri === '/') {
request.uri = `/variants/home-${variant.toLowerCase()}.html`;
}
return request;
}
Tip: KeyValueStore güncellemeleri birkaç dakika içinde yayılıyor. Development sırasında versioning kullan ve production değişiklikleri için gradual rollout uygula.
Lambda@Edge: Güç ve Esneklik
Lambda@Edge, network erişimi, harici API’ler veya karmaşık business logic gerektiren kompleks operasyonları ele alıyor. Trade-off olarak daha yüksek maliyet ve potansiyel cold start latency var.
Kullanım Senaryosu 1: Geo-Targeting ve Lokalizasyon
CloudFront, Lambda@Edge’in intelligent routing için kullanabileceği coğrafi header’lar sağlıyor.
// Geo-targeting için Lambda@Edge function (viewer request)
'use strict';
exports.handler = (event, context, callback) => {
const request = event.Records[0].cf.request;
const headers = request.headers;
// CloudFront geo header'ları sağlıyor
const country = headers['cloudfront-viewer-country']
? headers['cloudfront-viewer-country'][0].value
: 'US';
// Ülkeleri dil tercihlerine map et
const countryToLocale = {
'DE': '/de',
'AT': '/de',
'CH': '/de',
'TR': '/tr',
'FR': '/fr',
'ES': '/es',
'IT': '/it',
'US': '/en',
'GB': '/en',
'CA': '/en'
};
// Sadece root path'i redirect et
if (request.uri === '/') {
const locale = countryToLocale[country] || '/en';
// Kullanıcının locale tercihi cookie'si var mı kontrol et
const cookies = headers.cookie || [];
let localePreference = null;
for (let cookie of cookies) {
const matches = cookie.value.match(/locale=([^;]+)/);
if (matches) {
localePreference = matches[1];
break;
}
}
// Lokalize edilmiş path'e redirect et
const targetUri = localePreference || locale;
const response = {
status: '302',
statusDescription: 'Found',
headers: {
'location': [{
key: 'Location',
value: targetUri
}],
'cache-control': [{
key: 'Cache-Control',
value: 'max-age=3600'
}]
}
};
callback(null, response);
} else {
callback(null, request);
}
};
Kullanım Senaryosu 2: JWT Authentication
JWT token’ları edge’de doğrulamak, unauthorized request’lerin origin’e ulaşmasını önlüyor.
// JWT validation için Lambda@Edge function (viewer request)
'use strict';
const jwt = require('jsonwebtoken');
// Production'da AWS Secrets Manager'dan çek
const JWT_SECRET = process.env.JWT_SECRET;
exports.handler = async (event, context, callback) => {
const request = event.Records[0].cf.request;
const headers = request.headers;
// Protected path'ler
const protectedPaths = ['/api/', '/dashboard/', '/admin/'];
const isProtected = protectedPaths.some(path => request.uri.startsWith(path));
if (!isProtected) {
callback(null, request);
return;
}
// Authorization header'ını çıkar
const authHeader = headers.authorization || headers.Authorization;
if (!authHeader || authHeader.length === 0) {
callback(null, unauthorizedResponse('Missing authorization header'));
return;
}
const token = authHeader[0].value.replace('Bearer ', '');
try {
// JWT token'ı doğrula
const decoded = jwt.verify(token, JWT_SECRET, {
algorithms: ['HS256'],
maxAge: '24h'
});
// Origin için custom header'lara kullanıcı bilgisi ekle
request.headers['x-user-id'] = [{
key: 'X-User-Id',
value: decoded.userId
}];
request.headers['x-user-email'] = [{
key: 'X-User-Email',
value: decoded.email
}];
callback(null, request);
} catch (error) {
console.error('JWT validation failed:', error.message);
callback(null, unauthorizedResponse('Invalid or expired token'));
}
};
function unauthorizedResponse(message) {
return {
status: '401',
statusDescription: 'Unauthorized',
headers: {
'www-authenticate': [{
key: 'WWW-Authenticate',
value: 'Bearer realm="Access to protected resources"'
}],
'content-type': [{
key: 'Content-Type',
value: 'application/json'
}]
},
body: JSON.stringify({
error: message
})
};
}
Tip: Lambda@Edge function’larında asla secret’ları hardcode etme. API call’larını ve cold start etkisini minimize etmek için caching ile AWS Secrets Manager kullan.
Kullanım Senaryosu 3: Origin Selection ve Failover
Health check’lerle dinamik origin routing, dayanıklı mimariler sağlıyor.
// Origin selection için Lambda@Edge function (origin request)
'use strict';
const https = require('https');
exports.handler = async (event, context, callback) => {
const request = event.Records[0].cf.request;
// Primary ve secondary origin'ler
const origins = {
primary: {
domainName: 'api-primary.example.com',
port: 443,
protocol: 'https',
path: '/v1'
},
secondary: {
domainName: 'api-secondary.example.com',
port: 443,
protocol: 'https',
path: '/v1'
}
};
let selectedOrigin = origins.primary;
// Custom header'a göre route et
const routingHeader = request.headers['x-origin-override'];
if (routingHeader && routingHeader[0].value === 'secondary') {
selectedOrigin = origins.secondary;
}
// Path'e göre route et
if (request.uri.startsWith('/legacy/')) {
selectedOrigin = origins.secondary;
}
// Primary origin'i health check yap
try {
const isHealthy = await checkOriginHealth(selectedOrigin.domainName);
if (!isHealthy) {
console.log(`Primary origin ${selectedOrigin.domainName} unhealthy, failing over`);
selectedOrigin = origins.secondary;
}
} catch (error) {
console.error('Health check failed:', error);
selectedOrigin = origins.secondary;
}
// Request'i seçilen origin ile güncelle
request.origin = {
custom: {
domainName: selectedOrigin.domainName,
port: selectedOrigin.port,
protocol: selectedOrigin.protocol,
path: selectedOrigin.path,
sslProtocols: ['TLSv1.2'],
readTimeout: 30,
keepaliveTimeout: 5,
customHeaders: {}
}
};
callback(null, request);
};
function checkOriginHealth(domainName) {
return new Promise((resolve) => {
const options = {
hostname: domainName,
port: 443,
path: '/health',
method: 'GET',
timeout: 2000
};
const req = https.request(options, (res) => {
resolve(res.statusCode === 200);
});
req.on('error', () => resolve(false));
req.on('timeout', () => {
req.destroy();
resolve(false);
});
req.end();
});
}
Performans Optimizasyonu
Lambda@Edge Cold Start’ları Azaltmak
Cold start’lar, function’lar viewer request fazında çalıştığında kullanıcı deneyimini doğrudan etkiliyor. İşe yarayan yöntemler:
1. Package Size’ı Minimize Et
// KÖTÜ: Handler içinde initialize et
exports.handler = async (event) => {
const AWS = require('aws-sdk'); // Yavaş!
const dynamodb = new AWS.DynamoDB.DocumentClient();
// ...
};
// İYİ: Handler dışında initialize et
const AWS = require('aws-sdk');
const dynamodb = new AWS.DynamoDB.DocumentClient();
exports.handler = async (event) => {
// Warm invocation'larda initialization'ı yeniden kullanır
};
2. Memory Allocation’ı Doğru Boyutlandır
Daha fazla memory, daha fazla CPU demek ve bu da cold start süresini azaltıyor. Test’ler orta düzeyde dependency’leri olan Lambda@Edge function’lar için 512 MB’nin genellikle ideal nokta olduğunu gösterdi.
3. External Dependency’leri Azalt
Ağır kütüphaneleri daha hafif alternatiflerle değiştir:
moment.js→date-fnsveya nativeDate- Tam AWS SDK → bireysel service client’ları
- Büyük image processing kütüphaneleri → minimal implementasyon’lar
Production sistemlerden cold start metrikleri:
- Boş function: 100-300ms
- AWS SDK ile: 500-1000ms
- Sharp ile (image processing): 1000-3000ms
CloudFront Functions Optimizasyonu
Kodu Minimal Tut: 10 KB limiti tüm kodu içeriyor. Hardcode değerler yerine konfigürasyon verisi için KeyValueStore kullan.
KeyValueStore’dan Yararlan: Function yeniden deploy’u önlemek için konfigürasyon verisini offload et. KeyValueStore sub-milisaniye okuma ile 5 MB storage sağlıyor.
Maliyet Analizi ve Optimizasyon
Maliyet yapısını anlamak bilinçli kararlar almaya yardımcı oluyor.
Detaylı Maliyet Hesaplama
Senaryo: Aylık 5 milyar request, 50ms ortalama süre, 128 MB memory
CloudFront Functions:
5,000M invocation × $0.10 = $500
Toplam: $500/ay
Lambda@Edge:
Request charge'ları: 5,000M × $0.60 = $3,000
Compute: 5,000M × 0.05s × 0.125GB × $0.00005001 = $1,563
Toplam: $4,563/ay
Tasarruf: CloudFront Functions kullanarak $4,063/ay (%89 azalma)
Maliyet Optimizasyon Stratejileri
1. Mümkün Olduğunda CloudFront Functions Kullan: Header manipülasyonu ve cache key normalizasyonu gibi operasyonlar için CloudFront Functions 5-8x maliyet tasarrufu sağlıyor.
2. Lambda@Edge Memory’yi Optimize Et: CloudWatch metrikleri kullanarak memory allocation’ı doğru boyutlandır. Daha fazla memory, execution süresini azaltarak daha yüksek memory maliyetlerini dengeleyebilir.
3. Invocation Frekansını Azalt: Edge function invocation’larını minimize etmek için CloudFront cache policy’lerini etkili kullan. Her cache’lenen response bir function invocation’dan kaçınır.
4. Gerçek Kullanımı İzle: Maliyet threshold’ları için CloudWatch alarm’ları kur:
import * as cloudwatch from 'aws-cdk-lib/aws-cloudwatch';
const lambdaEdgeCostAlarm = new cloudwatch.Alarm(this, 'LambdaEdgeCostAlarm', {
metric: new cloudwatch.Metric({
namespace: 'AWS/Lambda',
metricName: 'Invocations',
dimensionsMap: {
FunctionName: edgeFunction.functionName,
},
statistic: 'Sum',
period: cdk.Duration.days(1),
}),
threshold: 1_000_000_000, // günde 1 milyar invocation
evaluationPeriods: 1,
alarmDescription: 'Lambda@Edge invocation budget threshold aşıldı',
});
Debugging ve Logging Zorlukları
Lambda@Edge logları function’ın çalıştığı AWS bölgesinde oluşuyor, bu da debugging’i karmaşık hale getiriyor.
Bölgeler Arasında Log’ları Bulmak
CloudFront Response Header’larını Kontrol Et:
curl -I https://your-distribution.cloudfront.net/path
# Ara: x-amz-cf-pop: IAD89-P1
# IAD = us-east-1 region
Havaalanı Kodu-Region Eşlemesi:
- IAD (Dulles) → us-east-1
- SFO (San Francisco) → us-west-1
- DUB (Dublin) → eu-west-1
- NRT (Tokyo) → ap-northeast-1
- SYD (Sydney) → ap-southeast-2
Structured Logging Best Practice
// Structured logging ile Lambda@Edge function
'use strict';
exports.handler = async (event, context) => {
const request = event.Records[0].cf.request;
const requestId = context.requestId;
// Kolay parse için structured log
const logContext = {
requestId,
uri: request.uri,
method: request.method,
country: request.headers['cloudfront-viewer-country']?.[0]?.value,
timestamp: new Date().toISOString(),
};
console.log('REQUEST_START', JSON.stringify(logContext));
try {
// Logic'in burada
console.log('PROCESSING', JSON.stringify({ ...logContext, step: 'validation' }));
return request;
} catch (error) {
console.error('ERROR', JSON.stringify({
...logContext,
error: error.message,
stack: error.stack,
}));
throw error;
} finally {
console.log('REQUEST_END', JSON.stringify(logContext));
}
};
Structured log’ları sorgulamak için CloudWatch Logs Insights kullan:
fields @timestamp, @message
| filter @message like /ERROR/
| sort @timestamp desc
| limit 100
Yaygın Tuzaklar ve Çözümler
1. Lambda@Edge Response Size Aşıldı (502 Error)
Problem: Function >1 MB response dönüyor, CloudFront 502 veriyor.
Çözüm: Dönmeden önce response size’ını kontrol et:
const responseBody = JSON.stringify(data);
const sizeInBytes = Buffer.byteLength(responseBody, 'utf8');
if (sizeInBytes > 1048576) { // 1 MB = 1048576 byte
console.error(`Response size ${sizeInBytes} 1MB limitini aşıyor`);
// Bunun yerine S3 object referansı dön
return {
status: '200',
body: JSON.stringify({
url: `https://s3.amazonaws.com/bucket/response-${requestId}.json`
})
};
}
2. Viewer Request Timeout (5 Saniye)
Problem: Viewer request Lambda@Edge function timeout veriyor.
Çözüm: Timeout koruması için Promise.race kullan:
const timeoutPromise = new Promise((_, reject) =>
setTimeout(() => reject(new Error('Timeout')), 4000)
);
const result = await Promise.race([
fetchExternalData(),
timeoutPromise
]);
3. Cache Key Verimsizliği Duplicate Object’ler Yaratıyor
Problem: Cache hit ratio düşük, yüksek origin request’leri.
Çözüm: Query parameter’ları normalize et:
function normalizeQueryString(querystring) {
// Tracking parameter'larını kaldır
const trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'fbclid', 'gclid'];
trackingParams.forEach(param => delete querystring[param]);
// Kalan parameter'ları sırala
const sorted = {};
Object.keys(querystring).sort().forEach(key => {
sorted[key] = querystring[key];
});
return sorted;
}
AWS CDK Deployment Pattern
CloudFront’u edge function’larla deploy etmek için eksiksiz CDK stack:
// Edge function'larla CloudFront için AWS CDK stack
import * as cdk from 'aws-cdk-lib';
import * as cloudfront from 'aws-cdk-lib/aws-cloudfront';
import * as origins from 'aws-cdk-lib/aws-cloudfront-origins';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as s3 from 'aws-cdk-lib/aws-s3';
import { Construct } from 'constructs';
import * as path from 'path';
export class EdgeComputingStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
// ÖNEMLİ: Lambda@Edge us-east-1'de deploy edilmeli
super(scope, id, { ...props, env: { region: 'us-east-1' } });
// Origin için S3 bucket
const bucket = new s3.Bucket(this, 'OriginBucket', {
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
encryption: s3.BucketEncryption.S3_MANAGED,
});
// Cache key normalizasyonu için CloudFront Function
const cacheKeyFunction = new cloudfront.Function(this, 'CacheKeyNormalization', {
code: cloudfront.FunctionCode.fromFile({
filePath: path.join(__dirname, '../functions/cache-key-normalization.js'),
}),
runtime: cloudfront.FunctionRuntime.JS_2_0,
comment: 'Daha iyi hit ratio için cache key normalize et',
});
// Security header'ları için CloudFront Function
const securityHeadersFunction = new cloudfront.Function(this, 'SecurityHeaders', {
code: cloudfront.FunctionCode.fromFile({
filePath: path.join(__dirname, '../functions/security-headers.js'),
}),
runtime: cloudfront.FunctionRuntime.JS_2_0,
comment: 'Tüm response'lara security header ekle',
});
// JWT authentication için Lambda@Edge function
const jwtAuthFunction = new cloudfront.experimental.EdgeFunction(
this,
'JwtAuthFunction',
{
runtime: lambda.Runtime.NODEJS_20_X,
handler: 'index.handler',
code: lambda.Code.fromAsset(path.join(__dirname, '../lambda/jwt-auth')),
timeout: cdk.Duration.seconds(5),
memorySize: 128,
}
);
// Optimize caching için cache policy
const cachePolicy = new cloudfront.CachePolicy(this, 'OptimizedCachePolicy', {
cachePolicyName: 'EdgeComputingOptimized',
comment: 'Normalize key'lerle optimize cache policy',
defaultTtl: cdk.Duration.hours(24),
maxTtl: cdk.Duration.days(365),
minTtl: cdk.Duration.seconds(1),
enableAcceptEncodingGzip: true,
enableAcceptEncodingBrotli: true,
headerBehavior: cloudfront.CacheHeaderBehavior.allowList(
'CloudFront-Viewer-Country',
'CloudFront-Viewer-Country-Region'
),
queryStringBehavior: cloudfront.CacheQueryStringBehavior.allowList(
'w', 'h', 'q', 'format'
),
});
// CloudFront distribution
const distribution = new cloudfront.Distribution(this, 'Distribution', {
defaultBehavior: {
origin: new origins.S3Origin(bucket),
viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
cachePolicy,
functionAssociations: [
{
function: cacheKeyFunction,
eventType: cloudfront.FunctionEventType.VIEWER_REQUEST,
},
{
function: securityHeadersFunction,
eventType: cloudfront.FunctionEventType.VIEWER_RESPONSE,
},
],
edgeLambdas: [
{
functionVersion: jwtAuthFunction.currentVersion,
eventType: cloudfront.LambdaEdgeEventType.VIEWER_REQUEST,
},
],
},
enableLogging: true,
logIncludesCookies: true,
});
// Output'lar
new cdk.CfnOutput(this, 'DistributionDomainName', {
value: distribution.distributionDomainName,
});
new cdk.CfnOutput(this, 'DistributionId', {
value: distribution.distributionId,
});
}
}
Warning: Lambda@Edge function’ları CloudFront distribution’ınızın nerede deploy edildiğine bakılmaksızın her zaman us-east-1 bölgesinde oluşturulmalı.
Önemli Çıkarımlar
-
İş için doğru servisi seç: CloudFront Functions kullanım senaryolarının %90’ı için (header’lar, cache key’ler, basit logic), Lambda@Edge karmaşık gereksinimler için (API’ler, authentication, image processing). Maliyet farkı 5-8x.
-
Cold start’lar kullanıcı deneyimini etkiliyor: Lambda@Edge cold start’ları kullanıcıları doğrudan etkiliyor. Package size’ı minimize et, initialization’ı optimize et, latency-sensitive operasyonlar için CloudFront Functions kullan.
-
1 MB response limit kesin: Lambda@Edge >1 MB response dönemez. Mimariyi buna göre tasarla: büyük payload’ları S3 üzerinden stream et.
-
Log’lar global olarak dağıtılmış: Lambda@Edge logları birden fazla AWS bölgesinde görünüyor. Correlation ID’lerle structured logging kullan, doğru bölgeyi bulmak için x-amz-cf-pop header’ını kontrol et.
-
Cache optimizasyonu kritik: Cache hit ratio’yu iyileştirmek için CloudFront Functions ile cache key’leri normalize et. Kötü cache key tasarımı duplicate object’ler yaratır ve origin load’u artırır.
-
CloudFront Functions ile security header’ları: HSTS, CSP, X-Frame-Options eklemek CloudFront Functions ile 1M request başına 6+.
-
KeyValueStore dinamik konfigürasyon sağlıyor: Function’ları yeniden deploy etmeden A/B test yüzdelerini, feature flag’leri ve routing kurallarını güncelle. 5 MB storage, sub-milisaniye okuma.
-
Maliyetleri sürekli izle: Edge function’lar milyarlarca invocation’a scale olabiliyor. CloudWatch alarm’ları kur, aylık maliyetleri gözden geçir, agresif optimize et.
-
Failover senaryolarını test et: Edge function’lar critical path’in parçası. Graceful error handling uygula, hata durumunda orijinal request’i dön, error rate’leri izle.
-
Basit başla, progressif scale et: CloudFront managed policy’lerle başla, optimizasyon için CloudFront Functions ekle, Lambda@Edge’i sadece gerektiğinde devreye sok. Her adımda etkiyi ölç.
Edge computing ile çalışmak bana CloudFront Functions ve Lambda@Edge arasındaki doğru seçimin spesifik gereksinimlere bağlı olduğunu öğretti. Basit başlamak ve sadece gerektiğinde karmaşıklık eklemek, en maliyet-etkin ve sürdürülebilir çözümleri üretiyor.
İlgili yazılar
Dev, staging ve production ortamlarında Lambda Layer versiyonlarını yönetmek için pratik yaklaşımlar. AWS CDK implementasyonları, otomatik deployment pipeline'ları ve rollback stratejileri ile.
Multi-environment deployment stratejileri, ölçekte performans optimizasyonu, ve maliyet yönetimi. Production deneyimleri ve öğrenilen dersler ile doğru monitoring ve incident response pattern'ları.
Amazon Cognito'nun gelişmiş özellikleri üzerine kapsamlı teknik kılavuz: özel authentication akışları, federation pattern'leri, multi-tenancy mimarileri, migration stratejileri ve production-grade güvenlik implementasyonu.
AWS Secrets Manager ve Systems Manager Parameter Store'u karşılaştıran kapsamlı teknik rehber - hangi servisi ne zaman kullanmalı ve gerçek dünya implementation pattern'leri.
Native AWS servisleri, otomasyon ve kanıtlanmış implementation pattern'leri kullanarak AWS maliyetlerini %40-70 azaltmaya yönelik kapsamlı bir rehber.