Amazon SAA-C03: Architetture Serverless e Guidate dagli Eventi / Integrazione API — Guida allo studio

Fa parte della AWS SAA-C03 — Guida di studio completa. Esercitati con risposte verificate nel centro esami Amazon, oppure fai test cronometrati su ExamRoll.io.

AWS Lambda: Modello di Esecuzione, Ciclo di Vita del Runtime e Cold Start

Lambda esegue il codice in micro-VM Firecracker isolate che seguono un ciclo di vita a due fasi. La fase INIT esegue il provisioning del container, il bootstrap del runtime, scarica e decomprime il pacchetto di deployment ed esegue qualsiasi inizializzazione a livello di modulo: costruzione di client SDK, caricamento di segreti decifrati con KMS, configurazione del pool di connessioni al database, caricamento delle classi JVM e warm-up del JIT. La fase INVOKE esegue l’handler. Un cold start comporta l’intero costo della fase INIT; un’invocazione warm riutilizza l’ambiente, quindi tutto ciò che viene memorizzato nella cache al di fuori dell’handler (pool di connessioni HTTP keep-alive, segreti decifrati, client DB) persiste tra le invocazioni su quel container. Questo è il motivo per cui il pattern canonico consiste nel costruire oggetti costosi a livello di modulo e riutilizzarli:

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):
    ...

L’entità del cold start varia a seconda del runtime. Node.js e Python richiedono da decine a qualche centinaio di millisecondi; la JVM e .NET possono superare il secondo. Per le funzioni collegate a una VPC, le ENI Hyperplane hanno in gran parte ammortizzato la penalità storica legata all’associazione delle ENI, ma le dimensioni del pacchetto e un codice INIT pesante rimangono i fattori dominanti.

Tre strumenti affrontano i cold start in modi diversi:

CaratteristicaComportamentoCostoIdeale per
Concurrency on-demandPredefinita; scala con un burst iniziale di ~500–3.000, poi +500/minPer invocazione + durataCarichi bursty, tolleranti alla latenza
Concurrency provisionedPre-inizializza N ambienti, fase INIT completata prima del trafficoPagamento per le unità provisioned 24/7 + invocazioniSLA di latenza p99 stringenti
SnapStart (Java, Python, .NET)Snapshot Firecracker dopo la fase INIT; ripristinato al cold startNessun costo aggiuntivo su Java; un piccolo costo di caching per gli altriFunzioni Java dove il provisioning completo è uno spreco

SnapStart è la soluzione economicamente più vantaggiosa per i carichi di lavoro Java senza contratti di latenza rigidi: i cold start si riducono di circa un ordine di grandezza senza costi aggiuntivi per invocazione. La concurrency provisioned è la risposta corretta quando un’API sincrona deve mantenere un p99 al di sotto, diciamo, di 100 ms durante i picchi; dimensionarla sul p95 del burst chiude il gap della tail-latency. Sottodimensionarla è un errore classico: la modalità on-demand avvia nuovi container solo quando arriva una richiesta, quindi un picco di traffico produce attese di diversi secondi per gli utenti reali.

# SAM: SnapStart on a Java 17 function
MyJavaFn:
  Type: AWS::Serverless::Function
  Properties:
    Runtime: java17
    SnapStart: { ApplyOn: PublishedVersions }
    AutoPublishAlias: live

La stessa concurrency provisioned può essere scalata tramite Application Auto Scaling: un’azione pianificata che aumenta le unità da 10 a 200 alle 07:45 e le riporta indietro alle 10:00 evita di pagare per la capacità warm durante la notte, eliminando al contempo i cold start dovuti al picco mattutino.

Il dimensionamento della memoria è contemporaneamente un selettore della CPU: la vCPU scala linearmente con la memoria fino a ~1.769 MB per vCPU. Una funzione fissata a 128 MB può costare complessivamente di più di una a 1.024 MB, perché un tempo di esecuzione raddoppiato spesso supera un prezzo per ms raddoppiato. Non tirare a indovinare: usa AWS Lambda Power Tuning per testare diverse configurazioni con payload rappresentativi.

Controlli di Concorrenza di Lambda e Protezione dei Sistemi a Valle

