Amazon SAA-C03: Serverless & Event-driven architecturen / API-integratie — Studiegids
Onderdeel van de AWS SAA-C03 — Complete studiegids. Oefen met geverifieerde antwoorden in het Amazon-examencentrum, of doe getimede oefentests op ExamRoll.io.
AWS Lambda: Uitvoeringsmodel, Runtime Lifecycle en Cold Starts
Lambda voert code uit in geïsoleerde Firecracker micro-VM’s die een tweefasige lifecycle volgen. De INIT-fase provisioneert de container, bootstrap de runtime, downloadt en pakt het deployment package uit, en voert alle initialisatie op moduleniveau uit — het aanmaken van SDK-clients, het laden van door KMS ontsleutelde secrets, het opzetten van een database connection pool, het laden van JVM-klassen en JIT warm-up. De INVOKE-fase voert de handler uit. Een cold start brengt de volledige INIT-kosten met zich mee; een warme aanroep hergebruikt de omgeving, dus alles wat buiten de handler wordt gecachet (HTTP keep-alive pools, ontsleutelde secrets, DB-clients) blijft behouden tussen aanroepen op die container. Daarom is het canonieke patroon om kostbare objecten op moduleniveau aan te maken en deze te hergebruiken:
import boto3, os
ddb = boto3.client('dynamodb') # reused across warm invokes
_secret = None
def _load_secret():
global _secret
if _secret is None:
_secret = kms.decrypt(...) # KMS call once per container, not per invoke
return _secret
def handler(event, ctx):
...
De omvang van een cold start varieert per runtime. Node.js en Python duren tientallen tot een paar honderd milliseconden; de JVM en .NET kunnen meer dan een seconde duren. Voor functies die aan een VPC gekoppeld zijn, hebben Hyperplane ENI’s de historische penalty voor het koppelen van een ENI grotendeels geamortiseerd, maar de grootte van het package en zware INIT-code blijven de dominante factoren.
Drie tools pakken cold starts op verschillende manieren aan:
| Feature | Gedrag | Kosten | Meest geschikt voor |
|---|---|---|---|
| On-demand concurrency | Standaard; schaalt met een initiële burst van ~500–3.000, daarna +500/min | Per aanroep + duur | Piekbelasting, latency-tolerant |
| Provisioned concurrency | Pre-initialiseert N omgevingen, INIT voltooid vóór verkeer | Betalen voor geprovisioneerde units 24/7 + aanroepen | Strikte p99 latency SLA |
| SnapStart (Java, Python, .NET) | Firecracker-snapshot na INIT; hersteld bij een cold start | Geen extra kosten voor Java; kleine kosten voor caching bij andere | Java-functies waar volledige provisioning verspilling is |
SnapStart is de kosteneffectieve ‘sweet spot’ voor Java-workloads zonder harde latency-contracten — cold starts verminderen met ongeveer een factor tien zonder extra kosten per aanroep. Provisioned concurrency is het juiste antwoord wanneer een synchrone API een p99 van bijvoorbeeld onder de 100 ms moet handhaven tijdens pieken; door het te dimensioneren op de p95-piek wordt de ’tail-latency gap’ gedicht. Het te laag inschatten is een klassieke fout: on-demand start alleen nieuwe containers op wanneer een verzoek binnenkomt, dus een piek veroorzaakt wachttijden van meerdere seconden voor echte gebruikers.
# SAM: SnapStart on a Java 17 function
MyJavaFn:
Type: AWS::Serverless::Function
Properties:
Runtime: java17
SnapStart: { ApplyOn: PublishedVersions }
AutoPublishAlias: live
Provisioned concurrency zelf kan worden geschaald via Application Auto Scaling — een geplande actie die opschaalt van 10 naar 200 om 07:45 en terug om 10:00 voorkomt dat je ’s nachts betaalt voor warme capaciteit, terwijl de cold starts van de ochtendpiek worden geëlimineerd.
Geheugengrootte is tegelijkertijd een CPU-knop: vCPU schaalt lineair met het geheugen tot ~1.769 MB per vCPU. Een functie die is vastgezet op 128 MB kan in totaal meer kosten dan een functie op 1.024 MB, omdat een verdubbelde runtime vaak de verdubbelde prijs per ms overschrijdt. Ga niet gokken — gebruik AWS Lambda Power Tuning om configuraties te testen met representatieve payloads.
Lambda Concurrency Controls en Bescherming van Downstream Systemen
Drie concurrency-knoppen zijn van belang en elk heeft een andere functie:
- Reserved concurrency begrenst en reserveert hoeveel gelijktijdige uitvoeringen een functie mag verbruiken. Het reserveert capaciteit uit de account-pool en beschermt downstream systemen (een kleine RDS-instantie, een partner-API met rate limits) tegen overbelasting.
- Provisioned concurrency pre-initialiseert omgevingen — de hendel voor latency, niet voor schaalbaarheid.
- Unreserved account concurrency is de gedeelde pool, met een standaardlimiet van 1.000 per Regio.
Aannemen dat Lambda ‘oneindig schaalt’ ziet twee plafonds over het hoofd. Ten eerste is de limiet voor gelijktijdige uitvoeringen op accountniveau reëel, en de burst-limieten (initieel 500–3.000 afhankelijk van de Regio, daarna +500/min) bepalen de opschalingssnelheid. Zodra deze wordt overschreden, ontvangen synchrone aanroepers een 429 TooManyRequestsException, die API Gateway presenteert als een 5xx-fout. Ten tweede hebben downstream systemen hun eigen limieten: een db.t3.micro met max_connections=85 kan duizend gelijktijdige Lambda’s die elk een verbinding openen niet aan. PostgreSQL forkt een backend-proces per verbinding dat ~10 MB RAM verbruikt; zelfs met reserve-CPU kan alleen al het opzetten en afbreken van verbindingen de instantie volledig belasten.
De twee oplossingen zijn (1) RDS Proxy, die veel client-side verbindingen poolt en multiplexeert naar een kleine set van persistente backend-verbindingen, en (2) het invoegen van een wachtrij zodat de verwerkingssnelheid wordt losgekoppeld van de aankomstsnelheid:
import psycopg2, os
conn = psycopg2.connect(
host=os.environ['PROXY_ENDPOINT'], # RDS Proxy, not the DB directly
dbname='orders', user='app', password=get_secret())
RDS Proxy is een oplossing met minimale wijzigingen — de driver en de connection string veranderen nauwelijks — wat het het juiste antwoord maakt wanneer de eis ‘minimale wijziging aan de applicatie’ plus het uitputten van verbindingen is. DynamoDB heeft dit probleem niet: de HTTPS API is stateless, wat de reden is dat DynamoDB van nature goed samengaat met high-fanout Lambda-workloads.
Lambda IAM, Omgevingsvariabelen en Netwerken
Elke functie neemt bij aanroep een execution role aan. Het trust policy van de rol verleent sts:AssumeRole aan lambda.amazonaws.com; het permission policy definieert wat de functie mag doen. De runtime injecteert automatisch kortlevende STS-credentials in AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY en AWS_SESSION_TOKEN. Plaats nooit IAM user access keys in omgevingsvariabelen of code — ze zijn statisch, vindbaar in gelekte broncode of CloudTrail-exports, moeten handmatig geroteerd worden en omzeilen het hele model van tijdelijke credentials.
FnRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal: { Service: lambda.amazonaws.com }
Action: sts:AssumeRole
Policies:
- PolicyName: ReadOrders
PolicyDocument:
Statement:
- Effect: Allow
Action: ["dynamodb:GetItem", "dynamodb:Query"]
Resource: !GetAtt OrdersTable.Arn
Omgevingsvariabelen met gevoelige configuratie moeten worden versleuteld met een customer-managed KMS key, met behulp van “helpers for encryption in transit” zodat de console de data client-side versleutelt. Ontsleutel eenmalig tijdens de INIT-fase en cache de platte tekst in een variabele op moduleniveau — anders betaalt elke aanroep voor een KMS API-call.
Standaard draait een functie in een door AWS beheerde VPC met onbeperkte uitgaande internettoegang. Koppel de functie alleen aan je eigen VPC als deze toegang moet hebben tot resources binnen de VPC (RDS in private subnets, ElastiCache, on-prem via Direct Connect). Lambda koppelt dan Hyperplane ENI’s aan de subnets die je specificeert en neemt hun routing over.
De klassieke valkuil is een Lambda in een private subnet plaatsen zonder route voor verkeer naar AWS-services, behalve via een NAT gateway — of erger nog, een zelfbeheerde NAT instance. NAT instances raken verzadigd op een enkele NIC, zijn een SPOF en worden per GB gefactureerd. Zelfs NAT gateways rekenen per GB en zijn onnodig voor verkeer naar AWS-services. Het correcte patroon is:
- Gateway VPC endpoints voor S3 en DynamoDB (gratis)
- Interface (PrivateLink) endpoints voor KMS, Secrets Manager, SQS, SNS, STS en vergelijkbare services
Dit houdt het verkeer op de AWS backbone, elimineert de doorvoerlimieten van NAT en voorkomt onverwachte egress-kosten. Let op dat Lambda ENI’s nooit een public IP krijgen; de functie in een “public” subnet plaatsen geeft deze geen internettoegang — je hebt nog steeds een NAT gateway nodig in een apart public subnet met een correcte route.
Amazon API Gateway: Endpoint Types, Autorisatie en Delivery
API Gateway biedt drie API-smaken:
| Kenmerk | REST API | HTTP API | WebSocket |
|---|---|---|---|
| Latency | Hoger | ~60% lager | Stateful, bidirectioneel |
| Kosten | Hoger | ~70% goedkoper | Per bericht |
| Usage plans / API keys | Ja | Nee | Nee |
| Request/response transforms (VTL) | Ja | Beperkt | — |
| JWT authorizers | Via Lambda | Native | Via Lambda |
| WAF | Ja | Nee (plaats CloudFront ervoor) | Ja |
Kies REST als je API keys en usage plans, JSON Schema request validatie, VTL mapping templates, Cognito authorizers met per-methode scopes, of WAF nodig hebt; kies HTTP voor lichtgewicht, met JWT geauthenticeerde proxy-patronen waar kosten en latency belangrijker zijn.
Endpoint types bepalen waar de API wordt aangeboden:
- Edge-optimized: aangeboden via een door Gateway beheerde CloudFront-distributie; TLS wordt beëindigd op de dichtstbijzijnde POP. Beste keuze voor wereldwijd verspreide clients.
- Regional: beschikbaar vanuit een enkele Region zonder CloudFront. Beste keuze als clients zich in dezelfde Region bevinden, als je je eigen CloudFront ervoor wilt plaatsen, of bij gebruik van Route 53 latency-based routing over meerdere Regions.
- Private: alleen bereikbaar via een interface VPC endpoint. Beste keuze voor interne microservices die niet over het publieke internet mogen gaan.
Het kiezen van edge-optimized voor een interne API in een enkele Region voegt een onnodige CloudFront-hop en tragere deployment-propagatie toe. Het kiezen van regional voor een wereldwijd gebruikte publieke API dwingt elk verzoek over het publieke internet naar één Region.
Custom domains vereisen ACM-certificaten waarvan de locatie afhangt van het endpoint type: us-east-1 voor edge-optimized (CloudFront is globaal en beëindigt TLS daar); de eigen Region van de API voor regional endpoints. Dit verwarren is een veelvoorkomende misconfiguratie. Base path mappings maken het mogelijk om met één domein meerdere API’s te multiplexen (/orders → orders API, /users → users API).
Autorisatie kent vier modellen, en het negeren van de ingebouwde opties is een klassiek anti-patroon:
| Mechanisme | Wanneer te gebruiken |
|---|---|
| IAM authorization | Aanroepers zijn AWS principals die SigV4 kunnen ondertekenen (andere services, SDK’s, cross-account) |
| Cognito user pool authorizer | Gebruikers authenticeren tegen een Cognito user pool; Gateway valideert de JWT |
| Lambda authorizer | Niet-standaard tokens, externe IdP’s zonder OIDC, complexe logica per request |
| API keys + usage plans | Meten, throttling, quota’s — nooit gebruiken als authenticatie |
Een custom Lambda authorizer voegt een extra aanroep per request toe (of per cache TTL), een extra functie om te patchen en te monitoren, en een codepad waar bugs in de handtekeningvalidatie ongemerkt toegang kunnen verlenen. Gebruik deze alleen als de ingebouwde opties echt niet aan de eisen kunnen voldoen.
Lambda proxy integration is het standaardpatroon — het volledige request wordt als een event doorgegeven en de functie moet de response in de juiste envelop-structuur retourneren:
{
"statusCode": 200,
"headers": {"Content-Type": "application/json"},
"body": "{\"orderId\":\"abc123\"}",
"isBase64Encoded": false
}
Voor fire-and-forget data-inname bij zeer hoge TPS, gebruik de directe AWS service-integratie van Gateway om data rechtstreeks naar SQS of Kinesis te pushen, waarmee de Lambda-stap volledig wordt overgeslagen. Dit elimineert cold starts in het schrijfpad en ontkoppelt de innamesnelheid van de verwerkingscapaciteit.
Gebruik voor veilige rollouts canary deployments op een stage: een percentage van het verkeer gaat naar de nieuwe deployment terwijl de meerderheid op de stabiele versie blijft. CloudWatch-metrics per canary informeren de beslissing voor promotie of rollback.
aws apigateway update-stage --rest-api-id abc123 --stage-name prod \
--patch-operations \
op=replace,path=/canarySettings/percentTraffic,value=10 \
op=replace,path=/canarySettings/deploymentId,value=xyz789
Voor een eenvoudige webhook waar de rompslomp van API Gateway overbodig is (single-tenant Slack callback, GitHub push handler), bieden Lambda function URLs een toegewijd HTTPS-endpoint direct op de functie. Beveilig deze met AuthType: AWS_IAM als de aanroepers AWS principals zijn; indien NONE, moet je de handtekening van het request valideren in de functie. Een function URL met AuthType: NONE en zonder verificatie in de functie is een anoniem compute-endpoint op het publieke internet.
Invocatietypes, Retries en Idempotentie
Eventbronnen (event sources) vallen uiteen in twee categorieën met zeer verschillend gedrag. Push-gebaseerde bronnen (API Gateway, ALB, S3, SNS, EventBridge, Cognito) roepen Lambda rechtstreeks aan en vereisen een AWS::Lambda::Permission resource-gebaseerde policy die lambda:InvokeFunction toekent met de juiste Principal (bijv. events.amazonaws.com) en SourceArn. Zonder deze policy matcht de regel wel met events, maar wordt elke aanroep stilzwijgend geweigerd — de functie wordt nooit uitgevoerd en de fouten verschijnen alleen in CloudTrail. Dit staat los van de execution role, die bepaalt wat de functie kan doen, niet wie haar kan aanroepen.
Poll-gebaseerde bronnen (SQS, Kinesis, DynamoDB Streams, MSK) worden door de Lambda-service gelezen via een event source mapping — er is geen resource-gebaseerde policy nodig, maar de execution role moet wel leesrechten (read permissions) toekennen.
Invocatietypes bepalen verder het gedrag bij retries:
- Synchroon (API Gateway, ALB,
RequestResponseSDK): fouten worden onmiddellijk geretourneerd; de aanroepende partij (caller) is verantwoordelijk voor retries. - Asynchroon (S3, SNS, EventBridge): Lambda buffert op een interne wachtrij en probeert het bij een fout twee keer opnieuw met vertraging, en stuurt het event vervolgens naar een DLQ of een on-failure destination.
- SQS event source mapping: SQS blijft het bericht opnieuw aanbieden totdat
maxReceiveCounteen verplaatsing naar de DLQ van de bronwachtrij (source queue) activeert. - Kinesis / DynamoDB Streams: probeert een enkele shard-batch opnieuw tot het succesvol is of de data verloopt, en blokkeert daarbij de shard — een vastgelopen batch houdt alle verdere verwerking voor die partitie tegen.
Omdat retries in elke laag zijn ingebouwd, is idempotentie verplicht, niet optioneel. Een SQS visibility timeout die verloopt tijdens een trage schrijfactie, of een asynchrone retry na een downstream 5xx-fout, zal duplicaten veroorzaken. Het canonieke patroon gebruikt een deterministische sleutel en een conditionele schrijfactie (conditional write) in DynamoDB:
def handler(event, context):
msg_id = event['Records'][0]['messageId']
try:
ddb.put_item(
TableName='processed',
Item={'id': {'S': msg_id}, 'ttl': {'N': str(ttl)}},
ConditionExpression='attribute_not_exists(id)')
except ddb.exceptions.ConditionalCheckFailedException:
return # already processed
process(event)
De @idempotent decorator van AWS Lambda Powertools implementeert precies dit patroon met DynamoDB als backend.
Ontkoppelen met SQS en SNS
Het rechtstreeks koppelen van push-bronnen met een hoge fan-out aan Lambda is kwetsbaar. S3 event notifications, bijvoorbeeld, zijn synchroon per event en onderhevig aan het concurrency-plafond van Lambda; als het aantal aanroepen de beschikbare concurrency overschrijdt tijdens een piek in uploads (een marketingcampagne die duizenden documenten in seconden plaatst), is het retry-venster van S3 kort en kunnen events feitelijk verloren gaan (dropped). De oplossing is een buffer:
| Patroon | Wanneer te gebruiken |
|---|---|
| S3 → Lambda direct | Lage, voorspelbare event-rate; idempotente verwerking |
| S3 → SQS → Lambda | Piekbelastingen (bursty workloads); behoefte aan retry/DLQ; rate limits stroomafwaarts |
| S3 → SNS → meerdere SQS | Fan-out naar meerdere onafhankelijke consumers |
| S3 → EventBridge → vele targets | Cross-account routing; content-gebaseerde filtering |
SNS is pub/sub: één publicatie, vele abonnees (subscribers) (SQS, Lambda, HTTPS, e-mail). Berichtfiltering is gebaseerd op attributen. SQS is een duurzame point-to-point wachtrij die berichten tot 14 dagen vasthoudt. De werkpaardcombinatie is SNS → SQS fan-out, wat elke consumer zijn eigen gebufferde wachtrij geeft voor onafhankelijke schaalvergroting en herhaling (replay).
Voor strikte volgorde (bijv. bestellingen per klant die sequentieel worden verwerkt), gebruik een SQS FIFO queue met de MessageGroupId ingesteld op de sleutel die de volgorde bepaalt. Berichten binnen een groep worden op volgorde afgeleverd; verschillende groepen worden parallel verwerkt. Standaard SQS biedt alleen ‘best-effort’ volgordebepaling.
Het canonieke ontkoppelde ingestiepatroon gebruikt de directe SQS-integratie van API Gateway om pieken op te vangen en een processor met een rate limit:
Resources:
OrdersQueue:
Type: AWS::SQS::Queue
Properties:
FifoQueue: true
ContentBasedDeduplication: true
RedrivePolicy:
deadLetterTargetArn: !GetAtt OrdersDLQ.Arn
maxReceiveCount: 5
ProcessorFunction:
Type: AWS::Lambda::Function
Properties:
ReservedConcurrentExecutions: 20 # cap the DB write rate
Mapping:
Type: AWS::Lambda::EventSourceMapping
Properties:
EventSourceArn: !GetAtt OrdersQueue.Arn
FunctionName: !Ref ProcessorFunction
BatchSize: 10
De gereserveerde concurrency is opzettelijk — het beperkt hoe snel de database schrijfacties ziet, zodat de wachtrij (niet RDS) de piek opvangt. Mislukte berichten worden na maxReceiveCount naar een DLQ gerouteerd voor offline inspectie.
EventBridge: Rules, Inputtransformatie en API Destinations
EventBridge is een schema-bewuste event bus met uitgebreide JSON-patroonmatching, SaaS-partnerbronnen, een schema registry en archivering/replay. Rules matchen op event-patronen en sturen door (fan-out) naar meer dan 30 typen targets (Lambda, Step Functions, SQS, Kinesis, ECS, Firehose), met content-gebaseerde filtering op de body van het bericht — niet alleen op attributen zoals bij SNS:
{
"source": ["tenant.energy"],
"detail-type": ["UsageReported"],
"detail": { "kWh": [{ "numeric": [">", 100] }] }
}
Een rule kan maximaal vijf targets hebben, die elk ofwel het onbewerkte (raw) event of een getransformeerde subset ervan ontvangen. Input transformers dwingen losse koppeling (loose coupling) af: een InputPathsMap extraheert JSON-paden uit het event, en een InputTemplate vormt deze om tot precies wat het target verwacht:
EventPattern:
source: ["com.acme.orders"]
detail-type: ["OrderPlaced"]
Targets:
- Arn: !GetAtt PaymentValidator.Arn
InputTransformer:
InputPathsMap:
orderId: "$.detail.orderId"
amount: "$.detail.total"
card: "$.detail.payment.cardToken"
InputTemplate: |
{"orderId": <orderId>, "amount": <amount>, "cardToken": <card>}
Elke validatie-Lambda ontvangt alleen wat hij nodig heeft; de adresvalidator ziet nooit het kaarttoken. Dit is aanzienlijk beter dan een monolithische Lambda die het volledige event ontvangt en intern vertakt — een monolitische functie concentreert IAM-permissies (één role moet elke downstream-permissie hebben), vergroot de ‘blast radius’ van een bug, koppelt de deployment-cadans, voorkomt afstemming van geheugen/timeout per verantwoordelijkheid, en dwingt de hele functie om te schalen naar de rate van de meest luidruchtige tak.
API destinations keren de richting om: EventBridge roept een extern HTTPS-eindpunt aan. In combinatie met een connection die Basic, API-key of OAuth-credentials opslaat in Secrets Manager, is dit de serverless manier om een externe SaaS-provider te informeren wanneer bijvoorbeeld een AWS Batch-taak slaagt — zonder dat een Lambda nodig is. EventBridge vangt het state-change event op, een rule matcht op JobSucceeded, en het API destination-target doet een POST naar de leverancier met credentials die vanuit de connection worden geïnjecteerd.
Scheduled rules (cron/rate-expressies) of de nieuwere EventBridge Scheduler vervangen ‘heartbeat’ EC2-instances voor periodieke taken — nachtelijke rapporten, uurlijkse cache-verversing.
Kies EventBridge boven SNS wanneer filtering op de inhoud van de bericht-body (niet alleen attributen) nodig is, wanneer nieuwe consumers later moeten kunnen aanhaken zonder wijzigingen aan de producer, of wanneer de routering over meerdere accounts of SaaS-bronnen heen gaat. Kies SNS wanneer de fan-out een eenvoudige, op attributen gefilterde notificatie is naar een stabiele set van subscribers.
Step Functions: Orkestratie en Distributed Map
Wanneer een workflow meer dan een paar stappen, vertakkingen, retries, menselijke goedkeuring of lange wachttijden heeft, wordt het onbeheersbaar om die logica in geketende Lambdas te verwerken. Step Functions externaliseert de state machine in Amazon States Language.
- Standard workflows: tot een jaar, exactly-once semantiek, volledige uitvoeringsgeschiedenis,
.waitForTaskTokenvoor menselijke/externe poorten. Orderverwerking, ETL, goedkeuringsstromen. - Express workflows: tot vijf minuten, at-least-once, hoog volume, goedkoop per uitvoering. Korte synchrone orkestraties achter API Gateway; IoT en streaming-transformaties.
Elke taak moet expliciete Retry en Catch declareren:
"ValidatePayment": {
"Type": "Task",
"Resource": "arn:aws:states:::lambda:invoke",
"Parameters": {"FunctionName": "PaymentValidator", "Payload.$": "$"},
"Retry": [{
"ErrorEquals": ["Lambda.ServiceException", "Lambda.TooManyRequestsException"],
"IntervalSeconds": 2, "MaxAttempts": 4, "BackoffRate": 2.0
}],
"Catch": [{"ErrorEquals": ["PaymentDeclined"], "Next": "RefundStep"}],
"Next": "ShipOrder"
}
Parallel- en Map-states voeren takken gelijktijdig uit en voegen de resultaten samen — een perfecte oplossing voor bestelsystemen met onafhankelijke validators (adres, voorraad, betaling). De state tussen stappen stroomt door het JSON-document van de uitvoering, waardoor een gedeelde database die uitsluitend voor workflowcoördinatie wordt gebruikt, overbodig wordt.
Het .waitForTaskToken-patroon pauzeert de uitvoering totdat een externe actor SendTaskSuccess aanroept met de token — het canonieke antwoord wanneer een workflow Lambdas, EC2, containers, on-prem systemen omspant en handmatige goedkeuring vereist met minimale operationele overhead:
"ManagerApproval": {
"Type": "Task",
"Resource": "arn:aws:states:::sns:publish.waitForTaskToken",
"Parameters": {
"TopicArn": "arn:aws:sns:us-east-1:111:approvals",
"Message": { "TaskToken.$": "$$.Task.Token", "OrderId.$": "$.orderId" }
},
"Next": "Fulfill"
}
Distributed Map breidt de standaard Map-state uit om tot 10.000 parallelle child-uitvoeringen te verwerken en kan direct itereren over objecten in een S3-bucket of rijen in een CSV/JSONL-bestand, met automatische batching, checkpointing en fouttolerantie. Voor duizenden semigestructureerde S3-objecten is dit de meest operationeel efficiënte optie — richt het op een prefix, definieer de taak per item, en Step Functions regelt de fan-out, MaxConcurrency, retries en het samenvoegen van resultaten:
{
"Type": "Map",
"ItemReader": {
"Resource": "arn:aws:states:::s3:listObjectsV2",
"Parameters": { "Bucket": "raw-events", "Prefix": "2024/" }
},
"MaxConcurrency": 1000,
"ItemProcessor": {
"ProcessorConfig": { "Mode": "DISTRIBUTED", "ExecutionType": "STANDARD" },
"StartAt": "ProcessObject",
"States": { "ProcessObject": { "Type": "Task", "Resource": "arn:aws:lambda:...:function:ProcessOne", "End": true } }
}
}
Hetzelfde nabouwen op SQS of EventBridge vereist een aangepaste administratie voor voltooiing, retries en het verzamelen van resultaten.
Step Functions vs. EventBridge: Step Functions is de juiste keuze wanneer jij de eigenaar bent van de volgorde en het resultaat — state, vertakkingen, retries, goedkeuringen. EventBridge is de juiste keuze wanneer producers niet weten of het hen kan schelen wie de consumenten zijn, en consumenten onafhankelijk van elkaar aanhaken.
S3 Event Notifications
Voor near-real-time verwerking van uploads, configureer S3 event notifications op s3:ObjectCreated:* (of een specifieke variant zoals Put, Post, CompleteMultipartUpload) met een Lambda als doelwit — met inachtneming van de hierboven genoemde burst-risico’s. Aandachtspunten:
- Stel reserved concurrency in om een downstream database te beschermen.
- Activeer een DLQ of on-failure destination voor ‘poison messages’.
- Leid S3-events via EventBridge wanneer meerdere consumenten dezelfde events nodig hebben. Directe S3-notificatieconfiguraties zijn beperkt in aantal en expressiviteit; EventBridge fan-out met per-target input transformers schaalt veel beter.
Streaming: Kinesis Data Streams vs. Firehose
Kinesis Data Streams (KDS) is een gesharde, geordende, herafspeelbare log met een retentie van 24 uur tot 365 dagen. De volgorde wordt per shard behouden, op basis van de partition key — cruciaal voor aggregatie per apparaat of per tenant. Meerdere consumenten lezen onafhankelijk (enhanced fan-out voor geïsoleerde doorvoer per consument). Kies KDS wanneer je geordend herafspelen, meerdere onafhankelijke consumenten of een hoge doorvoer per shard nodig hebt.
Kinesis Data Firehose is een volledig beheerde leveringsstream naar S3, Redshift, OpenSearch of Splunk met ingebouwde buffering (60 s of 1–128 MB), optionele Lambda-transformatie, compressie (GZIP, Snappy) en Parquet/ORC-conversie. Geen shards om te beheren. Firehose is de keuze met weinig operationele lasten wanneer aangepaste consumenten en herafspelen niet nodig zijn — alleen voor het landen van near-real-time data.
De canonieke near-real-time analytics-pipeline is producers → KDS → Firehose → S3 (Parquet) → Athena/QuickSight, met optionele Lambda-verrijking in Firehose.
AWS Transfer Family for Managed SFTP
Wanneer partners SFTP, FTPS of FTP vereisen voor dataoverdracht naar of van S3 of EFS, biedt AWS Transfer Family een beheerd, multi-AZ endpoint dat het protocol spreekt dat clients al gebruiken. Authenticatie ondersteunt door de service beheerde gebruikers, SSH-sleutels of aangepaste IdP’s via API Gateway/Lambda. Bestanden landen direct in S3 met SSE en lifecycle policies toegepast; IAM scope-down policies beperken elke gebruiker tot een specifieke prefix.
Dit zelf bouwen op EC2 vereist OpenSSH-hardening, patchen, HA over AZ’s, sleutelrotatie en log shipping — allemaal zaken die Transfer Family overneemt. Kies het wanneer de eis is “partners sturen ons bestanden via SFTP” en je de bestanden in S3 wilt hebben met minimale operationele overhead.
Een Canoniek Serverless Patroon Samenstellen
Een ingestion-ontwerp met lage overhead voor uurlijkse metrics per tenant: sensoren POSTen naar API Gateway (HTTP API, regional) → Lambda valideert en publiceert naar EventBridge → regels routeren naar een DynamoDB writer-Lambda (tenant-ID als partition key, uur-bucket als sort key) en, parallel daaraan, naar Firehose → S3 (Parquet) voor analytics. Nieuwe consumenten haken aan als extra EventBridge-regels zonder de producers aan te passen — de uitbreidbaarheidseis die SNS alleen niet zo netjes zou kunnen vervullen. Waar aanhoudende doorvoer en volgorde belangrijk zijn (factuurafstemming, financiële eventstromen), vervang EventBridge door Kinesis Data Streams en gebruik enhanced fan-out voor onafhankelijke consumenten.
Valkuilencatalogus: Waarom veelvoorkomende foute patronen falen
NAT instance/gateway voor verkeer naar AWS-services vanuit Lambda’s in een private subnet. NAT instances koppelen de doorvoersnelheid aan één EC2 NIC en zijn een SPOF; NAT gateways factureren per GB. Beide zijn onnodig voor AWS-services als bestemming. Gebruik gateway endpoints voor S3/DynamoDB en interface endpoints voor al het andere.
Cold starts negeren bij latency-kritische API’s. On-demand provisioneert containers pas wanneer een request binnenkomt, waardoor pieken de SLA’s niet halen. Dimensionneer provisioned concurrency op de p95-piek; gebruik SnapStart voor Java-workloads zonder harde SLA’s.
Monolithische Lambda die een volledig event ontvangt en intern vertakt. Schendt het ’least privilege’-principe (één role heeft alle downstream permissies), koppelt de deployment-cadans, voorkomt tuning per verantwoordelijkheid, en schaalt de hele functie op basis van de rate van de meest luidruchtige tak. Splits op per verantwoordelijkheid; verbind met EventBridge of Step Functions.
Directe DB-verbindingen vanuit veel Lambda’s. Het totale aantal verbindingen is gelijk aan het aantal gelijktijdige aanroepen, omdat containers geen pools delen. Los dit op met RDS Proxy (pooling), reserved concurrency (rate cap), of SQS (buffering).
Synchrone Lambda voor ingestie met pieken. Het overschrijden van de concurrency retourneert een 429 naar API Gateway en een 5xx naar clients; directe S3-notificaties tijdens pieken laten stilletjes events vallen. Voeg SQS tussen, of gebruik de directe integratie van Gateway → SQS.
Publieke Lambda function URL’s met AuthType: NONE en zonder signature-validatie in de functie. Anonieme compute op het publieke internet. Gebruik AWS_IAM voor AWS-callers of valideer signatures voor webhooks van derden.
Custom Lambda authorizer gebruiken waar een ingebouwde variant volstaat. Voegt latency toe, een extra functie om te patchen, en een codepad waar bugs in de signature-check stilletjes toegang kunnen verlenen. Geef de voorkeur aan IAM-autorisatie voor AWS principals; Cognito authorizer voor user pools.
Verkeerde ACM-certificaatregio voor custom domains. Edge-optimized endpoints vereisen het certificaat in us-east-1; regional endpoints in de eigen regio van de API.
Ontbrekende AWS::Lambda::Permission voor push-bronnen (EventBridge, S3, SNS). Events matchen de regels, maar aanroepen worden stilzwijgend geweigerd. Dit staat los van de execution role — dit bepaalt wie de functie mag aanroepen, niet wat de functie mag doen.
Ontbrekende idempotentie. Elke laag voert retries uit — asynchrone aanroepen, SQS redelivery na het verlopen van de visibility-timeout, Kinesis batch retries. Zonder een deterministische ontdubbelingssleutel en een conditionele write, zijn duplicaten onvermijdelijk.
← Containers · Alle domeinen · Opslag →
Oefen deze vragen → · Getimede oefening op ExamRoll.io →
Pass the whole exam — not just this question
You found this answer. Get every verified question and explanation in one place, and save hours of prep. Free to start.
Slaag voor je examen →