Tre selettori di concorrenza sono importanti e ognuno svolge un compito diverso:

Presumere che Lambda “scali all’infinito” ignora due limiti massimi. Primo, il limite di esecuzioni concorrenti a livello di account è reale, e i limiti di burst (iniziali 500–3.000 a seconda della Regione, poi +500/min) governano la velocità di aumento (ramp rate). Una volta superato, i chiamanti sincroni ricevono un’eccezione 429 TooManyRequestsException, che API Gateway espone come un errore 5xx. Secondo, i sistemi a valle hanno i propri limiti: un’istanza db.t3.micro con max_connections=85 non può sopravvivere a mille Lambda concorrenti che aprono ciascuna una connessione. PostgreSQL crea un processo di backend per ogni connessione, consumando ~10 MB di RAM; anche con CPU a disposizione, la sola creazione e chiusura delle connessioni può saturare l’istanza.

Le due mitigazioni sono (1) RDS Proxy, che mette in pool e multiplexa molte connessioni lato client su un piccolo insieme di connessioni di backend persistenti, e (2) inserire una coda in modo che la velocità di elaborazione sia disaccoppiata dalla velocità di arrivo delle richieste:

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 è una soluzione a modifica minima — il driver e la stringa di connessione cambiano a malapena — il che la rende la risposta giusta ogni volta che il requisito è “la minor modifica possibile all’applicazione” unito all’esaurimento delle connessioni. DynamoDB non ha questo problema: la sua API HTTPS è stateless, motivo per cui DynamoDB si abbina naturalmente a carichi di lavoro Lambda con un elevato fan-out.

IAM, Variabili d’Ambiente e Networking di Lambda

Ogni funzione assume un ruolo di esecuzione (execution role) al momento dell’invocazione. La policy di attendibilità (trust policy) del ruolo concede sts:AssumeRole a lambda.amazonaws.com; la sua policy di autorizzazione (permission policy) definisce ciò che la funzione può fare. Il runtime inserisce automaticamente le credenziali STS a breve termine in AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY e AWS_SESSION_TOKEN. Non incorporare mai le chiavi di accesso di un utente IAM nelle variabili d’ambiente o nel codice: sono statiche, individuabili nel codice sorgente trapelato o negli export di CloudTrail, devono essere ruotate manualmente e aggirano l’intero modello di credenziali temporanee.

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

Le variabili d’ambiente che contengono configurazioni sensibili dovrebbero essere crittografate con una chiave KMS gestita dal cliente, utilizzando gli “helper per la crittografia in transito” in modo che la console esegua la crittografia lato client. Decrittografare una sola volta in fase di INIT e memorizzare il testo in chiaro in una cache a livello di modulo, altrimenti ogni invocazione comporterà il costo di una chiamata API a KMS.

Di default, una funzione viene eseguita in un VPC gestito da AWS con accesso a internet in uscita senza restrizioni. Collegala al tuo VPC solo quando deve raggiungere risorse residenti nel VPC (RDS in sottoreti private, ElastiCache, on-premise tramite Direct Connect). Lambda collegherà quindi delle ENI Hyperplane nelle sottoreti specificate ed erediterà le loro regole di routing.

La trappola classica è posizionare una Lambda in una sottorete privata senza una rotta per il traffico verso i servizi AWS, se non attraverso un NAT gateway — o peggio, un’istanza NAT autogestita. Le istanze NAT si saturano su una singola NIC, sono un SPOF (Single Point of Failure) e vengono fatturate per GB. Anche i NAT gateway hanno un costo per GB e non sono necessari per il traffico verso i servizi AWS. Il pattern corretto è:

Questo mantiene il traffico sul backbone di AWS, rimuove i limiti di throughput del NAT e previene fatture a sorpresa per il traffico in uscita (egress). Nota che le ENI di Lambda non ricevono mai un IP pubblico; posizionare la funzione in una sottorete “pubblica” non le dà accesso a internet — è comunque necessario un NAT gateway in una sottorete pubblica separata con una rotta appropriata.

Amazon API Gateway: Tipi di Endpoint, Autorizzazione e Delivery

API Gateway offre tre tipi di API:

CaratteristicaREST APIHTTP APIWebSocket
LatenzaPiù alta~60% più bassaStateful, bidirezionale
CostoPiù alto~70% più economicoPer messaggio
Piani di utilizzo / Chiavi APINoNo
Trasformazioni richiesta/risposta (VTL)Limitate
Authorizer JWTTramite LambdaNativoTramite Lambda
WAFNo (usare CloudFront come frontend)

Scegli le REST API quando hai bisogno di chiavi API e piani di utilizzo, validazione delle richieste tramite JSON Schema, template di mapping VTL, authorizer Cognito con scope per metodo o WAF; scegli le HTTP API per pattern di proxy leggeri autenticati con JWT dove il costo e la latenza sono più importanti.

I tipi di endpoint determinano dove l’API viene esposta:

Selezionare “edge-optimized” per un’API interna a una singola Regione aggiunge un hop CloudFront non necessario e una propagazione più lenta dei deployment. Selezionare “regional” per un’API pubblica consumata globalmente forza ogni richiesta ad attraversare internet pubblico per raggiungere una singola Regione.

I domini personalizzati richiedono certificati ACM con una posizione che dipende dal tipo di endpoint: us-east-1 per gli endpoint edge-optimized (CloudFront è globale e termina il TLS lì); la Regione stessa dell’API per gli endpoint regional. Confondere questo aspetto è un errore di configurazione comune. Le mappature del percorso di base (base path mapping) consentono a un singolo dominio di multiplexare più API (/orders → API ordini, /users → API utenti).

L’autorizzazione ha quattro modelli, e andare oltre i meccanismi integrati è un classico anti-pattern:

MeccanismoQuando usarlo
Autorizzazione IAMI chiamanti sono principal AWS in grado di firmare con SigV4 (altri servizi, SDK, cross-account)
Authorizer di pool di utenti CognitoGli utenti si autenticano con un pool di utenti Cognito; il Gateway valida il JWT
Authorizer LambdaToken non standard, IdP di terze parti senza OIDC, logica complessa per richiesta
Chiavi API + piani di utilizzoMisurazione, throttling, quote — mai usati come autenticazione

Un authorizer Lambda personalizzato aggiunge un’invocazione extra per ogni richiesta (o per la durata della cache TTL), un’altra funzione da manutenere e monitorare, e un percorso di codice dove bug nella validazione della firma possono silenziosamente consentire l’accesso. Usalo solo quando i meccanismi integrati non possono davvero soddisfare il requisito.

L’integrazione proxy con Lambda è il pattern di default: l’intera richiesta viene passata come un evento e la funzione deve restituire una risposta con la struttura (envelope) prevista:

{
  "statusCode": 200,
  "headers": {"Content-Type": "application/json"},
  "body": "{\"orderId\":\"abc123\"}",
  "isBase64Encoded": false
}

Per un’ingestion di tipo fire-and-forget a TPS (transazioni al secondo) molto elevato, usa l’integrazione diretta con un servizio AWS di Gateway per inviare i dati direttamente a SQS o Kinesis, saltando completamente l’hop della Lambda. Questo elimina i cold start sul percorso di scrittura e disaccoppia la velocità di ingestion dalla capacità di elaborazione.

Per rollout sicuri, usa i deployment canary su uno stage: una percentuale del traffico viene indirizzata al nuovo deployment mentre la maggior parte rimane sulla versione stabile; le metriche CloudWatch specifiche per la versione canary guidano la decisione di promuovere o effettuare il 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

Per un semplice webhook dove la complessità di API Gateway è eccessiva (es. callback Slack single-tenant, gestore di push di GitHub), gli URL di funzione Lambda forniscono un endpoint HTTPS dedicato direttamente sulla funzione. Proteggili con AuthType: AWS_IAM quando i chiamanti sono principal AWS; se è NONE, è obbligatorio validare la firma della richiesta all’interno della funzione. Un URL di funzione con AuthType: NONE e nessuna verifica all’interno della funzione è un endpoint di calcolo anonimo su internet pubblico.

Tipi di Invocazione, Tentativi e Idempotenza

Le sorgenti di eventi si dividono in due categorie con comportamenti molto diversi. Le sorgenti di tipo push (API Gateway, ALB, S3, SNS, EventBridge, Cognito) invocano Lambda direttamente e richiedono una policy basata su risorse AWS::Lambda::Permission che conceda lambda:InvokeFunction con il Principal corretto (ad es., events.amazonaws.com) e il SourceArn. Senza di essa, la regola corrisponde agli eventi ma ogni invocazione viene rifiutata silenziosamente — la funzione non viene mai eseguita e i fallimenti appaiono solo in CloudTrail. Questo è distinto dal ruolo di esecuzione, che governa ciò che la funzione può fare, non chi può chiamarla.

Le sorgenti di tipo poll (SQS, Kinesis, DynamoDB Streams, MSK) vengono lette dal servizio Lambda tramite una mappatura della sorgente di eventi — non è necessaria alcuna policy basata su risorse, ma il ruolo di esecuzione deve concedere i permessi di lettura.

I tipi di invocazione determinano ulteriormente il comportamento dei tentativi (retry):

Poiché i tentativi sono integrati in ogni livello, l’idempotenza è obbligatoria, non opzionale. La scadenza di un visibility timeout di SQS durante una scrittura lenta o un tentativo asincrono dopo un errore 5xx a valle produrranno duplicati. Il pattern canonico utilizza una chiave deterministica e una scrittura condizionale su 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)

Il decoratore @idempotent di AWS Lambda Powertools implementa esattamente questo pattern utilizzando DynamoDB come backend.

Disaccoppiamento con SQS e SNS

Collegare sorgenti push ad alto fan-out direttamente a Lambda è fragile. Le notifiche di eventi S3, ad esempio, sono sincrone per ogni evento e soggette al limite massimo di concorrenza di Lambda; se le invocazioni superano la concorrenza disponibile durante un caricamento a raffica (una campagna di marketing che rilascia migliaia di documenti in pochi secondi), la finestra di tentativi di S3 è breve e gli eventi possono di fatto essere persi. Il rimedio è un buffer:

PatternQuando usarlo
S3 → Lambda direttoFrequenza di eventi bassa e prevedibile; elaborazione idempotente
S3 → SQS → LambdaCarichi di lavoro a raffica; necessità di retry/DLQ; rate limit a valle
S3 → SNS → più SQSFan-out verso più consumer indipendenti
S3 → EventBridge → molti targetRouting tra account; filtraggio basato sul contenuto

SNS è un sistema pub/sub: una pubblicazione, molti sottoscrittori (SQS, Lambda, HTTPS, email). Il filtraggio dei messaggi è basato sugli attributi. SQS è una coda point-to-point durevole che conserva i messaggi fino a 14 giorni. La combinazione più comune e robusta è il fan-out SNS → SQS, che fornisce a ogni consumer la propria coda bufferizzata per scalabilità e riesecuzione indipendenti.

Per un ordinamento rigoroso (ad es., ordini per cliente elaborati in sequenza), usare una coda SQS FIFO con MessageGroupId impostato sulla chiave di ordinamento. I messaggi all’interno di un gruppo vengono consegnati in ordine; gruppi diversi vengono elaborati in parallelo. Le code SQS standard offrono solo un ordinamento best-effort.

Il pattern canonico di ingestion disaccoppiata utilizza l’integrazione diretta di API Gateway con SQS per assorbire i picchi e un processore con rate limiting:

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

La concorrenza riservata è deliberata — limita la velocità con cui il database riceve le scritture, così che la coda (e non RDS) assorba il picco. I messaggi falliti vengono instradati a una DLQ dopo maxReceiveCount per un’ispezione offline.

EventBridge: Regole, Input Transformation e API Destination

EventBridge è un event bus consapevole dello schema con matching avanzato di pattern JSON, sorgenti di partner SaaS, registro degli schemi e funzionalità di archiviazione/replay. Le regole (rule) effettuano il matching sui pattern degli eventi e fanno fan-out verso più di 30 tipi di target (Lambda, Step Functions, SQS, Kinesis, ECS, Firehose), con filtraggio basato sul contenuto del corpo del messaggio — non solo sugli attributi come in SNS:

{
  "source": ["tenant.energy"],
  "detail-type": ["UsageReported"],
  "detail": { "kWh": [{ "numeric": [">", 100] }] }
}

Una regola può avere fino a cinque target, ognuno dei quali riceve l’evento grezzo o un sottoinsieme trasformato. Gli Input transformer impongono un disaccoppiamento debole: un InputPathsMap estrae percorsi JSON dall’evento e un InputTemplate li rimodella esattamente in ciò che il target si aspetta:

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>}

Ogni Lambda di validazione riceve solo ciò di cui ha bisogno; il validatore dell’indirizzo non vede mai il token della carta di credito. Questo è decisamente superiore a una Lambda monolitica che riceve l’intero evento ed esegue diramazioni al suo interno — un monolite concentra i permessi IAM (un unico ruolo deve possedere tutti i permessi a valle), aumenta il raggio d’impatto (blast radius) di un bug, accoppia la cadenza dei deployment, impedisce di ottimizzare memoria/timeout per singola responsabilità e costringe l’intera funzione a scalare sulla base della frequenza del ramo più trafficato.

Le API destination invertono la direzione: EventBridge chiama un endpoint HTTPS esterno. Abbinate a una connessione (connection) che memorizza credenziali di tipo Basic, API-key o OAuth in Secrets Manager, questo è il modo serverless per notificare un SaaS di terze parti quando, ad esempio, un job di AWS Batch ha successo — senza bisogno di Lambda. EventBridge cattura l’evento di cambio di stato, una regola fa matching su JobSucceeded e il target di tipo API destination effettua una POST verso il vendor con le credenziali iniettate dalla connessione.

Le regole pianificate (Scheduled rule) (con espressioni cron/rate) o il più recente EventBridge Scheduler sostituiscono le istanze EC2 di heartbeat per task periodici — report notturni, aggiornamento orario della cache.

Scegliere EventBridge invece di SNS quando il filtraggio si basa sul contenuto del corpo del messaggio (non solo sugli attributi), quando nuovi consumer devono potersi collegare in un secondo momento senza modifiche al producer, o quando il routing si estende a più account o sorgenti SaaS. Scegliere SNS quando il fan-out è una semplice notifica filtrata per attributi a un insieme stabile di sottoscrittori.

Step Functions: Orchestrazione e Map Distribuita

Quando un flusso di lavoro ha più di un paio di passaggi, diramazioni, tentativi di riesecuzione, approvazioni umane o lunghe attese, incorporare tale logica in una catena di Lambda diventa ingestibile. Step Functions esternalizza la macchina a stati in Amazon States Language.

Ogni task dovrebbe dichiarare esplicitamente Retry e Catch:

"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"
}

Gli stati Parallel e Map eseguono rami in modo concorrente e aggregano i risultati — una soluzione ideale per sistemi di gestione ordini con validatori indipendenti (indirizzo, inventario, pagamento). Lo stato tra i passaggi fluisce attraverso il documento JSON dell’esecuzione, eliminando la necessità di un database condiviso usato unicamente per il coordinamento del flusso di lavoro.

Il pattern .waitForTaskToken mette in pausa l’esecuzione finché un attore esterno non chiama SendTaskSuccess con il token — la risposta canonica quando un flusso di lavoro si estende tra Lambda, EC2, container, sistemi on-premise e richiede approvazione manuale con un overhead operativo minimo:

"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 estende lo stato Map standard per elaborare fino a 10.000 esecuzioni figlie parallele e può iterare direttamente su oggetti in un bucket S3 o su righe di un file CSV/JSONL, con batching, checkpointing e tolleranza ai guasti automatici. Per migliaia di oggetti S3 semistrutturati, è l’opzione operativamente più efficiente: basta puntarlo a un prefisso, definire il task per singolo elemento, e Step Functions gestisce il fan-out, MaxConcurrency, i tentativi di riesecuzione e l’aggregazione dei risultati:

{
  "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 } }
  }
}

Ricostruire la stessa logica su SQS o EventBridge richiederebbe una gestione personalizzata per il completamento, i tentativi e l’assemblaggio dei risultati.

Step Functions vs. EventBridge: Step Functions è la scelta giusta quando tu controlli la sequenza e il risultato — stato, diramazioni, tentativi, approvazioni. EventBridge è la scelta giusta quando i producer non sanno o non si preoccupano di chi consuma gli eventi, e i consumer si collegano in modo indipendente.

Notifiche di Eventi S3

Per l’elaborazione quasi in tempo reale degli upload, configura le notifiche di eventi S3 su s3:ObjectCreated:* (o una variante specifica come Put, Post, CompleteMultipartUpload) con una Lambda come destinazione — tenendo conto delle avvertenze sui picchi di traffico (burst) menzionate sopra. Misure di protezione:

Streaming: Kinesis Data Streams vs. Firehose

Kinesis Data Streams (KDS) è un log partizionato (sharded), ordinato e riproducibile con una conservazione (retention) da 24 ore a 365 giorni. L’ordine è preservato per shard, basato sulla chiave di partizione — un aspetto critico per l’aggregazione per dispositivo o per tenant. Più consumer possono leggere in modo indipendente (enhanced fan-out per un throughput isolato per consumer). Scegli KDS quando hai bisogno di riproduzione ordinata (replay), più consumer indipendenti o un throughput elevato per shard.

Kinesis Data Firehose è un flusso di consegna completamente gestito verso S3, Redshift, OpenSearch o Splunk, con buffering integrato (60 s o 1–128 MB), trasformazione opzionale tramite Lambda, compressione (GZIP, Snappy) e conversione in formato Parquet/ORC. Non ci sono shard da gestire. Firehose è la scelta a basso impatto operativo quando non sono necessari consumer personalizzati o la riproduzione dei dati, ma solo l’atterraggio di dati quasi in tempo reale.

La pipeline canonica per l’analisi quasi in tempo reale è producer → KDS → Firehose → S3 (Parquet) → Athena/QuickSight, con un arricchimento opzionale tramite Lambda in Firehose.

AWS Transfer Family per SFTP Gestito

Quando i partner richiedono l’uso di SFTP, FTPS o FTP per trasferire file da o verso S3 o EFS, AWS Transfer Family fornisce un endpoint gestito e multi-AZ che parla il protocollo già utilizzato dai client. L’autenticazione supporta utenti gestiti dal servizio, chiavi SSH o IdP personalizzati tramite API Gateway/Lambda. I file atterrano direttamente in S3 con SSE e le policy di ciclo di vita applicate; le policy IAM di scope-down limitano ogni utente a un prefisso specifico.

Costruire una soluzione simile su EC2 richiederebbe l’hardening di OpenSSH, l’applicazione di patch, l’alta disponibilità (HA) tra AZ, la rotazione delle chiavi e l’invio dei log — tutte attività che Transfer Family gestisce al posto tuo. Sceglilo ogni volta che il requisito è “i partner ci inviano file tramite SFTP” e vuoi che i file arrivino in S3 con il minimo overhead operativo.

Comporre un Pattern Serverless Canonico

Un design di ingestione a basso overhead per metriche orarie per-tenant: i sensori inviano una richiesta POST a API Gateway (HTTP API, regional) → una Lambda valida e pubblica su EventBridge → delle regole instradano l’evento a una Lambda che scrive su DynamoDB (ID del tenant come chiave di partizione, bucket orario come chiave di ordinamento) e, in parallelo, a Firehose → S3 (Parquet) per l’analisi. Nuovi consumer si collegano come regole aggiuntive di EventBridge senza modificare i producer — un requisito di estensibilità che il solo SNS non soddisferebbe in modo altrettanto pulito. Laddove il throughput sostenuto e l’ordinamento sono importanti (riconciliazione della fatturazione, flussi di eventi finanziari), sostituisci EventBridge con Kinesis Data Streams e utilizza l’enhanced fan-out per i consumer indipendenti.

Catalogo delle trappole: perché i pattern errati più comuni falliscono

Istanza/gateway NAT per il traffico verso servizi AWS da Lambda in subnet private. Le istanze NAT legano il throughput alla NIC di una singola EC2 e sono un SPOF; i gateway NAT fatturano per GB. Entrambi non sono necessari per destinazioni verso servizi AWS. Usare endpoint gateway per S3/DynamoDB, endpoint di interfaccia per tutto il resto.

Ignorare i cold start su API sensibili alla latenza. La modalità on-demand esegue il provisioning dei container solo quando arriva una richiesta, quindi i picchi di traffico (burst) non rispettano gli SLA. Dimensionare la provisioned concurrency sul p95 dei burst; usare SnapStart per i carichi di lavoro Java senza SLA stringenti.

Lambda monolitica che riceve un evento completo e si dirama internamente. Viola il principio del privilegio minimo (un singolo ruolo detiene tutte le permissioni a valle), accoppia la cadenza di deployment, impedisce l’ottimizzazione per singola responsabilità e scala l’intera funzione al ritmo del ramo più rumoroso. Suddividere per responsabilità; collegare con EventBridge o Step Functions.

Connessioni dirette al DB da molte Lambda. Il numero totale di connessioni eguaglia le invocazioni concorrenti perché i container non condividono i pool. Risolvere con RDS Proxy (pooling), reserved concurrency (rate cap) o SQS (buffering).

Lambda sincrona per l’ingestion di dati a raffica (bursty). Il superamento della concorrenza restituisce 429 ad API Gateway e 5xx ai client; le notifiche dirette da S3 durante i picchi di traffico scartano silenziosamente gli eventi. Inserire SQS o usare l’integrazione diretta Gateway → SQS.

URL di funzione Lambda pubblici con AuthType: NONE e nessuna validazione della firma all’interno della funzione. Capacità di calcolo anonima su internet pubblico. Usare AWS_IAM per chiamanti AWS o validare le firme per webhook di terze parti.

Authorizer Lambda personalizzato dove ne basterebbe uno integrato. Aggiunge latenza, un’altra funzione da manutenere e un percorso di codice in cui bug nel controllo della firma consentono silenziosamente l’accesso. Preferire l’autorizzazione IAM per i principal AWS; l’authorizer Cognito per le user pool.

Regione errata del certificato ACM per i domini personalizzati. Gli endpoint edge-optimized richiedono il certificato in us-east-1; gli endpoint regionali nella stessa Regione dell’API.

Mancanza di AWS::Lambda::Permission per le sorgenti di tipo push (EventBridge, S3, SNS). Gli eventi corrispondono alle regole ma le invocazioni vengono negate silenziosamente. È una cosa distinta dal ruolo di esecuzione: questo regola chi può chiamare la funzione, non cosa la funzione può fare.

Mancanza di idempotenza. Ogni livello esegue dei tentativi (retry): invocazioni asincrone, riconsegna di SQS alla scadenza del visibility-timeout, retry dei batch di Kinesis. Senza una chiave di deduplicazione deterministica e una scrittura condizionale, i duplicati sono inevitabili.



Container e Orchestrazione · Tutti i domini · Storage e Ciclo di Vita dei Dati

Esercitati su queste domande → · Pratica cronometrata su 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.

Supera l'esame →

Sfoglia Amazon →

Related guides

Accesso tutto incluso

Un abbonamento. Ogni esame.

Ogni piano sblocca la ricerca illimitata di risposte, test pratici, spiegazioni AI e la libreria completa di risorse — in oltre 20 lingue.

Mensile
24.87
Just €0.83/day
Tutto incluso:
  • Ricerca risposte illimitata
  • Test pratici illimitati
  • Spiegazioni basate su AI
  • Libreria completa di risorse
  • Oltre 20 lingue
  • Aggiornamenti settimanali dei contenuti
  • Premi e referral
  • Supporto prioritario
Inizia la prova gratuita

Nessuna carta di credito richiesta*

Miglior valore
12 mesi
179.87
Just €0.49/daySave 40%
Tutto incluso:
  • Ricerca risposte illimitata
  • Test pratici illimitati
  • Spiegazioni basate su AI
  • Libreria completa di risorse
  • Oltre 20 lingue
  • Aggiornamenti settimanali dei contenuti
  • Premi e referral
  • Supporto prioritario
Inizia la prova gratuita

Nessuna carta di credito richiesta*

✓ Piano gratuito incluso · ✓ Annulla in qualsiasi momento · ✓ Tutti i piani sbloccano il prodotto completo