Jak działa egzamin i jak czytać tę stronę
najpierw zasady gry, potem graTa strona to repetytorium do egzaminu AWS Certified Developer – Associate (DVA-C02). Każdy rozdział odpowiada konkretnym umiejętnościom (skill) z oficjalnego exam guide w wersji 2.1 — ich numery widzisz w znacznikach takich jak 1.2.3. Zamiast listy funkcji dostajesz mechanizmy: jak coś działa, dlaczego tak, i jak egzamin próbuje cię na tym złapać.
Format egzaminu
| Element | Wartość | Co to znaczy dla ciebie |
|---|---|---|
| Liczba pytań | 65: 50 punktowanych + 15 niepunktowanych | Niepunktowanych nie da się rozpoznać — traktuj każde pytanie poważnie. |
| Czas | 130 minut | Ok. 2 minuty na pytanie; długie scenariusze czytaj od ostatniego zdania (pytania). |
| Wynik | skala 100–1000, próg zaliczenia 720 | Wynik jest skalowany i liczony za cały egzamin (zalicz / nie zalicz). |
| Typy pytań | multiple choice (1 poprawna z 4) i multiple response (2+ poprawne z 5+) | W multiple response treść mówi, ile odpowiedzi wybrać. |
| Brak odpowiedzi | liczony jako błędny, zgadywanie nie jest karane | Nigdy nie zostawiaj pustego pytania. |
| Emerging topics | pytania pretestowe o nowych technologiach, nie wpływają na wynik | Nie panikuj, gdy trafisz coś spoza tej listy. |
| Nazwy usług | oficjalne skróty, np. Amazon SNS | Pełne nazwy są w funkcji Help podczas egzaminu. |
Domeny i ich waga
| Domena | Waga | Części tej strony |
|---|---|---|
| 1 · Development with AWS Services | 32% | I (wzorce), II (Lambda, kontenery), III (dane), IV (integracja) |
| 2 · Security | 26% | I (IAM, STS), VI (Cognito, KMS, sekrety, ochrona danych) |
| 3 · Deployment | 24% | V (API Gateway), VII (CloudFormation, SAM, CI/CD, CodeDeploy, testy) |
| 4 · Troubleshooting and Optimization | 18% | VIII (CloudWatch, X-Ray, troubleshooting), plus wydajność w II–V |
Jak czytać rozdziały
Strona ma trzy poziomy. Każdy blok nosi znacznik — L1 podstawy (model mentalny), L2 szczegóły na poziomie egzaminu, L3 rzadkie detale i przypadki brzegowe. Przełącznik głębokości jest w lewym dolnym rogu: głębokość 1 to szybka powtórka całości, głębokość 3 to wszystko.
| Ramka | Co w niej jest | Kiedy czytać |
|---|---|---|
| 🎯 Na egzaminie | na co egzamin kładzie największy nacisk | zawsze — to najwyżej punktowana wiedza |
| ⚠️ Pułapki | najczęstsze błędne odpowiedzi (dystraktory) i dlaczego kuszą | przed każdym egzaminem próbnym |
| 🧪 Scenariusze egzaminacyjne | pytanie w stylu egzaminu → słowa-klucze → odpowiedź i dlaczego nie pozostałe | jako trening; zakryj odpowiedź |
| 🧠 / ❓ / 🔥 / 🤓 | pytanie do przemyślenia, „nie ma głupich pytań”, dialog pojęć, ciekawostka | gdy coś nie „klika” |
| 📌 W pigułce | streszczenie rozdziału | powtórka dzień przed egzaminem |
- Znajdź w pytaniu słowa-klucze („least operational overhead”, „decouple”, „exactly once”, „near real time”).
- Wpisz je w wyszukiwarkę poniżej albo sprawdź słownik słów-kluczy na końcu strony.
- Przeczytaj 🎯 i ⚠️ w rozdziale — zwykle tam jest różnica między dwiema „prawie dobrymi” odpowiedziami.
- Liczby (limity, czasy, rozmiary) sprawdzisz w tabeli liczb i limitów.
Mapa kursu
Funkcja Lambda czyta wiadomości z kolejki SQS paczkami po 10. Dziewiąta wiadomość w paczce zawsze rzuca wyjątek. Co stanie się z pozostałymi dziewięcioma wiadomościami — i jak to naprawić jedną zmianą konfiguracji oraz kodu? Odpowiedź czeka na końcu strony, a cała mechanika w rozdziałach o SQS i zdarzeniach Lambdy.
Fakty sprawdzone w oficjalnym exam guide DVA-C02 (wersja 2.1) i dokumentacji AWS w październiku 2026. AWS zmienia limity i funkcje — przed egzaminem zerknij do What's New.
Fundamenty
Wzorce architektoniczne, IAM, dostęp programowy (CLI/SDK/STS), sieć VPC z perspektywy dewelopera oraz ruch przychodzący: ELB, Auto Scaling i Route 53. To słownik, którym posługują się wszystkie kolejne rozdziały — pytania o Lambdę, DynamoDB czy API Gateway bardzo często rozstrzygają się na roli IAM, na retry albo na podsieci.
Wzorce architektoniczne i odporność na błędy
ponawiaj mądrze, nie głośnoWyobraź sobie pizzerię. Jeśli kelner stoi przy piecu i czeka, aż pizza się upiecze, zanim przyjmie następne zamówienie, to działa synchronicznie i ściśle powiązany (tight coupling) z kucharzem. Jeśli przypina kartkę z zamówieniem na tablicy i wraca do sali, to działa asynchronicznie, a tablica jest luźnym powiązaniem (loose coupling): kucharz może być wolniejszy, chory albo może ich być trzech — kelnera to nie obchodzi. W AWS tą tablicą jest kolejka (SQS), temat (SNS), szyna zdarzeń (EventBridge), strumień (Kinesis) albo przepływ (Step Functions).
Druga połowa rozdziału to odporność (resilience): co robi Twój kod, gdy usługa, którą woła (AWS albo zewnętrzne API płatności), odpowie błędem, przekroczy czas albo zacznie dławić (throttling). Odpowiedź egzaminu jest prawie zawsze ta sama: timeout + retry z exponential backoff i jitter + limit prób + idempotentność, a przy dłuższej awarii — circuit breaker.
1.1.11.1.21.1.31.1.41.1.51.1.13
- „Decouple”, „buffer spikes”, „components fail independently” → wstaw kolejkę/temat/szynę między komponenty (luźne powiązanie, asynchroniczność).
- „One event, many independent consumers” → fan-out: SNS → wiele kolejek SQS (albo EventBridge z wieloma regułami).
- Choreography = usługi reagują na zdarzenia, brak centralnego koordynatora (EventBridge). Orchestration = centralny koordynator steruje krokami, retry i kompensacją (Step Functions).
- Stateless = żadnego stanu sesji w pamięci instancji/funkcji; stan trzymaj w DynamoDB, ElastiCache, S3 — wtedy skalujesz poziomo i nie potrzebujesz sticky sessions.
- Błędy przejściowe (5xx, timeouty,
ThrottlingException,ProvisionedThroughputExceededException) → retry z exponential backoff i jitter, z limitem prób. Błędy 4xx typuAccessDenied/ValidationException→ nie ponawiaj. - SDK AWS ponawia sam: tryb
standard(domyślny, 3 próby łącznie) lubadaptive(plus kliencki rate limiter). UstawiaszAWS_RETRY_MODE/retry_modeiAWS_MAX_ATTEMPTS/max_attempts. - Retry wymaga idempotentności: ten sam token/klucz żądania (np.
ClientToken,ClientRequestToken, klucz idempotencji w DynamoDB) = ten sam efekt.
Wzorce architektoniczne, które egzamin nazywa wprost
| Wzorzec / pojęcie | Co to znaczy | Typowa odpowiedź AWS |
|---|---|---|
| Monolit | Jedna jednostka wdrożenia; wszystko skaluje się i wdraża razem. | EC2/Beanstalk; na egzaminie zwykle punkt wyjścia do „rozbij na mikroserwisy”. |
| Mikroserwisy | Małe, niezależnie wdrażane usługi, każda z własnymi danymi i API. | Lambda/ECS + API Gateway, komunikacja przez SQS/SNS/EventBridge. |
| Event-driven | Producent emituje zdarzenie „coś się stało”, nie wie, kto je obsłuży. | EventBridge, SNS, S3 Event Notifications, DynamoDB Streams. |
| Fan-out | Jedno zdarzenie → wiele niezależnych odbiorców, każdy we własnym tempie. | SNS → kilka kolejek SQS (każda z własnym konsumentem i DLQ). |
| Choreography | Każda usługa słucha zdarzeń i publikuje kolejne; brak dyrygenta. | EventBridge (reguły per usługa). Trudniej o globalne retry/timeouty. |
| Orchestration | Centralny koordynator wywołuje kroki, pilnuje retry, timeoutów i kompensacji (saga). | Step Functions (Retry/Catch na krokach). |
| Sync vs async | Sync: wołający czeka na wynik (żądanie–odpowiedź). Async: wrzuca i idzie dalej, wynik później/osobno. | Sync: API Gateway → Lambda, ALB. Async: SQS, SNS, Lambda Event invocation. |
| Stateful vs stateless | Stateful trzyma stan sesji lokalnie; stateless — każde żądanie samowystarczalne. | Stan na zewnątrz: DynamoDB, ElastiCache, S3; tokeny JWT zamiast sesji w pamięci. |
Retry, Catch i krokami kompensującymi.Retry, exponential backoff i jitter
Exponential backoff = każde kolejne ponowienie czeka dłużej (np. 1×, 2×, 4×, 8× bazowego opóźnienia), z górnym limitem. Jitter = losowy składnik opóźnienia. Bez jitter tysiąc klientów, którzy dostali błąd w tej samej chwili, ponowi w tej samej chwili — usługa dostaje falę („thundering herd”) i znowu pada. AWS SDK używa full jitter: opóźnienie losowane z całego przedziału od 0 do wyliczonej granicy. Najlepsze praktyki Well-Architected: backoff + jitter + maksymalna liczba ponowień, a w systemie wielowarstwowym ponawiaj w jednym miejscu, bo retry na każdej warstwie mnoży ruch.
| Ustawienie SDK | Co robi | Kiedy |
|---|---|---|
retry_mode = standard (domyślny) | Exponential backoff z full jitter, retry quota (token bucket — gdy żetony się skończą, SDK przestaje ponawiać i szybko zwraca błąd), maks. opóźnienie 20 s. | Prawie zawsze. Zalecany domyślny tryb dla wszystkich obciążeń. |
retry_mode = adaptive | Wszystko ze standard + kliencki rate limiter, który po odpowiedziach throttling może opóźnić nawet pierwsze żądanie. | Jeden zasób, dużo throttlingu, akceptowalne opóźnienia. Nie jako ogólny domyślny. |
retry_mode = legacy | Stare, różne w każdym SDK zachowanie, bez ustandaryzowanej retry quota. | Tylko wsteczna kompatybilność — przejdź na standard. |
max_attempts / AWS_MAX_ATTEMPTS | Łączna liczba prób łącznie z pierwszą. Domyślnie 3 (1 + 2 retry); 1 wyłącza retry. | Podnieś dla długich operacji wsadowych, obniż dla ścieżek o niskim opóźnieniu. |
# ~/.aws/config — dotyczy CLI i wszystkich SDK
[default]
retry_mode = standard
max_attempts = 5
# albo zmienne środowiskowe (mają pierwszeństwo przed plikiem)
export AWS_RETRY_MODE=adaptive
export AWS_MAX_ATTEMPTS=5
Własny kod (np. wywołanie zewnętrznego API płatności, którego SDK AWS nie obsługuje) piszesz według
tego samego przepisu. Szkic w Pythonie — „full jitter” to po prostu random.uniform(0, granica):
import random, time
def call_with_retry(fn, max_attempts=5, base=0.1, cap=20.0):
for attempt in range(max_attempts):
try:
return fn(timeout=2.0) # zawsze jawny timeout
except TransientError: # 5xx, timeout, 429/throttling
if attempt == max_attempts - 1:
raise # limit prób → oddaj błąd (albo DLQ)
time.sleep(random.uniform(0, min(cap, base * 2 ** attempt))) # backoff + full jitter
# błędy 4xx (walidacja, brak uprawnień) NIE są łapane → bez retry
Idempotentność, timeouty i circuit breaker
Idempotentna operacja to taka, której wielokrotne wykonanie daje ten sam efekt co jedno.
Analogia: przycisk windy — naciśnięcie go pięć razy nie przywoła pięciu wind. W systemach rozproszonych łatwo o
„at most once” albo „at least once”, a „exactly once” robisz przez tokeny idempotencji: usługa pamięta
token i na powtórzone żądanie zwraca poprzedni wynik zamiast wykonać akcję drugi raz. Przykłady w AWS:
ClientToken w RunInstances (EC2), ClientRequestToken w
TransactWriteItems (DynamoDB, token ważny 10 minut), narzędzie Idempotency z Powertools for AWS Lambda
(stan trzyma w warstwie persystencji — najczęściej w tabeli DynamoDB, może też w Valkey/Redis). Kolejki standardowe SQS i strumienie dostarczają „at least once”, więc konsument
też musi być idempotentny (SQS, Lambda).
Timeouty: ustawiaj jawnie timeout połączenia i żądania; nie polegaj na wartościach domyślnych, bo nie znają Twojego obciążenia. Za wysoki timeout wiąże zasoby (wątki, połączenia, czas Lambdy, za który płacisz), za niski generuje sztuczne błędy. Klasyk egzaminu: Lambda z timeoutem 15 min czeka na zawieszone API — ustaw krótszy timeout klienta HTTP niż timeout funkcji.
Circuit breaker (bezpiecznik): jeśli wywołania do zależności powtarzalnie kończą się błędem/timeoutem, wołający przestaje ją wołać na pewien czas (obwód otwarty — szybki błąd albo fallback), potem przepuszcza próbne wywołanie (half-open), a gdy się uda — wraca do normalnego stanu (zamknięty). Retry jest na krótkie, przejściowe błędy; circuit breaker — na dłuższą awarię, żeby nie dobijać leżącej usługi i nie marnować własnych zasobów. W AWS implementuje się go np. w Step Functions + stan obwodu w DynamoDB.
- „Ponawiaj natychmiast w pętli, aż się uda” — kusi prostotą, ale przy throttlingu tylko pogłębia problem. Poprawnie: backoff + jitter + limit prób.
- „Exponential backoff wystarczy” — bez jitter klienci ponawiają synchronicznie i robią fale ruchu. Egzamin lubi odpowiedź z oboma słowami.
- „Zwiększ liczbę retry” jako lekarstwo na
ProvisionedThroughputExceededException/ThrottlingException— retry jest częścią rozwiązania, ale jeśli limit jest stale przekraczany, trzeba podnieść pojemność/kwotę albo rozłożyć ruch (np. kolejką). - Retry błędów 4xx (
AccessDeniedException,ValidationException) — nie zmienią się po ponowieniu; SDK ich nie ponawia. - Retry bez idempotentności — powtórzone „obciąż kartę” = podwójna płatność. Najpierw idempotency key, potem retry.
- Sticky sessions jako „skalowanie” — to obejście dla aplikacji stateful, nie wzorzec stateless; poprawnie: wynieś sesję do ElastiCache/DynamoDB.
- Choreography vs orchestration odwrotnie — „centralny koordynator, widoczność przepływu, kompensacje” to orkiestracja (Step Functions), nie EventBridge.
Aplikacja wywołuje DynamoDB i w godzinach szczytu sporadycznie dostaje ProvisionedThroughputExceededException. Co powinien zrobić kod, aby obsłużyć te błędy przy najmniejszym nakładzie pracy?
sporadycznie · throttling · najmniejszy nakład
Odpowiedź
Polegać na wbudowanym retry SDK (exponential backoff z jitter), ewentualnie zwiększyć max_attempts. To błąd typu throttling, SDK go ponawia automatycznie.
Dlaczego nie: natychmiastowe ponawianie w pętli (pogłębia throttling); własny kod retry od zera (więcej pracy, SDK już to robi); przejście na inną bazę (przesada przy sporadycznych błędach).
Po złożeniu zamówienia trzy niezależne systemy (fakturowanie, magazyn, analityka) muszą dostać kopię zdarzenia i przetwarzać je we własnym tempie, z możliwością ponowienia. Jaka architektura?
jedno zdarzenie · wielu niezależnych odbiorców · własne tempo
Odpowiedź
Fan-out: temat SNS z trzema subskrybującymi kolejkami SQS (albo EventBridge z trzema regułami). Każda kolejka buforuje i ma własną DLQ.
Dlaczego nie: jedna kolejka SQS z trzema konsumentami (każda wiadomość trafi tylko do jednego z nich); synchroniczne wywołanie trzech API (ścisłe powiązanie, awaria jednego blokuje zamówienie).
Lambda wywołuje zewnętrzne API dostawcy, które co jakiś czas przestaje odpowiadać na kilka minut. Funkcja czeka wtedy do swojego timeoutu, rosną koszty i współbieżność. Co zrobić?
zależność zewnętrzna · dłuższa awaria · marnowane zasoby
Odpowiedź
Krótki timeout klienta HTTP + ograniczony retry z backoff i jitter + circuit breaker (po serii błędów szybki fallback zamiast kolejnych wywołań), ew. bufor SQS przed integracją.
Dlaczego nie: wydłużenie timeoutu Lambdy (zwiększa koszt, nic nie naprawia); więcej pamięci (nie dotyczy czekania na sieć); nieograniczony retry (dobija leżącą usługę).
Klient ponawia żądanie „utwórz płatność” po timeoucie. Czasami powstają dwie płatności. Jak to naprawić?
duplikaty po retry · exactly-once z punktu widzenia klienta
Odpowiedź
Klucz idempotencji generowany przez klienta i wysyłany z każdym ponowieniem; serwer zapisuje go (np. warunkowym zapisem do DynamoDB) i na duplikat zwraca poprzedni wynik.
Dlaczego nie: wyłączenie retry (gubi płatności przy prawdziwych błędach); dłuższy timeout (zmniejsza, ale nie usuwa problemu); kolejka FIFO sama w sobie (deduplikuje tylko w oknie 5 minut i tylko w SQS — rozdz. SQS).
Aplikacja webowa na kilku instancjach EC2 za ALB trzyma koszyk w pamięci instancji. Po skalowaniu w dół użytkownicy tracą koszyki. Najlepsze rozwiązanie długoterminowe?
stan w pamięci · skalowanie · utrata sesji
Odpowiedź
Uczyń aplikację stateless — przenieś sesję do ElastiCache (Redis/Valkey) lub DynamoDB.
Dlaczego nie: sticky sessions (nadal tracisz koszyk, gdy instancja znika); wyłączenie skalowania w dół (koszt, i tak awarie instancji).
🔬 Głębiej: retry quota, nagłówek x-amz-retry-after, DynamoDB i nowe zachowanie 2026
Retry quota w trybie standard to token bucket wspólny dla klienta: każde ponowienie zużywa żetony, sukces je
oddaje. Gdy żetonów brak, SDK nie ponawia i od razu zwraca błąd — to chroni usługę przed lawiną retry przy
dłuższej awarii (zachowanie zbliżone do circuit breakera po stronie SDK). Niektóre usługi zwracają nagłówek
x-amz-retry-after (opóźnienie w ms) — SDK go uwzględnia, przycinając czekanie do przedziału od wyliczonego backoffu do backoffu + 5 s.
Dokumentacja SDK (2026) opisuje zaktualizowane zachowanie retry, które na razie wymaga opt-in zmienną
AWS_NEW_RETRIES_2026=true: bazowe opóźnienie 50 ms dla błędów przejściowych i 1000 ms dla
throttlingu, a klienci DynamoDB i DynamoDB Streams domyślnie 4 próby. Bez opt-in SDK działa po staremu.
W starszych testach próbnych zobaczysz po prostu „exponential backoff” bez tych liczb — odpowiedź jest ta sama.
- Luźne powiązanie i asynchroniczność = kolejka/temat/szyna między komponentami; fan-out = SNS → wiele SQS.
- Choreografia = EventBridge, bez dyrygenta; orkiestracja = Step Functions, z centralnym Retry/Catch.
- Stateless: stan sesji poza instancją (DynamoDB/ElastiCache) → swobodne skalowanie poziome.
- Błędy przejściowe i throttling: retry + exponential backoff + jitter + limit prób; 4xx — bez retry.
- SDK:
standard(domyślny, 3 próby, maks. 20 s opóźnienia) alboadaptive(rate limiter);max_attemptsliczy też pierwszą próbę. - Retry ⇒ idempotentność (tokeny); dłuższa awaria ⇒ circuit breaker; zawsze jawne timeouty.
IAM: kto może co, na czym i kiedy
jeden „Deny” bije wszystkie „Allow”IAM działa jak ochrona w biurowcu. Masz identyfikator (principal: użytkownik IAM, rola, sesja roli, usługa AWS), a przy każdych drzwiach strażnik sprawdza listy: tę przypiętą do Ciebie (identity-based policy — „co ta osoba może”) i tę wiszącą na drzwiach (resource-based policy — „kto może tu wejść”). Domyślnie odpowiedź brzmi nie (implicit deny). Wystarczy jedno wyraźne „wolno” (Allow) na którejś liście, ale jedno wyraźne „zakaz” (explicit Deny) gdziekolwiek przekreśla wszystko.
Aplikacje nie powinny mieć „swoich” kluczy. Zamiast tego przyjmują rolę (assume role):
dostają tymczasowe poświadczenia z STS na określony czas. Rola ma dwie polityki: trust policy (kto może
ją przyjąć — np. lambda.amazonaws.com albo konto 222233334444) i permissions policy (co wolno
po jej przyjęciu).
2.1.52.1.62.1.7
- Kolejność decyzji: explicit Deny > Allow > implicit deny (domyślne). Wyjątek: root konta ma pełny dostęp.
- Ta sama konto: wystarczy Allow w polityce tożsamości albo w polityce zasobu. Cross-account: potrzebny Allow po obu stronach (polityka tożsamości w koncie A i polityka zasobu/trust policy w koncie B).
- Permissions boundary, SCP i session policy tylko ograniczają — nie nadają uprawnień. Efektywne uprawnienia = część wspólna.
- Aplikacja na EC2/Lambda/ECS → rola (instance profile / execution role / task role), nigdy klucze w kodzie.
- Przekazanie roli usłudze (np. tworzenie Lambdy z rolą) wymaga
iam:PassRole. - Dostęp dla zewnętrznej firmy (third party) → rola cross-account z warunkiem
sts:ExternalId(problem „confused deputy”). - Najmniejsze uprawnienia: zacznij od managed policies, zawężaj; IAM Access Analyzer generuje politykę z historii CloudTrail i waliduje polityki; policy simulator testuje polityki bez wykonywania akcji.
- Fine-grained (2.1.7): warunki (
Condition), policy variables (${aws:username},${aws:PrincipalTag/team}), ABAC na tagach,dynamodb:LeadingKeysdla dostępu „tylko do swoich wierszy”.
Typy polityk i jak się składają
| Typ polityki | Co robi | Kiedy |
|---|---|---|
| Identity-based (AWS managed / customer managed / inline) | Dołączona do użytkownika, grupy lub roli; nadaje uprawnienia. Inline = relacja 1:1, usuwana razem z tożsamością. | Codzienne nadawanie uprawnień; customer managed do ponownego użycia i wersjonowania. |
| Resource-based | Dołączona do zasobu (bucket S3, kolejka SQS, temat SNS, klucz KMS, funkcja Lambda, trust policy roli); ma element Principal. Zawsze inline. | Dostęp cross-account bez przyjmowania roli; zezwolenie usłudze AWS (np. S3 → Lambda). |
| Trust policy roli | Specjalna resource-based policy roli: kto może wykonać sts:AssumeRole (lub AssumeRoleWithWebIdentity/AssumeRoleWithSAML). | Każda rola; cross-account; role dla usług (Principal: {"Service": "lambda.amazonaws.com"}). |
| Permissions boundary | Managed policy ustawiająca maksymalne uprawnienia użytkownika/roli. Sama nic nie nadaje. | Delegowanie: deweloperzy tworzą role, ale nie mogą eskalować uprawnień. |
| SCP (AWS Organizations) | Ogranicza maksymalne uprawnienia principali w kontach organizacji. Nie nadaje uprawnień. | Guardrails na poziomie organizacji („nikt nie wyłączy CloudTrail”, „tylko eu-central-1”). |
| Session policy | Przekazana przy AssumeRole*/GetFederationToken; zawęża uprawnienia tej jednej sesji. Nie nadaje uprawnień. | Jedna rola, różne zawężone sesje (np. per najemca). |
| ACL (S3, starsze) | Listy kontroli dostępu cross-account, nie w formacie JSON. | Spuścizna; obecnie zalecane wyłączenie ACL w S3 (S3 security). |
// Trust policy roli dla zewnętrznej firmy (konto 999988887777)
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": { "AWS": "arn:aws:iam::999988887777:root" },
"Action": "sts:AssumeRole",
"Condition": { "StringEquals": { "sts:ExternalId": "a1b2c3-unikalne-dla-klienta" } }
}]
}
Elementy polityki, warunki i zmienne
Polityka to JSON z Version (zawsze "2012-10-17" — tylko ta wersja języka
obsługuje policy variables) i listą Statement: Sid, Effect
(Allow/Deny), Principal (tylko w resource-based), Action/NotAction,
Resource/NotResource, Condition. NotAction dopasowuje
wszystko oprócz wymienionych akcji — z Allow łatwo przyznać za dużo.
| Klucz warunku / zmienna | Co sprawdza | Typowe pytanie |
|---|---|---|
aws:MultiFactorAuthPresent, aws:MultiFactorAuthAge | Czy (i jak dawno) użyto MFA. | „Usuwanie tylko z MFA”. |
aws:SourceIp, aws:SourceVpc, aws:SourceVpce | Publiczny IP wywołującego; VPC / VPC endpoint, przez który przyszło żądanie. | „Bucket dostępny tylko z naszego VPC endpointu”. |
aws:SecureTransport | Czy żądanie szło po TLS. | „Wymuś HTTPS dla bucketu” (Deny gdy false). |
aws:RequestedRegion | Region, do którego idzie wywołanie. | „Zablokuj użycie innych regionów”. |
aws:PrincipalOrgID, aws:PrincipalAccount, aws:PrincipalArn | Organizacja / konto / ARN wywołującego. | „Dostęp dla wszystkich kont naszej organizacji” bez listy kont. |
aws:PrincipalTag/klucz, aws:ResourceTag/klucz, aws:RequestTag/klucz, aws:TagKeys | Tagi principala, zasobu, tagi w żądaniu. | ABAC: „dostęp, gdy tag projektu użytkownika = tag zasobu”. |
aws:SourceArn, aws:SourceAccount | Zasób/konto, w imieniu którego usługa AWS woła. | Confused deputy przy service principal (np. SNS → SQS). |
aws:CalledVia, aws:ViaAWSService | Czy żądanie przyszło przez usługę AWS w Twoim imieniu. | „KMS tylko gdy woła S3”. |
aws:CurrentTime, aws:EpochTime | Czas żądania. | Dostęp tylko w oknie czasowym. |
${aws:username}, ${aws:userid}, ${aws:PrincipalTag/team} | Policy variables — wartość wstawiana w czasie ewaluacji. | „Jedna polityka, każdy użytkownik tylko do swojego prefiksu S3” — arn:aws:s3:::bucket/home/${aws:username}/*. |
Operatory: StringEquals/StringLike (z * i ?),
ArnLike, IpAddress, DateGreaterThan, Bool,
NumericLessThan, Null (czy klucz istnieje). Sufiks …IfExists = „sprawdź,
jeśli klucz jest w żądaniu”. Dla kluczy wielowartościowych: ForAllValues: (każda wartość z żądania musi
pasować) i ForAnyValue: (co najmniej jedna). Jeśli klucza nie ma w kontekście żądania, warunek jest
fałszywy (poza …IfExists i Null) — z wyjątkiem operatorów zaprzeczających (np. StringNotEquals, ArnNotLike), dla których brak klucza daje prawdę. Przykład 2.1.7: w DynamoDB
ForAllValues:StringEquals na dynamodb:LeadingKeys = ${www.amazon.com:user_id}
lub ${cognito-identity.amazonaws.com:sub} daje każdemu użytkownikowi dostęp tylko do jego partycji
(DynamoDB, Cognito).
Role, sesje i dostęp między kontami
| Mechanizm | Co robi | Kiedy |
|---|---|---|
| Rola usługi (service role) | Rola, którą przyjmuje usługa AWS w Twoim imieniu (Lambda execution role, ECS task role, CodeBuild service role). | Każdy kod działający w AWS. |
| Service-linked role | Rola predefiniowana i zarządzana przez usługę, powiązana z nią na stałe. | Np. Auto Scaling, ELB — tworzone automatycznie. |
| Instance profile | Kontener na rolę, który przypinasz do EC2; kod pobiera poświadczenia z IMDS. | Aplikacja na EC2 (rozdz. SDK). |
| Cross-account role | Konto B tworzy rolę z trust policy wskazującą konto A; użytkownik w A potrzebuje sts:AssumeRole na ARN tej roli. | Narzędzia CI/CD w koncie „tools” wdrażają do kont „prod”. |
| Resource-based policy cross-account | Zasób w B (bucket, kolejka, klucz KMS) wymienia principal z A; principal zachowuje swoje uprawnienia (nie oddaje ich, jak przy przyjęciu roli). | Wspólny bucket/kolejka; mniej kroków niż rola. |
| Role chaining | Rola przyjmuje kolejną rolę; sesja ograniczona do maks. 1 godziny. | Pytanie „dlaczego DurationSeconds 2h zwraca błąd”. |
Czas sesji roli: DurationSeconds od 900 s (15 min) do ustawienia maximum session
duration roli (1–12 h); bez parametru — 1 godzina. Tożsamość sesji widzisz jako
arn:aws:sts::111122223333:assumed-role/NazwaRoli/NazwaSesji.
s3:*, a i tak dostaje AccessDenied. Co jeszcze może blokować?kms:Decrypt) w polityce klucza. Do diagnozy: policy simulator, a dla zakodowanej wiadomości błędu — aws sts decode-authorization-message.Narzędzia najmniejszych uprawnień
| Narzędzie | Co robi | Kiedy |
|---|---|---|
| IAM Access Analyzer — external access | Wykrywa zasoby (buckety, role, klucze KMS, kolejki…) udostępnione poza Twoją strefę zaufania (konto/organizację). Działa per region. | „Które zasoby są publiczne lub dostępne z innych kont?” |
| IAM Access Analyzer — unused access | Wskazuje nieużywane role, klucze dostępu, hasła i uprawnienia. | Sprzątanie nadmiarowych uprawnień. |
| Access Analyzer — policy generation | Generuje szablon polityki na podstawie aktywności w logach CloudTrail z wybranego okresu. | „Utwórz politykę najmniejszych uprawnień na podstawie tego, czego aplikacja faktycznie używa”. |
| Access Analyzer — policy validation | Sprawdza politykę pod kątem gramatyki i najlepszych praktyk (błędy, ostrzeżenia, sugestie). | Przed wdrożeniem polityki, w CI. |
IAM policy simulator (SimulatePrincipalPolicy, SimulateCustomPolicy) | Testuje polityki tożsamości, boundaries, SCP i resource-based dla listy akcji/zasobów — bez wykonywania żądań. | „Sprawdź, czy rola może wykonać X, zanim wdrożysz”. |
| Last accessed information | Pokazuje, kiedy usługa/akcja była ostatnio używana przez tożsamość. | Usuwanie nieużywanych uprawnień. |
- „Dodaj Allow, to przebije Deny” — nigdy. Explicit Deny zawsze wygrywa, niezależnie od miejsca.
- „Permissions boundary nadaje uprawnienia” — nie, tylko ogranicza. Boundary
s3:*bez polityki tożsamości = brak dostępu. - Cross-account tylko po jednej stronie — polityka bucketu w B wymienia konto A, ale użytkownik w A nie ma Allow w swojej polityce → odmowa. Potrzebne obie strony.
- Klucze dostępu IAM usera w kodzie/zmiennych środowiskowych na EC2/Lambda — zawsze błędna odpowiedź; poprawnie rola.
- „Dodaj użytkownika do trust policy” zamiast nadać mu
sts:AssumeRole— przy cross-account potrzebne jest jedno i drugie. - Brak
iam:PassRole— deweloper malambda:CreateFunction, a i tak błąd przy wskazaniu roli wykonania. - ExternalId jako „hasło” — to ochrona przed confused deputy dla stron trzecich, nie mechanizm uwierzytelnienia.
- Role chaining z DurationSeconds > 1 h — operacja się nie powiedzie.
- Grupa IAM jako principal w polityce zasobu — grupy nie są principalami; wskaż użytkownika, rolę lub konto.
Aplikacja w koncie A (rola AppRole) ma czytać obiekty z bucketu w koncie B. Bucket policy w B zezwala AppRole na s3:GetObject, a mimo to aplikacja dostaje AccessDenied. Co jeszcze jest potrzebne?
cross-account · polityka zasobu jest · nadal odmowa
Odpowiedź
Allow na s3:GetObject (ARN bucketu w B) w polityce tożsamości AppRole w koncie A. Cross-account wymaga zgody obu kont. Jeśli obiekty są szyfrowane SSE-KMS — także dostęp do klucza KMS.
Dlaczego nie: dodanie roli do ACL bucketu (ACL nie zastąpi polityki tożsamości); permissions boundary (tylko ogranicza); utworzenie użytkownika IAM w koncie B z kluczami (gorsza praktyka).
Firma chce pozwolić deweloperom tworzyć role IAM dla swoich funkcji Lambda, ale tak, by żadna utworzona rola nie mogła mieć więcej uprawnień niż zestaw zatwierdzony przez zespół bezpieczeństwa.
delegowanie tworzenia ról · bez eskalacji · maksymalne uprawnienia
Odpowiedź
Permissions boundary: polityka deweloperów pozwala na iam:CreateRole tylko z warunkiem iam:PermissionsBoundary = zatwierdzona polityka.
Dlaczego nie: SCP (działa na całe konto, nie selektywnie na tworzone role); inline policy na deweloperach (nie ogranicza ról, które utworzą); ręczny przegląd (nie skaluje się).
Firma monitorująca koszty (third party) potrzebuje dostępu tylko do odczytu do kont wielu klientów. Jak zabezpieczyć rolę przed użyciem przez innego klienta tej firmy?
third party · cross-account · confused deputy
Odpowiedź
Rola cross-account z trust policy dla konta firmy i warunkiem sts:ExternalId unikalnym dla klienta.
Dlaczego nie: użytkownik IAM z kluczami dla firmy (długoterminowe klucze); warunek aws:SourceIp (nie rozwiązuje confused deputy); MFA w trust policy (automat nie poda MFA).
Każdy użytkownik IAM ma mieć dostęp tylko do prefiksu home/<jego-nazwa>/ w jednym buckecie. Rozwiązanie z najmniejszym nakładem utrzymania?
jedna polityka · wielu użytkowników · per-user prefix
Odpowiedź
Jedna polityka z policy variable arn:aws:s3:::bucket/home/${aws:username}/*, dołączona do grupy.
Dlaczego nie: osobna polityka na użytkownika (utrzymanie); osobny bucket na użytkownika (limity, koszty); ACL obiektów (spuścizna).
Zespół chce zastąpić szeroką politykę * roli aplikacji polityką zawierającą tylko akcje faktycznie wywoływane w ostatnich 90 dniach. Co użyć?
least privilege · na podstawie aktywności · CloudTrail
Odpowiedź
IAM Access Analyzer policy generation (na podstawie logów CloudTrail).
Dlaczego nie: policy simulator (testuje istniejącą politykę, nie generuje); AWS Config (zgodność konfiguracji); Trusted Advisor (ogólne rekomendacje).
🔬 Głębiej: limity IAM, polityka zasobu a sesje ról, NotPrincipal
- Rozmiar: customer managed policy maks. 6 144 znaki (bez białych znaków); suma polityk inline: użytkownik 2 048, grupa 5 120, rola 10 240 znaków; trust policy domyślnie 2 048 znaków (do 8 192 po podniesieniu kwoty); session policy maks. 2 048 znaków i do 10 managed policy ARN.
- Managed policies na rolę: domyślnie 20 (maks. 25); na użytkownika 10 (maks. 20); na grupę 10. Ról w koncie: 1000 (maks. 10 000). W starszych materiałach limity managed policies na rolę bywają niższe — licz się z tym w starych testach.
- ExternalId: 2–1 224 znaki. Nazwa roli: 64 znaki; nazwa sesji roli: 64 znaki.
- W tym samym koncie polityka zasobu, która przyznaje dostęp ARN sesji roli, nie jest ograniczana przez implicit deny w polityce tożsamości ani boundary; jeśli wskazuje ARN roli, boundary i session policy nadal ograniczają.
GetCallerIdentitynie wymaga żadnych uprawnień — działa nawet przy explicit Deny nasts:GetCallerIdentity.
- Domyślnie odmowa; Allow otwiera; explicit Deny wygrywa zawsze.
- To samo konto: Allow w tożsamości lub zasobie. Cross-account: Allow po obu stronach.
- Boundary, SCP, session policy = sufit, nie podłoga.
- Rola = trust policy (kto przyjmuje) + permissions policy (co może); sesja 15 min – 12 h, domyślnie 1 h, chaining maks. 1 h.
- Third party → ExternalId; przekazanie roli →
iam:PassRole; per-user zasoby → policy variables. - Access Analyzer: zewnętrzny dostęp, nieużywany dostęp, generowanie i walidacja polityk; simulator: testy bez wykonania.
Dostęp programowy: CLI, SDK, STS i poświadczenia
skąd mój kod wie, kim jest?Każde wywołanie API AWS jest podpisane (Signature Version 4) kluczem, który należy do jakiejś tożsamości. Ani CLI, ani SDK nie zgadują — przeszukują po kolei listę miejsc, w których mogą leżeć poświadczenia, i biorą pierwsze znalezione. To credential provider chain. Analogia: szukasz kluczy do domu — najpierw w dłoni, potem w kieszeni, potem w torbie, na końcu na haczyku przy drzwiach. Jeśli w kieszeni leżą stare klucze od poprzedniego mieszkania, nigdy nie dojdziesz do haczyka.
Na egzaminie liczy się kolejność tego łańcucha, różnica między kluczami długoterminowymi (IAM user) i tymczasowymi (STS: rola, sesja), to, jak kod na EC2/Lambda/ECS dostaje rolę bez żadnych kluczy, oraz kilka praktycznych przełączników CLI.
1.1.92.1.32.1.4
- Kolejność w CLI: opcje wiersza poleceń (
--profile,--region) → zmienne środowiskowe → (assume role / web identity / IAM Identity Center z profilu) → plik~/.aws/credentials→ plik~/.aws/config→ poświadczenia kontenera (ECS task role) → instance profile EC2 (IMDS). Pierwsze trafienie wygrywa. - Kod na EC2 → instance profile (rola); Lambda → execution role; ECS → task role. SDK pobiera i odświeża tymczasowe poświadczenia sam.
- STS:
AssumeRole(role, cross-account),AssumeRoleWithWebIdentity(OIDC, np. Cognito/Google),AssumeRoleWithSAML,GetSessionToken(sesja z MFA dla IAM usera),GetCallerIdentity(„kim jestem?”),DecodeAuthorizationMessage(dekoduje zakodowaną przyczynę odmowy). - IMDSv2: najpierw
PUTpo token (nagłówekX-aws-ec2-metadata-token-ttl-seconds, maks. 21 600 s = 6 h), potemGETz nagłówkiemX-aws-ec2-metadata-token. Wymuszenie:HttpTokens=required. - CLI:
--dry-run(EC2: sprawdza uprawnienia —DryRunOperationvsUnauthorizedOperation),--query(JMESPath, filtr po stronie klienta),--filter(s)(po stronie serwera),--output json|yaml|yaml-stream|text|table, paginacja--max-items/--page-size/--starting-token/--no-paginate. - Dostęp deweloperów bez długoterminowych kluczy: IAM Identity Center +
aws configure sso/aws sso login, albo CloudShell w konsoli (wstępnie uwierzytelniony).
Pliki konfiguracyjne, profile i zmienne środowiskowe
# ~/.aws/credentials — sekrety (aws configure)
[default]
aws_access_key_id = AKIA...
aws_secret_access_key = ...
# ~/.aws/config — ustawienia; profile poza default mają prefiks "profile "
[default]
region = eu-central-1
output = json
[profile prod-admin]
role_arn = arn:aws:iam::123456789012:role/Admin
# skąd wziąć poświadczenia do AssumeRole
source_profile = default
# opcjonalnie: wymagaj kodu MFA
mfa_serial = arn:aws:iam::111122223333:mfa/jan
[profile ci-on-ec2]
role_arn = arn:aws:iam::123456789012:role/Deploy
# bazą jest instance profile
credential_source = Ec2InstanceMetadata
| Zmienna | Co robi | Kiedy |
|---|---|---|
AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN | Poświadczenia (token sesji — dla tymczasowych z STS). | CI, szybkie testy. Mają pierwszeństwo przed plikami i rolą instancji! |
AWS_PROFILE | Wybiera nazwany profil (jak --profile). | Wiele kont/ról w jednej powłoce. |
AWS_REGION, AWS_DEFAULT_REGION | Region. AWS_REGION nadpisuje AWS_DEFAULT_REGION i region z profilu; --region nadpisuje oba. | „Komenda trafia do złego regionu”. |
AWS_DEFAULT_OUTPUT | Format wyjścia CLI. | Skrypty (text), czytanie (table). |
AWS_CONFIG_FILE, AWS_SHARED_CREDENTIALS_FILE | Inna lokalizacja plików. | Kontenery, CI. |
AWS_ROLE_ARN, AWS_ROLE_SESSION_NAME | Rola do przyjęcia przez web identity (z tokenem OIDC). | EKS (IRSA), GitHub Actions OIDC. |
AWS_EC2_METADATA_DISABLED | Wyłącza odpytywanie IMDS. | Poza EC2, by nie czekać na timeout IMDS. |
AWS_RETRY_MODE, AWS_MAX_ATTEMPTS | Retry SDK/CLI (rozdz. 1). | Throttling, dłuższe operacje. |
STS: tymczasowe poświadczenia
| API | Co robi | Kiedy / limity |
|---|---|---|
AssumeRole | Zwraca AccessKeyId + SecretAccessKey + SessionToken dla roli. Opcjonalnie SerialNumber + TokenCode (MFA), ExternalId, session policy. | Cross-account, eskalacja do roli admina. 900 s – maks. session duration roli (1–12 h), domyślnie 1 h; chaining maks. 1 h. |
AssumeRoleWithWebIdentity | Wymienia token OIDC (Google, Cognito, GitHub, EKS) na poświadczenia roli; nie wymaga poświadczeń AWS. | Aplikacje mobilne/web (zwykle przez Cognito identity pool), CI z OIDC. Domyślnie 1 h. |
AssumeRoleWithSAML | Wymienia asercję SAML (AD FS, IdP firmy) na poświadczenia roli. | Federacja korporacyjna. |
GetSessionToken | Tymczasowe poświadczenia dla IAM usera, typowo z kodem MFA. | „API wymaga MFA” dla wywołań z CLI. 900 s – 129 600 s (36 h), domyślnie 43 200 s (12 h); dla roota maks. 1 h. |
GetFederationToken | Poświadczenia dla „federated user”, wywoływane przez IAM usera; trzeba przekazać session policy — bez niej sesja nie ma żadnych uprawnień. | Broker tożsamości (rzadkie). 900 s – 36 h, domyślnie 12 h. |
GetCallerIdentity | Zwraca konto, ARN i UserId wywołującego. Nie wymaga uprawnień. | „Którą tożsamością działa mój skrypt?”: aws sts get-caller-identity. |
DecodeAuthorizationMessage | Dekoduje zakodowaną wiadomość z błędu 403 (m.in. czy przyczyną był explicit Deny czy brak Allow, akcja, zasób, wartości warunków). Wymaga sts:DecodeAuthorizationMessage. | „EC2 zwróciło UnauthorizedOperation z Encoded authorization failure message”. |
aws sts assume-role --role-arn arn:aws:iam::123456789012:role/Admin \
--role-session-name jan --serial-number arn:aws:iam::111122223333:mfa/jan --token-code 123456
aws sts decode-authorization-message --encoded-message <zakodowany-tekst> \
--query DecodedMessage --output text
EC2: IMDSv2 i instance profile
Instance Metadata Service odpowiada pod 169.254.169.254; poświadczenia roli leżą pod
/latest/meta-data/iam/security-credentials/<rola>. IMDSv2 jest sesyjny: token z PUT,
ważny od 1 s do 6 h. HttpTokens = optional (v1 i v2) albo required (tylko v2).
HttpPutResponseHopLimit (1–64) ogranicza, ile skoków sieciowych może przejść odpowiedź z tokenem —
w kontenerach na EC2 z hop limit 1 wywołanie może nie dostać odpowiedzi; rozwiązaniem bywa hop limit 2.
Ruch do IMDS nie jest filtrowany przez security groups.
TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" \
-H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \
http://169.254.169.254/latest/meta-data/iam/security-credentials/
SigV4, paginacja, waitery, throttling
| Mechanizm | Co robi | Kiedy |
|---|---|---|
| Signature Version 4 | Podpis HMAC żądania w nagłówku Authorization albo w parametrach query string (presigned URL). Żądanie musi dotrzeć do AWS zwykle w ciągu 5 minut od znacznika czasu. SigV4a — wariant asymetryczny, ważny w wielu regionach. | SDK/CLI podpisują same; ręcznie tylko przy własnym kliencie HTTP (np. do API Gateway z autoryzacją IAM). Błąd „Signature expired” → zegar maszyny. |
| Paginacja | API list zwracają strony (np. S3 ListObjects do 1000 obiektów) z tokenem kolejnej strony (NextToken/Marker/ContinuationToken). SDK ma paginatory (boto3 get_paginator, JS v3 paginate*). | „Skrypt widzi tylko część zasobów” → brak obsługi paginacji. |
CLI --page-size | Mniejsze strony (więcej wywołań), nadal zwraca wszystko. | Timeouty przy listowaniu bardzo wielu zasobów. |
CLI --max-items + --starting-token | Zwraca maks. N elementów i NextToken, od którego wznowisz. | Przetwarzanie w porcjach. |
CLI --no-paginate | Tylko pierwsza strona, bez automatycznego dociągania. | Szybki podgląd. |
| Waitery | Odpytują API aż zasób osiągnie stan (np. aws ec2 wait instance-running — co 15 s, kod 255 po 40 nieudanych próbach; boto3 get_waiter('bucket_exists')). | „Poczekaj, aż tabela/instancja/stos będzie gotowy” bez własnej pętli. |
| Throttling | Kody ThrottlingException, RequestLimitExceeded (EC2), TooManyRequestsException, SlowDown (S3), ProvisionedThroughputExceededException — SDK ponawia z backoff. | Patrz rozdz. 1; trwały problem → kwota/Service Quotas. |
Przełączniki CLI, które pojawiają się w pytaniach
| Opcja | Co robi | Kiedy |
|---|---|---|
--dry-run | (EC2 i część innych) sprawdza uprawnienia bez wykonania: DryRunOperation = masz uprawnienia, UnauthorizedOperation = nie masz. | „Sprawdź, czy rola może uruchomić instancję, bez uruchamiania”. |
--query | Filtr i projekcja JMESPath po stronie klienta, np. --query 'Reservations[].Instances[].InstanceId'. | Wyciągnięcie jednego pola do skryptu. |
--filters/--filter | Filtrowanie po stronie serwera (mniej danych w odpowiedzi). | Duże listy; łącz z --query. |
--output | json (domyślny), yaml, yaml-stream, text (tabulatory — dla grep/awk), table. | Skrypty vs czytanie. |
--profile, --region | Nadpisują wszystko inne. | Inne konto/region na jedną komendę. |
--debug | Pełny log żądań/odpowiedzi, w tym skąd wzięto poświadczenia. | „Której tożsamości używa CLI?” (lub get-caller-identity). |
--generate-cli-skeleton, --cli-input-json/--cli-input-yaml | Szablon parametrów do pliku i wczytanie parametrów z pliku. | Złożone wywołania w skryptach. |
Dostęp deweloperów: IAM Identity Center i CloudShell
IAM Identity Center (dawniej AWS SSO) to zalecany sposób dawania ludziom dostępu do wielu
kont: logowanie przez portal, permission sets mapowane na role w kontach. W CLI: aws configure sso
(zapisuje sso_session, sso_start_url, sso_region w
~/.aws/config), potem aws sso login pobiera tymczasowe poświadczenia — zero kluczy w
plikach. AWS CloudShell to powłoka w przeglądarce, z poświadczeniami zalogowanego użytkownika konsoli,
preinstalowanym CLI, 1 GB trwałego miejsca na region (dane usuwane po 120 dniach bez sesji) i wygasaniem po
20–30 minutach bezczynności.
- „Rola instancji nie działa”, bo na EC2 ustawiono
AWS_ACCESS_KEY_IDw środowisku lub zostawiono~/.aws/credentials— wyższa pozycja łańcucha wygrywa. - Klucze IAM usera w kodzie, w AMI, w zmiennych Lambdy — zawsze zła odpowiedź; poprawnie rola + chain.
--queryzmniejsza transfer — nie; działa po stronie klienta. Mniej danych z serwera daje--filter(s).--page-sizeogranicza wynik — nie; zmienia tylko rozmiar stron. Ograniczenie wyniku to--max-items.- GetSessionToken do przyjęcia roli — to sesja tej samej tożsamości (np. z MFA); rolę przyjmuje
AssumeRole. - DecodeAuthorizationMessage „bez uprawnień” — wymaga
sts:DecodeAuthorizationMessage; za toGetCallerIdentitynie wymaga niczego. - IMDSv1 „bo prostsze” — pytania o bezpieczeństwo (SSRF) wskazują IMDSv2 z
HttpTokens=required.
Aplikacja na EC2 ma przypiętą rolę z dostępem do S3, ale wywołania zwracają AccessDenied jako użytkownik old-dev. Co jest najbardziej prawdopodobną przyczyną?
rola jest · tożsamość inna · kolejność łańcucha
Odpowiedź
Na instancji są poświadczenia wyżej w łańcuchu (zmienne środowiskowe lub plik ~/.aws/credentials z kluczami old-dev), więc SDK nigdy nie sięga do instance profile. Usuń je.
Dlaczego nie: „rola nie ma uprawnień” (wtedy błąd wskazałby rolę); „trzeba zrestartować instancję” (nie zmienia łańcucha).
Deweloper dostaje UnauthorizedOperation z długą zakodowaną wiadomością przy RunInstances. Jak najszybciej poznać, która polityka zablokowała żądanie?
encoded authorization failure message
Odpowiedź
aws sts decode-authorization-message (z uprawnieniem sts:DecodeAuthorizationMessage).
Dlaczego nie: CloudTrail (pokaże zdarzenie, ale nie rozkodowany kontekst decyzji tak bezpośrednio); get-caller-identity (tylko tożsamość).
Polityka wymaga MFA (aws:MultiFactorAuthPresent) dla ec2:StopInstances. Jak użytkownik IAM wykona to z CLI?
MFA · CLI · IAM user
Odpowiedź
aws sts get-session-token --serial-number … --token-code …, a zwrócone tymczasowe poświadczenia (z AWS_SESSION_TOKEN) użyć do wywołania. Alternatywnie profil z role_arn + mfa_serial.
Dlaczego nie: --mfa jako flaga komendy EC2 (nie istnieje); nowy klucz dostępu (nie zawiera kontekstu MFA).
Skrypt ma sprawdzić, czy rola CI może uruchamiać instancje EC2, bez tworzenia żadnych zasobów.
sprawdź uprawnienia · bez skutków
Odpowiedź
aws ec2 run-instances … --dry-run: DryRunOperation oznacza, że uprawnienia są.
Dlaczego nie: policy simulator też zadziała, ale pytanie dotyczy CLI i realnego kontekstu; --no-paginate/--query nie mają związku.
Zespół 20 deweloperów korzysta z 6 kont AWS. Jak dać im dostęp z CLI bez długoterminowych kluczy dostępu?
wiele kont · ludzie · bez access keys
Odpowiedź
IAM Identity Center z permission sets; deweloperzy używają aws configure sso i aws sso login.
Dlaczego nie: użytkownicy IAM w każdym koncie (klucze, rozproszenie); wspólne klucze w menedżerze haseł (brak rozliczalności).
🔬 Głębiej: kody wyjścia CLI, IMDS w kontenerach, SDK w Pythonie
- Kody wyjścia CLI:
0sukces,1błąd części transferów S3,2błąd parsowania komendy,130przerwanie Ctrl+C,252zła składnia/parametr,253błędna konfiguracja lub brak poświadczeń,254usługa zwróciła błąd,255ogólny błąd (np. waiter po limicie prób). - Boto3 przegląda: parametry klienta/sesji → zmienne środowiskowe → assume role / web identity → IAM Identity Center →
~/.aws/credentials→ login konsolowy →~/.aws/config→ (stary plik Boto2) → poświadczenia kontenera → IMDS. - Ustawienie konta/regionu: AMI może wymusić IMDSv2 (
imds-support v2.0); ustawienia na poziomie instancji mają pierwszeństwo przed ustawieniami konta, a te przed AMI.
- Chain: CLI opcje → env → profil (rola/SSO) → credentials → config → kontener → IMDS; pierwsze trafienie wygrywa.
- Kod w AWS = rola (instance profile / execution role / task role); SDK odświeża poświadczenia sam.
- STS: AssumeRole (rola), …WithWebIdentity (OIDC), …WithSAML, GetSessionToken (MFA), GetCallerIdentity (bez uprawnień), DecodeAuthorizationMessage.
- IMDSv2: PUT token (≤ 6 h) → GET z nagłówkiem;
HttpTokens=required. - CLI:
--dry-run,--query(klient),--filters(serwer),--output,--max-items/--starting-token. - Ludzie: IAM Identity Center +
aws sso login; szybka praca: CloudShell.
VPC dla dewelopera: Lambda w prywatnej podsieci
podsieć publiczna ≠ internet dla LambdyVPC to Twoje prywatne osiedle w regionie AWS. Podsieci (subnets) to ulice — każda w
jednej strefie dostępności (AZ). Ulica jest publiczna, jeśli jej tablica tras (route table) prowadzi ruch
0.0.0.0/0 do Internet Gateway (IGW) — bramy osiedla. Ulica jest prywatna, jeśli takiej
trasy nie ma. Mieszkańcy prywatnej ulicy mogą wychodzić „na miasto” tylko przez NAT gateway — portiernię,
która stoi na ulicy publicznej, wypuszcza ruch wychodzący i wpuszcza wyłącznie odpowiedzi, nigdy nowe połączenia
z zewnątrz.
Domyślnie Lambda działa poza Twoim VPC i ma dostęp do internetu. Gdy podłączysz ją do VPC (żeby sięgnąć do RDS, ElastiCache czy prywatnego API), widzi tylko to, co jest w VPC. Do internetu i publicznych endpointów AWS (S3, DynamoDB, SQS…) potrzebuje wtedy NAT gateway albo VPC endpointów.
1.2.1
- Lambda w VPC: konfigurujesz podsieci i security groups; rola wykonania potrzebuje uprawnień do ENI (managed policy
AWSLambdaVPCAccessExecutionRole:ec2:CreateNetworkInterface,ec2:DescribeNetworkInterfaces,ec2:DeleteNetworkInterface…). - Lambda w VPC + dostęp do internetu = prywatne podsieci + NAT gateway w podsieci publicznej (trasa
0.0.0.0/0→ NAT). Podłączenie Lambdy do podsieci publicznej nie daje internetu. - Do S3 i DynamoDB bez NAT → gateway endpoint (darmowy, wpis w tablicy tras). Do innych usług (SQS, SNS, Secrets Manager, KMS, STS, Lambda…) → interface endpoint (PrivateLink, ENI w podsieci, płatny).
- Security group: stateful, tylko reguły allow, poziom ENI/instancji. Network ACL: stateless (odpowiedzi trzeba wpuścić jawnie, porty efemeryczne 1024–65535), allow i deny, poziom podsieci, reguły w kolejności numerów.
- Dostęp Lambdy do RDS: SG bazy wpuszcza port bazy ze SG Lambdy (odwołanie do SG, nie do IP).
- VPC Flow Logs: metadane ruchu (IP, porty, ACCEPT/REJECT) do CloudWatch Logs, S3 lub Firehose — nie treść pakietów.
Jak Lambda „wchodzi” do VPC: Hyperplane ENI
Lambda nie dostaje ENI na każde wywołanie (tak było dawno temu — stąd stara lore o „zimnych
startach w VPC”). Obecnie tworzy Hyperplane ENI dla każdej kombinacji podsieć + security group,
współdzielonej przez funkcje o tej samej konfiguracji; jedna obsługuje do 65 000 połączeń/portów, a przy większym
ruchu Lambda dokłada kolejne. Nowa funkcja jest w stanie Pending, dopóki ENI nie jest gotowa (może to
potrwać kilka minut). Po 14 dniach bezczynności Lambda odzyskuje ENI i funkcja przechodzi w Inactive —
następne wywołanie się nie powiedzie, a funkcja wraca do Pending. Po odłączeniu od VPC usunięcie ENI
trwa do 20 minut. Polityki IAM mogą wymuszać konfigurację VPC kluczami lambda:VpcIds,
lambda:SubnetIds, lambda:SecurityGroupIds.
| Element | Co robi | Kiedy |
|---|---|---|
| Internet Gateway | Połączenie VPC z internetem w obie strony dla zasobów z publicznym IP. | Podsieci publiczne (ALB, NAT gateway, bastion). |
| NAT gateway (public) | Ruch wychodzący z prywatnych podsieci do internetu; brak połączeń przychodzących. Stoi w podsieci publicznej, ma Elastic IP. Klasyczny NAT gateway jest zonalny — awaria jego AZ odcina inne AZ, jeśli z niego korzystają (istnieje też regional NAT gateway, który obejmuje wiele AZ i nie wymaga podsieci publicznej). | Lambda/EC2 w prywatnej podsieci wołają zewnętrzne API. Płatny (godziny + GB). |
| Gateway endpoint | Trasa do S3 lub DynamoDB (prefix list) w wybranych tablicach tras; bez NAT, bez IGW, bez opłat. Tylko w tym samym regionie; niedostępny przez VPN/peering/Direct Connect. | Lambda/EC2 w VPC czytają S3/DynamoDB tanio i prywatnie. |
| Interface endpoint (PrivateLink) | ENI z prywatnym IP w Twojej podsieci; private DNS przekierowuje standardową nazwę usługi. Chroniony security group. Płatny. | SQS, SNS, Secrets Manager, KMS, STS, API Gateway prywatne, S3 z on-premises. |
| Endpoint policy | Resource-based policy na endpoincie — kto/co może przez niego przejść. Nie zastępuje polityk IAM ani bucketu. | „Przez ten endpoint tylko nasz bucket”. W połączeniu z aws:SourceVpce w bucket policy. |
| VPC peering | Prywatne połączenie dwóch VPC (nieprzechodnie). | Lambda w VPC A → baza w VPC B. |
Security group vs Network ACL
| Cecha | Security group | Network ACL |
|---|---|---|
| Poziom | ENI / instancja / Lambda | Podsieć |
| Reguły | Tylko allow | Allow i deny |
| Ewaluacja | Wszystkie reguły naraz | Rosnąco po numerze, pierwsza pasująca wygrywa |
| Odpowiedzi | Automatycznie dozwolone (stateful) | Trzeba jawnie wpuścić (stateless) |
| Domyślnie | Nowa SG: brak reguł wejściowych, wyjście — wszystko dozwolone | Domyślna NACL: wszystko dozwolone; nowa (custom) NACL: wszystko zabronione |
| Źródło | CIDR, prefix list albo inna security group | Tylko CIDR |
| Kiedy | Podstawowy mechanizm kontroli ruchu | Grube blokady, np. zablokowanie konkretnego IP |
- Lambda w prywatnych podsieciach w ≥ 2 AZ, z własną security group
sg-lambda(wyjście: wszystko). - SG bazy: inbound TCP 5432/3306 ze źródła
sg-lambda. - Gateway endpoint S3 dołączony do tablic tras prywatnych podsieci.
- NAT gateway w podsieci publicznej (najlepiej po jednym na AZ) i trasa
0.0.0.0/0 → nat-…w prywatnych tablicach tras. - Sekrety: interface endpoint Secrets Manager albo dostęp przez NAT; uprawnienia do ENI w roli (
AWSLambdaVPCAccessExecutionRole). - Duża liczba połączeń do bazy → RDS Proxy.
VPC Flow Logs
Flow log można włączyć dla VPC, podsieci lub ENI. Rekord to m.in. adresy, porty, protokół, liczba
bajtów/pakietów i action = ACCEPT/REJECT (odrzucenie przez SG lub NACL).
Cel: CloudWatch Logs (dostarczenie zwykle ok. 5 min), S3 (ok. 10 min) lub Data Firehose. Nie zawierają treści
pakietów i nie rejestrują m.in. ruchu do Amazon DNS ani do metadanych 169.254.169.254. Typowe
pytanie: „połączenie z Lambdy do bazy się nie udaje — jak sprawdzić, czy ruch jest odrzucany?” → flow logs, szukaj
REJECT.
- „Umieść Lambdę w podsieci publicznej, żeby miała internet” — Hyperplane ENI nie dostaje publicznego IP; potrzebny NAT w podsieci publicznej i Lambda w prywatnej.
- „Dodaj Internet Gateway” jako jedyna zmiana — sam IGW nie pomoże zasobom w prywatnej podsieci.
- NAT gateway do S3/DynamoDB — działa, ale kosztuje; „najtaniej/najbezpieczniej” = gateway endpoint.
- Gateway endpoint dla SQS/Secrets Manager — gateway endpointy są tylko dla S3 i DynamoDB; reszta przez interface endpoint.
- NACL bez portów efemerycznych — wejście 443 dozwolone, ale odpowiedzi (1024–65535) zablokowane wyjściem → timeouty. SG tego problemu nie ma (stateful).
- Deny w security group — nie istnieje; do jawnego blokowania IP służy NACL (albo WAF przed ALB/API).
- Lambda w VPC wisi do timeoutu przy wywołaniu SDK do usługi AWS — brak NAT/endpointu, a nie brak uprawnień (wtedy byłoby AccessDenied).
Funkcję Lambda podłączono do VPC, by czytała z RDS. Od tej chwili wywołania zewnętrznego API płatności kończą się timeoutem. Co zrobić?
Lambda w VPC · internet · timeout
Odpowiedź
NAT gateway w podsieci publicznej i trasa 0.0.0.0/0 → NAT w tablicy tras prywatnych podsieci Lambdy.
Dlaczego nie: przeniesienie Lambdy do podsieci publicznej (bez publicznego IP); zwiększenie timeoutu (nic nie naprawia); interface endpoint (nie prowadzi do internetu).
Lambda w prywatnej podsieci bez NAT ma zapisywać pliki do S3. Rozwiązanie najtańsze i bez wychodzenia ruchu do internetu?
S3 · bez NAT · najtaniej
Odpowiedź
Gateway VPC endpoint dla S3 dołączony do tablicy tras podsieci Lambdy.
Dlaczego nie: NAT gateway (koszt); interface endpoint S3 (działa, ale płatny — ma sens np. z on-premises); publiczna podsieć (nie działa dla Lambdy).
Lambda w VPC odczytuje sekret z Secrets Manager, a VPC nie ma dostępu do internetu i nie może go mieć (wymóg bezpieczeństwa).
usługa AWS inna niż S3/DynamoDB · bez internetu
Odpowiedź
Interface VPC endpoint (PrivateLink) dla Secrets Manager z włączonym private DNS i SG wpuszczającą 443 z Lambdy.
Dlaczego nie: gateway endpoint (tylko S3/DynamoDB); NAT (zabroniony internet); zmienne środowiskowe z sekretem (słabsze bezpieczeństwo).
Jak pozwolić tylko funkcjom Lambda z SG sg-app łączyć się z bazą Aurora, bez śledzenia ich adresów IP?
zmienne IP · referencja SG
Odpowiedź
Reguła inbound w SG bazy: port bazy, źródło = sg-app.
Dlaczego nie: NACL z CIDR podsieci (zbyt szeroko, bezstanowo); lista IP (Hyperplane ENI się zmieniają).
Zespół podejrzewa, że ruch z aplikacji do bazy jest odrzucany przez reguły sieciowe. Jak to potwierdzić?
czy ruch odrzucany · metadane ruchu
Odpowiedź
Włączyć VPC Flow Logs na ENI/podsieci i szukać rekordów REJECT.
Dlaczego nie: CloudTrail (wywołania API, nie ruch sieciowy); X-Ray (śledzi żądania aplikacji, nie decyzje SG/NACL).
🔬 Głębiej: limity VPC i szczegóły
- Reguł in/out na security group: 60 (każdy kierunek); security groups na ENI: 5 (do 16); reguł na NACL: 20 (do 40).
- Security groups nie filtrują ruchu do Amazon DNS, DHCP, metadanych EC2 i endpointów metadanych zadań ECS.
- Gateway endpoint: trasy dodawane automatycznie, nie da się ich edytować; trasa do konkretnego zakresu IP usługi ma pierwszeństwo przed trasą endpointu; ruch do S3 w innym regionie idzie przez IGW.
- Private NAT gateway — do innych VPC/on-premises (bez internetu); public NAT — do internetu.
- Hyperplane ENI nie da się usunąć, dopóki istnieje funkcja/wersja, która jej używa; jeśli usuniesz rolę wykonania przed ENI, Lambda nie usunie ENI i trzeba to zrobić ręcznie.
- Lambda w VPC widzi tylko VPC; internet = prywatne podsieci + NAT w publicznej.
- S3/DynamoDB = gateway endpoint (darmowy); pozostałe usługi = interface endpoint (PrivateLink).
- SG: stateful, allow, referencje do SG. NACL: stateless, allow+deny, numery, porty efemeryczne.
- Rola Lambdy potrzebuje uprawnień ENI (
AWSLambdaVPCAccessExecutionRole). - Flow Logs: ACCEPT/REJECT, do CloudWatch Logs/S3/Firehose, bez treści pakietów.
ELB, Auto Scaling i Route 53: ruch do zdrowych celów
chory serwer wypada z gry, zdrowy wracaLoad balancer to recepcjonistka w przychodni: przyjmuje pacjentów pod jednym numerem i rozsyła ich do wolnych gabinetów. Co pół minuty puka do każdego gabinetu („zdrów?”) — to health check. Gabinet, który kilka razy z rzędu nie odpowie, przestaje dostawać pacjentów; gdy znów zacznie odpowiadać kilka razy z rzędu, wraca do grafiku. Auto Scaling to kierownik, który dostawia i zabiera gabinety zależnie od kolejki, a Route 53 to książka telefoniczna miasta, która może wskazywać różne przychodnie w zależności od tego, skąd dzwonisz i która przychodnia jest otwarta.
Rodzaje load balancerów: ALB (warstwa 7: HTTP/HTTPS/gRPC, routing po ścieżce, hoście, nagłówkach; cele: instancje, IP, Lambda), NLB (warstwa 4: TCP/UDP/TLS, ogromna przepustowość, statyczne IP / Elastic IP per AZ) i GWLB (warstwa 3: przepuszcza ruch przez wirtualne appliance’y — firewalle, IDS — z enkapsulacją GENEVE na porcie 6081). Classic Load Balancer to poprzednia generacja.
4.2.8
- Health check ALB (domyślnie dla celów instance/IP): co 30 s, timeout 5 s, 2 kolejne porażki → unhealthy, 5 kolejnych sukcesów → healthy, kod sukcesu 200 (konfigurowalny
Matcher, np.200-299). Endpoint health checku = readiness aplikacji (np./healthsprawdzający zależności). - Gdy wszystkie cele w grupie są unhealthy, ALB kieruje ruch do wszystkich („fail open”).
- Adres klienta za ALB: nagłówek
X-Forwarded-For(plusX-Forwarded-Proto,X-Forwarded-Port). NLB z celami po instance ID zachowuje IP klienta. - Sticky sessions (ALB): ciasteczko
AWSALB(duration-based) lub ciasteczko aplikacji (application-based), od 1 s do 7 dni, domyślnie 1 dzień. - Deregistration delay (connection draining): domyślnie 300 s, zakres 0–3600 s.
- Cross-zone: w ALB zawsze włączony na poziomie LB (można wyłączyć na target group); NLB i GWLB — domyślnie wyłączony.
- Wiele certyfikatów TLS na jednym listenerze HTTPS = SNI; certyfikaty z ACM.
- ASG: health check EC2 domyślnie; włącz ELB health checks, by ASG wymieniał instancje, które nie przechodzą health checku aplikacji. Lifecycle hooks (domyślnie 1 h oczekiwania) do akcji przy starcie/terminacji.
- Route 53: alias (zone apex, cele AWS, bez opłat za zapytania) vs CNAME; polityki routingu: simple, weighted, latency, failover, geolocation, geoproximity, IP-based, multivalue.
initial/draining i strefy AZ.ALB vs NLB vs GWLB
| Cecha | ALB | NLB | GWLB |
|---|---|---|---|
| Warstwa OSI | 7 (HTTP/HTTPS, gRPC, WebSocket) | 4 (TCP, UDP, TLS, TCP_UDP) | 3 (pakiety IP, GENEVE 6081) |
| Routing | Reguły: host-header, path-pattern, http-header, http-request-method, query-string, source-ip | Po protokole i porcie (hash przepływu) | Do appliance’ów |
| Akcje | forward (także ważone grupy docelowe), redirect (np. HTTP→HTTPS), fixed-response, authenticate-cognito, authenticate-oidc | forward | forward |
| Cele | Instancje, IP, Lambda (żądanie/odpowiedź maks. 1 MB) | Instancje, IP, ALB | Instancje, IP appliance’ów |
| Adres | Nazwa DNS (IP się zmieniają) | Statyczny IP per AZ, opcjonalnie Elastic IP | — |
| Kiedy | Mikroserwisy HTTP, routing po ścieżce, uwierzytelnianie na LB | Ekstremalna wydajność, niskie opóźnienia, nie-HTTP, stałe IP do allowlist | Inspekcja ruchu przez firewalle firm trzecich |
Uwierzytelnianie na ALB (authenticate-cognito/authenticate-oidc) działa
tylko na listenerze HTTPS — patrz Cognito. Lambda jako cel ALB dostaje zdarzenie
z nagłówkami (opcjonalnie multiValueHeaders) i musi zwrócić obiekt ze statusCode.
Atrybuty target group, które warto znać
| Atrybut | Co robi | Kiedy |
|---|---|---|
HealthCheckPath, Matcher | Ścieżka i kody sukcesu (HTTP 200–499; domyślnie 200). | Health check sprawdzający gotowość aplikacji. |
HealthCheckIntervalSeconds / HealthCheckTimeoutSeconds | 5–300 s (domyślnie 30) / 2–120 s (domyślnie 5; dla celu Lambda: 35 / 30). | Szybsze wykrywanie awarii. |
HealthyThresholdCount / UnhealthyThresholdCount | 2–10 (domyślnie 5) / 2–10 (domyślnie 2). | „Instancja długo wraca do ruchu po naprawie” → zmniejsz healthy threshold. |
deregistration_delay.timeout_seconds | Czas na dokończenie żądań w locie po wyrejestrowaniu (0–3600 s, domyślnie 300). | Długie żądania przerywane przy wdrożeniu/scale-in → zwiększ; szybkie wdrożenia → zmniejsz. |
slow_start.duration_seconds | Nowy cel dostaje stopniowo rosnący ruch (30–900 s, domyślnie 0 = wyłączone). | Aplikacje z rozgrzewką (JIT, cache). |
stickiness.enabled, stickiness.type (lb_cookie/app_cookie) | Ten sam klient → ten sam cel. Duration-based: ciasteczko AWSALB. Application-based: Twoje ciasteczko (+ AWSALBAPP). | Aplikacje stateful (lepiej: uczyń je stateless). |
load_balancing.algorithm.type | round_robin (domyślny), least_outstanding_requests, weighted_random. | Nierówne czasy żądań → least outstanding requests. |
Kody błędów ALB (pytania troubleshootingowe)
| Kod | Typowa przyczyna | Co zrobić |
|---|---|---|
| 502 Bad Gateway | Cel zamknął połączenie (RST/FIN), zwrócił niepoprawną odpowiedź, minął deregistration delay, odpowiedź Lambdy > 1 MB. | Keep-alive celu dłuższy niż idle timeout ALB; poprawny format odpowiedzi. |
| 503 Service Unavailable | Brak zarejestrowanych celów w target group. | Zarejestruj cele / sprawdź ASG. |
| 504 Gateway Timeout | Cel nie odpowiedział przed idle timeout (domyślnie 60 s) albo nie dało się połączyć w 10 s; NACL blokuje porty efemeryczne. | Zwiększ idle timeout / przyspiesz aplikację / popraw reguły sieci. |
| 4xx z celu vs z ALB | Metryki HTTPCode_Target_4XX_Count vs HTTPCode_ELB_4XX_Count rozróżniają źródło. | CloudWatch. |
Auto Scaling
| Polityka / funkcja | Co robi | Kiedy |
|---|---|---|
| Target tracking | Utrzymuje metrykę na celu, np. ASGAverageCPUUtilization = 50%, ALBRequestCountPerTarget, ASGAverageNetworkIn/Out lub własna metryka. | Domyślny wybór; „utrzymuj średnie CPU na 50%”. |
| Step scaling | Alarm CloudWatch + kroki zależne od wielkości przekroczenia. | Różna reakcja na małe i duże skoki. |
| Simple scaling | Jedna zmiana na alarm, potem cooldown (domyślnie 300 s). AWS odradza na rzecz target tracking/step. | Starsze konfiguracje. |
| Scheduled | Zmiana min/max/desired o określonej porze (cron + strefa czasowa). | Znany szczyt: „codziennie o 9:00”. |
| Predictive | Prognozuje obciążenie z historii i skaluje z wyprzedzeniem. | Cykliczne wzorce ruchu. |
| Lifecycle hooks | Wstrzymują instancję w Pending:Wait/Terminating:Wait (domyślnie 1 h, maks. 48 h lub 100× heartbeat); wynik CONTINUE/ABANDON przez complete-lifecycle-action, przedłużenie przez record-lifecycle-action-heartbeat. | Instalacja/konfiguracja przed wejściem do ruchu; zrzut logów przed terminacją. |
| Health check grace period | Czas po starcie, w którym ASG ignoruje wyniki health checków (konsola: domyślnie 300 s; CLI/SDK: 0). | „Instancje są terminowane zanim aplikacja wystartuje”. |
| Warm pool | Pula wstępnie zainicjalizowanych instancji obok ASG. | Długi czas startu aplikacji. |
| Instance refresh | Stopniowa wymiana instancji (np. po zmianie launch template). | Nowy AMI w całej grupie. |
ASG utrzymuje desired capacity między min a max i równoważy instancje między AZ (przy terminacji balans AZ ma pierwszeństwo). Konfiguracja instancji: launch template (wersjonowany). Stara lore: launch configuration — od 1 stycznia 2023 nie obsługuje nowych typów instancji, a konta utworzone od 1 października 2024 nie mogą tworzyć nowych launch configurations żadną metodą; w starszych testach wciąż występuje jako poprawna opcja.
Route 53: rekordy, alias, routing, health checks
| Polityka routingu | Co robi | Kiedy |
|---|---|---|
| Simple | Jeden zasób (może wiele IP, zwracane wszystkie). | Jeden serwer/ALB. |
| Weighted | Proporcje wag (0–255), np. 1 i 255 → 1/256 ruchu. | Canary/blue-green na poziomie DNS, testy A/B. |
| Latency | Region o najniższym opóźnieniu dla użytkownika. | Aplikacja w wielu regionach, „najlepsza wydajność”. |
| Failover | Active-passive: primary, a przy niezdrowym health checku — secondary. | DR, statyczna strona zapasowa w S3. |
| Geolocation | Według lokalizacji użytkownika (kontynent/kraj/stan); rekord default dla nieznanych lokalizacji. | Treści per kraj, zgodność prawna. |
| Geoproximity | Według lokalizacji zasobów, z bias rozszerzającym/zmniejszającym obszar. | Przesuwanie ruchu między regionami. |
| IP-based | Według znanych zakresów CIDR klientów. | Ruch od konkretnych ISP/sieci. |
| Multivalue answer | Do 8 losowych zdrowych rekordów. | Prosty rozkład po stronie klienta z health checkami (nie zastępuje ELB). |
Alias vs CNAME: alias to rozszerzenie Route 53 wskazujące zasoby AWS (ELB, CloudFront,
API Gateway, S3 website, VPC endpoint, inny rekord w strefie); działa na zone apex (example.com),
zapytania do zasobów AWS są bezpłatne, TTL ustala AWS. CNAME nie może być na zone apex i jest płatny. Rekordy:
A (IPv4), AAAA (IPv6), CNAME, MX, TXT,
NS, SOA… TTL to czas cache’owania odpowiedzi przez resolvery — krótki przed
migracją. Private hosted zone odpowiada tylko w powiązanych VPC.
Health checks Route 53: monitorują endpoint (HTTP/HTTPS/TCP; HTTP/HTTPS zdrowy, gdy połączenie TCP nawiąże się w 4 s, a endpoint odpowie kodem 2xx/3xx w ciągu kolejnych 2 s; dla samego TCP wystarczy połączenie w 10 s; opcjonalnie szukany tekst w pierwszych 5 120 bajtach odpowiedzi), inny health check (calculated) albo alarm CloudWatch. Endpoint jest zdrowy, gdy > 18% checkerów raportuje „healthy”. Interwał 30 s albo 10 s (fast, dodatkowo płatny), plus failure threshold. Nie da się sprawdzić prywatnego IP — dla zasobów prywatnych użyj health checku na alarmie CloudWatch.
- Adres klienta z IP połączenia za ALB — widzisz IP węzła ALB; prawdziwy klient jest w
X-Forwarded-For. - ASG nie wymienia instancji, która zwraca 500 — bo domyślny health check ASG to EC2 status checks; włącz typ ELB.
- Instancje terminowane w pętli tuż po starcie — za krótki grace period / health check sprawdza zależności, które jeszcze startują.
- CNAME dla
example.com— niemożliwe na zone apex; alias. - Multivalue zamiast load balancera — to nie jest load balancer; przy pytaniu o rozkład ruchu HTTP i health checki aplikacji → ALB.
- Sticky sessions jako rozwiązanie utraty sesji — maskują problem; poprawnie sesja w ElastiCache/DynamoDB.
- NLB do routingu po ścieżce URL — tylko ALB (warstwa 7).
- Uwierzytelnianie Cognito na listenerze HTTP — wymaga HTTPS.
- Simple scaling + cooldown jako najlepsza praktyka — AWS zaleca target tracking lub step scaling.
Aplikacja za ALB zapisuje w logach adres IP klienta, ale wszystkie wpisy pokazują prywatne adresy z VPC. Jak uzyskać prawdziwy adres?
IP klienta · za ALB
Odpowiedź
Odczytać nagłówek X-Forwarded-For (lub włączyć access logs ALB).
Dlaczego nie: proxy protocol (to NLB, nie ALB); flow logs (pokażą ruch, ale nie zaszyją IP w logi aplikacji); zmiana SG (bez związku).
Podczas wdrożeń użytkownicy dostają błędy, bo długie żądania (do 2 min) są przerywane, gdy stare instancje są wyrejestrowywane.
żądania w locie · wyrejestrowanie
Odpowiedź
Ustawić deregistration delay ≥ czas najdłuższego żądania (domyślnie 300 s — sprawdź, czy ktoś go nie skrócił).
Dlaczego nie: sticky sessions (nie chronią przed wyrejestrowaniem); zwiększenie health check interval (opóźnia wykrycie awarii).
Instancje w ASG za ALB czasem zawieszają aplikację (HTTP 500), choć system operacyjny działa. ASG ich nie wymienia. Jak to naprawić?
aplikacja padła · EC2 zdrowe · auto-naprawa
Odpowiedź
Włączyć health check typu ELB w ASG (z sensownym grace period).
Dlaczego nie: CloudWatch alarm na CPU (nie wykrywa 500); lifecycle hook (działa tylko przy starcie/terminacji).
Jeden ALB obsługuje api.example.com i shop.example.com, każdy z własnym certyfikatem TLS. Jak to skonfigurować?
wiele domen · jeden listener HTTPS
Odpowiedź
Listener HTTPS z dwoma certyfikatami z ACM (SNI) i regułami host-header kierującymi do dwóch target groups.
Dlaczego nie: dwa ALB (koszt, niepotrzebne); NLB (brak routingu po hoście); certyfikat self-signed na instancjach (gorsza praktyka).
Nowa wersja aplikacji ma dostać 10% ruchu w obu regionach na poziomie DNS, z możliwością szybkiego wycofania.
procent ruchu · DNS
Odpowiedź
Route 53 weighted routing (np. wagi 90/10).
Dlaczego nie: latency (wybiera region, nie wersję); failover (active-passive); geolocation (według kraju). Na poziomie ALB to samo da forward do ważonych target groups.
Przed wejściem instancji do ruchu skrypt musi pobrać konfigurację i zarejestrować instancję w zewnętrznym systemie; przed terminacją — wysłać logi do S3.
akcja przy starcie i zamykaniu · ASG
Odpowiedź
Lifecycle hooks launch i terminate, zakończone complete-lifecycle-action.
Dlaczego nie: user data (tylko start, brak wstrzymania przed wejściem do ruchu i brak etapu terminacji); scheduled scaling (czas, nie zdarzenie).
🔬 Głębiej: limity i szczegóły ELB/ASG
- ALB: certyfikatów na LB 25 (bez domyślnego), listenerów 50, target groups 100 na LB, celów 1000 na LB, target groups na akcję 5, funkcji Lambda w target group: 1.
- ALB 504: połączenie do celu musi powstać w 10 s; SSL handshake do celu — 10 s.
- Duration-based stickiness:
AWSALBto jedna nazwa dla wszystkich target groups, więc przy wielu warstwach ALB sticky działa tylko na jednej — application-based działa na wielu; application-based nie działa z ważonymi target groups. X-Forwarded-Forma trybyappend(domyślny),preserve,remove(atrybutrouting.http.xff_header_processing.mode).- Termination lifecycle hooks są „best effort” — przy timeout/abandon instancja i tak zostaje zakończona.
- Route 53: po utworzeniu health checku nie zmienisz interwału ani opcji string matching; health check alarmu CloudWatch musi być w tym samym koncie.
- ALB = L7 (ścieżka/host/nagłówki, Lambda, Cognito/OIDC na HTTPS); NLB = L4, statyczne IP; GWLB = appliance’y (GENEVE 6081).
- Health check ALB: 30 s, 2 porażki out, 5 sukcesów in, 200; wszystkie chore → fail open.
- IP klienta:
X-Forwarded-For; sticky:AWSALB(1 s – 7 dni, domyślnie 1 dzień); draining: 300 s. - ASG: target tracking domyślnie, ELB health checks, grace period, lifecycle hooks (1 h).
- Route 53: alias na apex i do AWS (bez opłat); weighted/latency/failover/geo/multivalue; health check zdrowy przy > 18% checkerów.
Compute: EC2, Beanstalk, Lambda, kontenery
Gdzie właściwie biegnie Twój kod? Od „wynajmuję serwer” (EC2), przez „daję kod, ktoś inny stawia serwery” (Elastic Beanstalk), po „daję funkcję, płacę za milisekundy” (Lambda) i „daję obraz kontenera” (ECS, Fargate, EKS). Lambda to jeden z kluczowych serwisów na DVA-C02, więc dostaje aż trzy rozdziały: model wykonania, konfigurację oraz zdarzenia i błędy.
EC2 i storage: serwer, który wynajmujesz na sekundy
user data, IMDS, EBS vs instance store vs EFSEC2 (Elastic Compute Cloud) to wirtualna maszyna, którą wynajmujesz na godziny albo sekundy. Wybierasz typ instancji (ile vCPU i pamięci), AMI (Amazon Machine Image, czyli obraz dysku z systemem), sieć (podsieć, security group) i dyski. Resztą, czyli systemem, łatkami i aplikacją, zajmujesz się sam. To najbardziej „ręczna” opcja compute w tej części.
Analogia: EC2 to wynajęte mieszkanie. Dostajesz klucze (key pair), umeblowanie wybierasz sam (AMI), a user data to kartka „co zrobić po wprowadzeniu się”, wykonywana przy pierwszym uruchomieniu. Dyski to trzy rodzaje szaf. EBS to szafa, którą zabierasz przy przeprowadzce. Instance store to szafa wbudowana w mieszkanie, która przepada, gdy się wyprowadzisz. EFS to wspólna piwnica dla całego bloku.
3.1.42.1.3
- User data uruchamia się domyślnie tylko przy pierwszym starcie instancji, jako root. Limit to 16 KB przed kodowaniem base64. Logi skryptu znajdziesz w
/var/log/cloud-init-output.log. - Instance metadata (IMDS) odpytujesz pod
http://169.254.169.254/latest/meta-data/. IMDSv2 wymaga tokenu sesji: najpierwPUT /latest/api/token, potem nagłówekX-aws-ec2-metadata-token. Tymczasowe poświadczenia roli instancji leżą podiam/security-credentials/. Więcej w rozdziale o SDK. - Instance store przeżywa reboot, ale dane giną przy stop, hibernate i terminate. EBS przeżywa stop. Root volume jest domyślnie usuwany przy terminate (
DeleteOnTermination), dodatkowe wolumeny nie są. - EBS jest przypięty do jednej AZ. Wolumen i instancja muszą być w tej samej strefie. EFS (NFS) montuje wiele instancji z wielu AZ naraz, ale tylko z Linuksa.
- Domyślne metryki EC2 w CloudWatch nie obejmują pamięci RAM ani zajętości dysku. Do tego potrzebujesz CloudWatch agenta (np.
mem_used_percent, namespaceCWAgent). - Aplikacja potrzebuje więcej CPU lub RAM? Zmień typ instancji: M to ogólne przeznaczenie, C to obliczenia, R to pamięć, I/D to storage, T to burstable z kredytami CPU.
EBS
dysk sieciowy, 1 AZ, przeżywa stop
Instance store
dysk fizycznie w hoście, tymczasowy
EFS
NFS, wiele instancji i AZ
Instancja od środka: AMI, typ, user data, metadata
AMI to szablon dysku startowego i jest zasobem regionalnym. Żeby uruchomić tę samą konfigurację w innym regionie, kopiujesz AMI (CopyImage, „Copy AMI”). Własny AMI z zainstalowaną aplikacją („golden image”) skraca start instancji w Auto Scaling, bo nie trzeba niczego doinstalowywać w user data.
Key pair: AWS przechowuje klucz publiczny (trafia do ~/.ssh/authorized_keys), a klucz prywatny masz tylko Ty. Zgubisz go, to go nie odzyskasz.
# IMDSv2: token (TTL max 21600 s = 6 h), potem zapytanie
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" \
-H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
curl -H "X-aws-ec2-metadata-token: $TOKEN" \
http://169.254.169.254/latest/meta-data/iam/security-credentials/
Szczegóły IMDS i user data
| Opcja | Co robi | Kiedy |
|---|---|---|
HttpTokens=required | wymusza IMDSv2 (IMDSv1 bez tokenu odrzucony) | „MOST secure”, ochrona przed SSRF |
HttpPutResponseHopLimit | liczba skoków sieciowych odpowiedzi na PUT, 1–64, domyślnie 1 | kontenery na EC2 nie dostają tokenu? Zwiększ do 2 |
Endpoint IPv6 [fd00:ec2::254] | IMDS po IPv6, trzeba go włączyć | instancje IPv6-only |
| User data base64, 16 KB | skrypt shell albo dyrektywy cloud-init, uruchamiany jako root | bootstrap: instalacja pakietów, pobranie kodu |
| Zmiana user data | tylko na zatrzymanej instancji z root volume na EBS | poprawka skryptu bez nowej instancji |
| User data przy każdym starcie | wymaga zmiany konfiguracji cloud-init (domyślnie tylko pierwszy boot) | pytanie „skrypt nie wykonał się po restarcie” |
Storage: EBS, instance store, EFS
| Cecha | EBS | Instance store | EFS |
|---|---|---|---|
| Co to jest | dysk blokowy po sieci | dysk fizycznie w hoście | sieciowy system plików NFSv4 |
| Trwałość | przeżywa stop; root domyślnie kasowany przy terminate | przeżywa tylko reboot | niezależny od instancji |
| Zasięg | jedna AZ, zwykle jedna instancja | jedna instancja | wiele instancji, wiele AZ (Regional) albo One Zone |
| Typowe użycie | root volume, bazy na jednej instancji | cache, bufory, dane tymczasowe, najwyższe IOPS | współdzielone pliki, CMS, katalogi domowe, Lambda/ECS |
| System | dowolny | dowolny | Linux (Windows nieobsługiwany) |
| Typ EBS | Co robi | Kiedy |
|---|---|---|
gp3 (SSD) | bazowo 3 000 IOPS i 125 MiB/s w cenie; IOPS i przepustowość dokupujesz niezależnie od rozmiaru (max 80 000 IOPS, 2 000 MiB/s, 64 TiB) | domyślny wybór, boot, większość aplikacji |
gp2 (SSD) | 3 IOPS na GiB (100–16 000), małe wolumeny burstują do 3 000 | starsze środowiska; IOPS rosną tylko z rozmiarem |
io2 Block Express / io1 | provisioned IOPS (do 256 000 / 64 000), Multi-Attach | krytyczne bazy, stała niska latencja |
st1 / sc1 (HDD) | przepustowość sekwencyjna / najtańszy „zimny”; nie mogą być bootem | big data, logi, archiwa |
Stare pytania: do września 2025 gp3 miał limit 16 TiB, 16 000 IOPS i 1 000 MiB/s. W testach próbnych możesz spotkać „potrzebujesz ponad 16 000 IOPS, więc io2”. Dziś gp3 sięga 80 000 IOPS, ale io2 nadal jest odpowiedzią na „najniższa, stała latencja” i „Multi-Attach”.
Szyfrowanie EBS (KMS) obejmuje dane w spoczynku na wolumenie, ruch między wolumenem a instancją, snapshoty i wolumeny odtworzone ze snapshotów. Szyfrowania nie da się zdjąć. Klucza KMS istniejącego wolumenu nie zmienisz. Żeby zaszyfrować niezaszyfrowany wolumen lub zmienić klucz: snapshot, potem kopia snapshotu z szyfrowaniem, potem nowy wolumen. Możesz też włączyć „encryption by default” dla regionu.
Multi-Attach działa tylko dla io1/io2: do 16 instancji Nitro w tej samej AZ. Pytanie o wspólny dysk dla wielu AZ to zawsze EFS.
Monitorowanie i rozmiar instancji
Domyślnie (basic monitoring) EC2 wysyła metryki co 5 minut za darmo (status checks co minutę). Detailed monitoring daje okresy 1-minutowe za dodatkową opłatą. Metryki z hypervisora to m.in. CPUUtilization, ruch sieciowy i operacje dyskowe. Pamięć i wolne miejsce na dysku widzi tylko system operacyjny, więc zbiera je CloudWatch agent (metryki in-guest, logi, StatsD/collectd). Szczegóły w rozdziale o metrykach.
Instancje T (burstable) mają bazową wydajność CPU i zbierają kredyty CPU. W trybie standard po wyczerpaniu kredytów spadają do bazy, w trybie unlimited burstują dalej za dopłatą. Metryka CPUCreditBalance spada do zera, a aplikacja zwalnia? Typowe rozwiązania to unlimited albo zmiana typu (np. M).
Opcje zakupu: On-Demand (płatność za sekundę), Savings Plans i Reserved Instances (zobowiązanie na 1 lub 3 lata), Spot (wolne moce, duża zniżka, ostrzeżenie 2 minuty przed przerwaniem), Dedicated Hosts/Instances, Capacity Reservations (rezerwacja pojemności w AZ).
- „User data uruchomi się przy każdym restarcie”: nie, domyślnie tylko przy pierwszym boocie. Restart nie wykona go ponownie.
- „Instance store na dane, które muszą przetrwać zatrzymanie”: stop i hibernate kasują instance store. Kusi wydajnością, ale nadaje się tylko do danych tymczasowych.
- „EBS współdzielony między AZ”: EBS żyje w jednej AZ. Przeniesienie wymaga snapshotu i nowego wolumenu w innej AZ. Współdzielenie między AZ to EFS.
- „Metryka pamięci jest w CloudWatch od razu”: nie ma jej. Potrzebny jest CloudWatch agent i rola z uprawnieniem do
cloudwatch:PutMetricData. - „Klucze dostępu zapisane w user data lub na dysku”: zawsze wybieraj rolę IAM (instance profile). Poświadczenia przychodzą wtedy z IMDS i same się rotują.
- „EFS dla Windows”: EFS nie obsługuje Windows. Współdzielony system plików dla Windows to inna usługa (Amazon FSx for Windows File Server), której nie ma na liście usług in-scope egzaminu (exam guide DVA-C02).
Aplikacja na EC2 przetwarza pliki tymczasowe i potrzebuje maksymalnej wydajności I/O. Utrata danych po zatrzymaniu instancji jest akceptowalna. Jaki storage?
tymczasowe, najwyższe I/O, utrata akceptowalna
Odpowiedź
Instance store. To dysk fizycznie podpięty do hosta, najszybszy i w cenie instancji.
Dlaczego nie: EBS io2 jest trwały, ale droższy i po sieci. EFS ma wyższą latencję. S3 to obiekty, a nie dysk.
Deweloper dodał do user data skrypt instalujący agenta. Po zatrzymaniu i uruchomieniu instancji agent nie został zainstalowany ponownie (wcześniej go odinstalowano). Dlaczego?
user data, restart, nie wykonał się
Odpowiedź
User data domyślnie działa tylko przy pierwszym uruchomieniu. Żeby skrypt działał przy każdym starcie, trzeba to skonfigurować w cloud-init (albo użyć np. SSM).
Dlaczego nie: „brak uprawnień root” odpada, bo user data działa jako root. „Limit 16 KB” dałby błąd już przy pierwszym starcie.
Zespół bezpieczeństwa wymaga, żeby aplikacje na EC2 nie mogły pobrać poświadczeń roli prostym żądaniem GET do metadanych (ochrona przed SSRF). Co skonfigurować?
SSRF, metadata, token
Odpowiedź
IMDSv2 z HttpTokens=required. Każde zapytanie wymaga wtedy tokenu uzyskanego żądaniem PUT.
Dlaczego nie: wyłączenie IMDS całkowicie odetnie rolę instancji. Security group nie filtruje ruchu do 169.254.169.254.
Pięć instancji w trzech AZ za ALB musi czytać i zapisywać te same pliki przesyłane przez użytkowników, z semantyką systemu plików (Linux). Najmniej pracy operacyjnej?
wiele instancji, wiele AZ, system plików, Linux
Odpowiedź
Amazon EFS zamontowany na wszystkich instancjach.
Dlaczego nie: EBS Multi-Attach działa tylko w jednej AZ i tylko io1/io2. Instance store jest lokalny. Synchronizacja przez S3 i cron to dodatkowa praca.
Zespół chce w CloudWatch alarmować, gdy zużycie pamięci na instancjach przekroczy 80%. Metryki nie ma na liście. Co zrobić?
pamięć, brak metryki
Odpowiedź
Zainstaluj CloudWatch agenta (metryka mem_used_percent) i daj instancji rolę z uprawnieniem do publikowania metryk.
Dlaczego nie: detailed monitoring tylko zwiększa częstotliwość metryk hypervisora, pamięci nie doda.
🔬 Głębiej: drobiazgi EC2, które czasem wypływają
- Kolejność ustawień IMDS przy starcie: parametry podane przy uruchomieniu wygrywają z ustawieniami konta w regionie, a te z ustawieniem AMI (
ImdsSupport=v2.0). Jeśli na koncie włączone jest wymuszanie (HttpTokensEnforced), start zHttpTokens=optionalsię nie powiedzie. - Rozmiar user data po base64 to ceil(n/3)·4, a limit 16 KB dotyczy surowego tekstu.
- Spot z hibernacją dostaje powiadomienie o przerwaniu, ale bez 2-minutowego zapasu.
- gp2 utworzone przed 3 grudnia 2018 i niezmodyfikowane mogą mieć niższy limit przepustowości.
- User data: pierwszy boot, root, 16 KB, log w
cloud-init-output.log. - IMDSv2 = PUT po token, potem nagłówek
X-aws-ec2-metadata-token. Rola instancji zamiast kluczy. - EBS: jedna AZ, przeżywa stop. Instance store: ginie przy stop. EFS: wiele AZ, Linux.
- Pamięć i dysk w CloudWatch tylko przez CloudWatch agenta. Basic monitoring co 5 min, detailed co 1 min.
- AMI jest regionalne, więc kopiujesz je między regionami.
Elastic Beanstalk: Ty dajesz kod, AWS stawia resztę
polityki wdrożeń, .ebextensions, worker + cron.yaml, swap URLElastic Beanstalk to „PaaS” zbudowany z klocków AWS. Wrzucasz paczkę z kodem (source bundle, np. ZIP), wybierasz platformę (Node.js, Python, Java, Docker…), a Beanstalk tworzy za Ciebie EC2, Auto Scaling group, load balancer, security groups, alarmy i logi. Same zasoby nadal należą do Ciebie i widzisz je w konsoli. Beanstalk tylko je orkiestruje (pod spodem przez CloudFormation).
Analogia: Beanstalk to firma przeprowadzkowa z ekipą. Mówisz „to jest mój dobytek (kod), mieszkanie ma mieć 2–6 pokoi (instancje)”, a oni wnoszą meble. Polityka wdrożenia mówi, jak wymieniają meble przy kolejnej dostawie: wszystko naraz (przez chwilę nie ma gdzie usiąść), pokój po pokoju, z dodatkowym pokojem na czas wymiany albo w zupełnie nowym mieszkaniu obok.
Słownik: aplikacja to kontener na wszystko. Wersja aplikacji (application version) to konkretna paczka kodu w S3. Środowisko (environment) to działający zestaw zasobów z jedną wersją. Środowisko ma tier: web server (HTTP za load balancerem) albo worker (czyta zadania z kolejki SQS). Tieru nie da się zmienić po utworzeniu środowiska.
3.4.53.4.113.1.2
- Polityki wdrożeń: All at once (najszybsza, przestój), Rolling (paczkami, bez przestoju, mniejsza pojemność), Rolling with additional batch (pełna pojemność przez cały czas), Immutable (nowe instancje w tymczasowym ASG, najbezpieczniejszy rollback), Traffic splitting (canary: procent ruchu na nową wersję). Do tego blue/green przez Swap environment URLs, czyli zamianę CNAME dwóch środowisk.
- Domyślna polityka (opcja
DeploymentPolicy) toAllAtOnce. Rolling i Rolling with additional batch nie działają w środowisku single-instance. Traffic splitting wymaga Application Load Balancera. - .ebextensions/*.config (YAML lub JSON, w katalogu głównym paczki) konfigurują środowisko i instancje:
option_settings,Resources,packages,files,commands,container_commands(zleader_only)… - Worker environment: demon SQS na każdej instancji wysyła wiadomość jako HTTP POST na localhost. Odpowiedź 200 usuwa wiadomość z kolejki. Zadania okresowe definiujesz w cron.yaml.
- Kolejność ważności konfiguracji: ustawienia zrobione bezpośrednio na środowisku (konsola/CLI/API) > saved configuration >
.ebextensions> wartości domyślne. - Baza RDS utworzona w środowisku żyje i umiera razem z nim. Na produkcji tworzysz RDS osobno (albo odłączasz ją od środowiska, „decouple”) i podajesz adres przez zmienne środowiskowe.
- Limit wersji aplikacji w regionie (domyślnie 1 000) rozwiązuje application version lifecycle policy, która usuwa stare wersje według liczby lub wieku.
EvaluationTime. Liczby są ilustracyjne, a kolejność kroków pochodzi z dokumentacji Elastic Beanstalk.Polityki wdrożeń: dokładne zachowanie
| Polityka | Co robi | Gdy wdrożenie padnie | Przestój / DNS | Kod trafia na |
|---|---|---|---|---|
| All at once | wdraża na wszystkie instancje naraz; najszybsza | przestój, rollback ręcznym redeployem | przestój: tak; DNS bez zmian | istniejące instancje |
| Rolling | paczka po paczce (BatchSize, BatchSizeType Percentage/Fixed); paczka na czas wdrożenia wypada z ruchu | jedna paczka poza ruchem; paczki już wdrożone zostają na v2 (mieszane wersje); ręczny redeploy | bez przestoju, ale mniejsza pojemność | istniejące |
| Rolling with additional batch | najpierw uruchamia dodatkową paczkę, potem robi rolling; pełna pojemność cały czas | minimalny wpływ, jeśli padnie pierwsza paczka; później jak Rolling | bez przestoju, pełna pojemność | nowe i istniejące |
| Immutable | drugi, tymczasowy ASG: najpierw 1 instancja, po health checku reszta; potem przeniesienie do starego ASG i usunięcie starych instancji | minimalny: terminuje nowe instancje | bez przestoju; pojemność chwilowo się podwaja | nowe instancje |
| Traffic splitting | pełny zestaw nowych instancji w tymczasowym ASG; NewVersionPercent (domyślnie 10%) ruchu na v2 przez EvaluationTime (domyślnie 5 min), potem 100% | procent klientów chwilowo dotknięty; ruch wraca na stare instancje, nowe są terminowane | bez przestoju; tylko ALB | nowe instancje |
| Blue/green (nie jest polityką, to procedura) | klonujesz środowisko, wdrażasz v2 na „green”, testujesz, potem Swap environment URLs (eb swap) | minimalny: nie robisz swapu albo swapujesz z powrotem | bez przestoju; zmiana DNS (CNAME) | nowe środowisko |
# .ebextensions/deploy.config
option_settings:
aws:elasticbeanstalk:command:
DeploymentPolicy: Rolling # AllAtOnce | Rolling | RollingWithAdditionalBatch | Immutable | TrafficSplitting
BatchSizeType: Percentage
BatchSize: 25
aws:elasticbeanstalk:trafficsplitting: # tylko dla TrafficSplitting
NewVersionPercent: "15"
EvaluationTime: "10"
Ustawienia wdrożeń z namespace aws:elasticbeanstalk:command: Timeout (domyślnie 600 s; Beanstalk dolicza wewnętrznie 240 s), IgnoreHealthCheck (domyślnie false; true oznacza, że wdrożenie nie jest anulowane przez nieudane health checki), Healthy threshold (próg zdrowia; można go obniżyć np. do Warning). Uwaga: DeploymentPolicy ustawiona przez konsolę oraz BatchSize i BatchSizeType ustawione przez konsolę lub EB CLI przy tworzeniu środowiska nadpisują to, co jest w plikach konfiguracyjnych.
Rolling deployments (nowa wersja aplikacji) to co innego niż rolling updates, czyli zmiany konfiguracji wymagające wymiany instancji (np. typ instancji). Te drugie konfiguruje namespace aws:autoscaling:updatepolicy:rollingupdate, a mogą być też immutable. Immutable update wymaga enhanced health reporting.
Blue/green jest też wymagany przy przejściu na niekompatybilną wersję platformy (np. nowa gałąź). Środowiska nie mogą wtedy współdzielić bazy utworzonej przez Beanstalk, bo ta należy do jednego z nich.
Struktura paczki: .ebextensions, .platform, Procfile
my-app.zip
├── app.py / package.json / ...
├── Procfile # web: gunicorn app:app (proces "web" dostaje ruch z proxy)
├── Buildfile # krótkie komendy budujące
├── cron.yaml # tylko worker: zadania okresowe
├── .ebextensions/
│ ├── 01-packages.config # pliki wykonywane alfabetycznie
│ └── 02-options.config
└── .platform/
├── nginx/conf.d/my.conf # nadpisanie konfiguracji proxy
├── hooks/prebuild/ # skrypty (chmod +x) przy wdrożeniu aplikacji
├── hooks/predeploy/
├── hooks/postdeploy/
└── confighooks/... # te same etapy przy wdrożeniu samej konfiguracji
| Klucz / plik | Co robi | Kiedy |
|---|---|---|
option_settings | ustawia opcje konfiguracji (namespace:option) | polityka wdrożeń, zmienne aws:elasticbeanstalk:application:environment, ASG, ELB |
Resources | dodatkowe zasoby w składni CloudFormation (np. tabela DynamoDB, kolejka SQS) | „utwórz zasób razem ze środowiskiem” |
packages, sources, files, users, groups, services | konfiguracja instancji: pakiety yum, archiwa, pliki, usługi | przygotowanie systemu |
commands | uruchamiane przed rozpakowaniem aplikacji i konfiguracją serwera | zmiany systemowe |
container_commands | uruchamiane po rozpakowaniu do katalogu staging, przed wdrożeniem; alfabetycznie, jako root; leader_only: true = tylko na jednej instancji | migracje bazy raz na wdrożenie |
.platform/hooks/prebuild | po rozpakowaniu, przed konfiguracją aplikacji i serwera (po commands, przed Buildfile) | Amazon Linux 2/2023: zalecane zamiast commands |
.platform/hooks/predeploy | po konfiguracji, przed przeniesieniem do lokalizacji docelowej (po container_commands, przed Procfile) | krok budowania, poprawki konfiguracji |
.platform/hooks/postdeploy | po wdrożeniu aplikacji i proxy | rozgrzanie cache, powiadomienie |
Procfile | długo działające procesy; Beanstalk restartuje je po awarii; proxy (port 80) kieruje ruch do procesu web na port 5000 (zmienna PORT) | własna komenda startowa |
Buildfile | krótkie komendy kończące się, niemonitorowane | kompilacja, przygotowanie |
# .ebextensions/db-migrate.config
container_commands:
01_migrate:
command: "python manage.py migrate"
leader_only: true
option_settings:
aws:elasticbeanstalk:application:environment:
DB_HOST: mydb.abc123.eu-central-1.rds.amazonaws.com
Duplikat klucza (np. dwa razy option_settings) w tym samym pliku spowoduje odrzucenie jednej sekcji. Pliki muszą mieć rozszerzenie .config i poprawny YAML (wcięcia spacjami).
Worker environment i cron.yaml
Analogia: worker to zaplecze restauracji. Kelner (web tier) wrzuca kartkę z zamówieniem do okienka (kolejka SQS), a kucharz (demon sqsd) zdejmuje kartkę i woła kucharza-aplikację: „POST, tu masz zamówienie”. Kiedy aplikacja odpowie 200 OK, kartka trafia do kosza (DeleteMessage). Jeśli nie odpowie, kartka wraca do okienka po czasie widoczności.
Opcja (aws:elasticbeanstalk:sqsd) | Co robi | Domyślnie |
|---|---|---|
WorkerQueueURL | kolejka, z której czyta demon; pusty = autogenerowana kolejka standard | autogenerowana |
HttpPath | ścieżka, na którą idzie POST (port zawsze 80, http://localhost/) | / |
VisibilityTimeout | na ile wiadomość jest zablokowana podczas przetwarzania | 300 s (5 min) |
InactivityTimeout / ConnectTimeout | czekanie na odpowiedź / na połączenie | ConnectTimeout 5 s |
MaxRetries | ile prób przed przeniesieniem do DLQ (1–100) | 10 |
RetentionPeriod | ile wiadomość jest ważna | 345 600 s (4 dni) |
# cron.yaml (w katalogu głównym paczki workera)
version: 1
cron:
- name: "backup-job" # unikalna nazwa
url: "/backup" # ścieżka POST
schedule: "0 */12 * * *" # wyrażenie cron, UTC
Zadanie okresowe wrzuca do kolejki tylko lider wybierany przez zapis do tabeli DynamoDB, więc zadanie nie dubluje się na każdej instancji. Obsłużyć je może dowolna instancja. Przy istniejącej kolejce FIFO zadania okresowe nie są obsługiwane. Demon ustawia nagłówki X-Aws-Sqsd-Msgid, X-Aws-Sqsd-Queue, X-Aws-Sqsd-Receive-Count, X-Aws-Sqsd-Attr-*, a User-Agent to aws-sqsd. Przy autogenerowanej kolejce DLQ jest włączona domyślnie.
Konfiguracja, wersje, baza danych
Kolejność ważności (od najwyższej): ustawienia zastosowane bezpośrednio na środowisku (konsola, EB CLI, AWS CLI, SDK, w tym „recommended values” wstawiane przez konsolę), potem saved configuration, potem pliki .ebextensions (alfabetycznie), na końcu wartości domyślne. Dlatego „zmieniłem MinSize w .ebextensions i nic się nie stało” zwykle oznacza, że ktoś ustawił tę wartość w konsoli.
Saved configuration to zapis konfiguracji środowiska w S3 (YAML). Używasz go do tworzenia kolejnych środowisk z tymi samymi ustawieniami (eb config save zapisuje lokalnie do .elasticbeanstalk/saved_configs/). Plik env.yaml w paczce (environment manifest) może m.in. nadać nazwę środowisku i wskazać stos.
Lifecycle policy wersji: każde wdrożenie z konsoli lub EB CLI tworzy wersję w S3. Po przekroczeniu limitu (1 000 wersji w regionie) nie wdrożysz nowej. Polityka usuwa wersje według liczby (max count) albo wieku (max age), maksymalnie 100 przy jednym uruchomieniu. Nie usuwa wersji używanych przez środowiska. Opcjonalnie kasuje też source bundle z S3 (domyślnie paczka zostaje).
RDS: baza dodana w konsoli Beanstalk jest częścią środowiska. Terminate środowiska = utrata bazy (chyba że zadziała deletion policy: Snapshot, Delete albo Retain). Na produkcji tworzysz RDS niezależnie i przekazujesz endpoint przez właściwości środowiska (option_settings lub konsola), a hasło najlepiej przez Secrets Manager. Beanstalk dla zintegrowanej bazy ustawia zmienne RDS_HOSTNAME, RDS_PORT, RDS_DB_NAME, RDS_USERNAME, RDS_PASSWORD.
EB CLI: eb init (projekt), eb create (środowisko), eb deploy (nowa wersja; --staged wdraża pliki z indeksu git, --label nadaje etykietę), eb swap (zamiana CNAME), eb config save. Docker: wystarczy Dockerfile albo Dockerrun.aws.json v1 (gotowy obraz z rejestru), a dla wielu kontenerów platforma „ECS managed Docker”. Rozmiar instancji (CPU, pamięć) zmieniasz typem instancji: opcja InstanceTypes w namespace aws:ec2:instances (starsza InstanceType w aws:autoscaling:launchconfiguration jest oznaczona jako przestarzała).
- „Rolling = brak wpływu na pojemność”: w trakcie Rolling jedna paczka jest poza ruchem. Pełną pojemność daje dopiero Rolling with additional batch albo Immutable.
- „Immutable zmienia DNS”: nie. Immutable i traffic splitting działają za tym samym load balancerem. DNS (CNAME) zmienia się tylko przy blue/green ze swapem URL.
- „Najszybszy rollback w Rolling”: w Rolling (i All at once) rollback to ręczny redeploy poprzedniej wersji. Najszybszy i najbezpieczniejszy rollback daje Immutable (terminacja nowych instancji) albo swap URL.
- „Baza RDS w środowisku Beanstalk na produkcji”: zniknie razem ze środowiskiem i blokuje blue/green. Zawsze wybieraj RDS poza środowiskiem (albo decouple).
- „commands do migracji bazy”:
commandsdziałają, zanim aplikacja zostanie rozpakowana. Migracja tocontainer_commandszleader_only: true. - „Zmiana w .ebextensions zawsze wygrywa”: ustawienia nałożone bezpośrednio (konsola/API) i saved configuration mają wyższy priorytet.
- „Worker czyta SQS samodzielnie przez SDK”: w workerze robi to demon
sqsd. Aplikacja tylko odbiera POST i zwraca 200.
Aplikacja na Beanstalk musi przy wdrożeniu zachować pełną pojemność. Koszt dodatkowych instancji ma być minimalny, a rollback przy błędzie szybki i bez wpływu na użytkowników. Którą politykę wybrać?
pełna pojemność, szybki rollback, bez wpływu
Odpowiedź
Immutable. Nowe instancje powstają w tymczasowym ASG, a przy błędzie są po prostu terminowane, bez wpływu na stare.
Dlaczego nie: Rolling with additional batch utrzymuje pojemność, ale po pierwszej paczce rollback to ręczny redeploy. Blue/green wymaga zmiany DNS i drugiego środowiska. All at once ma przestój.
Środowisko deweloperskie; liczy się tylko czas wdrożenia, krótki przestój jest OK.
najszybciej, przestój akceptowalny
Odpowiedź
All at once, najszybsza polityka i zarazem domyślna.
Dlaczego nie: wszystkie pozostałe są wolniejsze.
Zespół chce wysłać 10% ruchu produkcyjnego na nową wersję, przez 15 minut obserwować zdrowie i automatycznie wrócić do starej wersji w razie problemów, bez zmiany DNS.
procent ruchu, canary, bez DNS
Odpowiedź
Traffic splitting z NewVersionPercent=10 i EvaluationTime=15 (wymaga ALB).
Dlaczego nie: blue/green zmienia DNS i przełącza 100% ruchu. Weighted routing w Route 53 to ręczna praca z dwoma środowiskami.
Migracja schematu bazy ma się wykonać dokładnie raz na wdrożenie, choć środowisko ma 8 instancji. Jak?
raz na wdrożenie, wiele instancji
Odpowiedź
container_commands z leader_only: true w .ebextensions.
Dlaczego nie: commands działają na każdej instancji przed rozpakowaniem kodu. Hook postdeploy działa na każdej instancji.
Aplikacja musi co noc generować raport w tle, nie obciążając serwerów web. Najmniej pracy operacyjnej w Beanstalk?
zadanie okresowe, w tle, Beanstalk
Odpowiedź
Worker environment z plikiem cron.yaml. Demon sam wrzuci zadanie do SQS i wyśle POST na wskazaną ścieżkę.
Dlaczego nie: cron na instancjach web obciąża je i dubluje zadanie na każdej instancji.
Wdrożenie nowej wersji kończy się błędem „application version limit reached”. Jak zapobiec temu na stałe?
limit wersji, automatycznie
Odpowiedź
Application version lifecycle policy (max count albo max age), opcjonalnie z usuwaniem source bundle z S3.
Dlaczego nie: wniosek o zwiększenie limitu tylko odsuwa problem. Ręczne kasowanie wersji nie jest rozwiązaniem trwałym.
DeploymentPolicy?🔬 Głębiej: Beanstalk Cluster, logi immutable, saved configs
- Beanstalk ma dziś dwa tryby: Standard (aplikacje bezpośrednio na EC2, czyli wszystko powyżej) i Cluster (kontenery na Amazon EKS, rolling przez
max-surge/max-unavailable). Pytania egzaminacyjne dotyczą trybu Standard. - Polityki wymieniające wszystkie instancje (immutable, traffic splitting, managed platform updates z wymianą instancji) kasują nazbierane kredyty CPU instancji T.
- Po nieudanym immutable update logi nowych instancji trafiają do S3 i są trzymane tylko godzinę.
- Saved configurations są dostępne tylko dla środowisk Standard.
- Z limitów regionu: 75 aplikacji, 200 środowisk i 1 000 wersji aplikacji (wszystkie można podnieść).
- All at once: szybko, z przestojem. Rolling: paczkami, mniejsza pojemność. +batch: pełna pojemność. Immutable: nowy ASG, najbezpieczniej. Traffic splitting: canary %. Blue/green: swap URL (DNS).
- Kolejność ważności: bezpośrednie ustawienia > saved config > .ebextensions > domyślne.
container_commands+leader_only= raz na wdrożenie. Hooki w.platform/hooks.- Worker:
sqsdrobi POST na localhost:80, 200 usuwa wiadomość, zadania okresowe wcron.yaml. - RDS poza środowiskiem. Lifecycle policy pilnuje limitu 1 000 wersji.
Lambda: model wykonania, czyli kto, kiedy i jak woła Twoją funkcję
sync / async / poller, cold start, limityAWS Lambda uruchamia Twój kod (funkcję) w odpowiedzi na zdarzenie, bez serwerów do zarządzania. Płacisz za liczbę wywołań i czas trwania (w milisekundach, proporcjonalnie do skonfigurowanej pamięci). Funkcja ma handler, czyli punkt wejścia (np. app.lambda_handler), który dostaje dwa argumenty: event (dane zdarzenia, JSON) i context (informacje o wywołaniu i środowisku).
Analogia: Lambda to food truck na żądanie. Gdy przychodzi zamówienie, a żaden truck nie stoi pod ręką, trzeba go przywieźć, rozpalić grill i rozłożyć składniki. To cold start (faza INIT). Kolejne zamówienia obsługuje już rozgrzany truck (warm start). Rozłożone składniki, czyli wszystko, co zrobiłeś poza handlerem (klienci SDK, połączenia z bazą), zostają na kolejne zamówienia. Gdy zamówień przybywa szybciej, niż truck nadąża, AWS podstawia kolejne trucki: każdy obsługuje jedno zamówienie naraz, a liczba trucków w danej chwili to concurrency.
1.2.21.2.51.2.6
- Trzy sposoby wywołania: synchroniczny (
RequestResponse; wywołujący czeka na wynik: API Gateway, ALB, Cognito, SDK), asynchroniczny (Event; Lambda kolejkuje zdarzenie i od razu zwraca HTTP 202: S3, SNS, EventBridge) oraz event source mapping (Lambda sama odpytuje źródło i wywołuje funkcję z paczkami rekordów: SQS, Kinesis, DynamoDB Streams, MSK/Kafka, MQ, DocumentDB). - Cykl życia środowiska: INIT (rozszerzenia, runtime, kod poza handlerem; limit 10 s) → INVOKE (handler; limit = timeout funkcji) → zamrożenie → ponowne użycie albo SHUTDOWN. Kod poza handlerem wykonuje się raz na środowisko.
- Inicjalizuj klientów SDK i połączenia z bazą poza handlerem, bo są wtedy używane ponownie.
/tmpteż przetrwa między wywołaniami w tym samym środowisku, ale nie wolno na tym polegać jako na trwałym stanie. - Limity: pamięć 128–10 240 MB (CPU proporcjonalnie), timeout 1–900 s (domyślnie 3 s), payload 6 MB sync, 1 MB async, zmienne środowiskowe 4 KB, 5 warstw, paczka ZIP 50 MB spakowana / 250 MB rozpakowana, obraz kontenera 10 GB,
/tmp512 MB–10 240 MB, concurrency 1 000 na region (soft limit). - Execution role (rola wykonawcza, trust
lambda.amazonaws.com) mówi, co funkcja może robić. Resource-based policy funkcji mówi, kto może ją wywołać (S3, SNS, inne konto:lambda:InvokeFunction,aws lambda add-permission). - Wywołanie synchroniczne zwraca 200 nawet gdy funkcja rzuciła wyjątek. Błąd sygnalizuje nagłówek
X-Amz-Function-Error. Throttling to 429TooManyRequestsException.
Typy wywołań i kto ich używa
| Typ | Co robi | Kto tak woła | Kto ponawia |
|---|---|---|---|
Synchroniczny (RequestResponse, domyślny w Invoke) | wywołujący czeka na odpowiedź funkcji | API Gateway, ALB, Lambda Function URL, Cognito (triggery), Lex, Amazon Data Firehose (transformacja), S3 Batch Operations, VPC Lattice, CLI/SDK | klient (Lambda nie ponawia) |
Asynchroniczny (Event) | Lambda wrzuca zdarzenie do wewnętrznej kolejki i zwraca 202 | S3, SNS, EventBridge (reguły i event bus), EventBridge Scheduler, CloudWatch Logs (subskrypcje), CloudFormation (custom resources), CodePipeline, AWS Config, SES, IoT | Lambda: 2 ponowienia przy błędzie funkcji; zob. rozdz. 10 |
| Event source mapping (poller) | Lambda sama odpytuje kolejkę lub strumień i wywołuje funkcję synchronicznie z paczką rekordów | SQS, Kinesis Data Streams, DynamoDB Streams, Amazon MSK, self-managed Kafka, Amazon MQ, DocumentDB | poller (SQS: kolejka po visibility timeout; strumienie: do skutku lub wygaśnięcia) |
| Step Functions | synchronicznie albo asynchronicznie, zależnie od integracji | orkiestracja (rozdz. 23) | definicja Retry w maszynie stanów |
# synchronicznie (CLI v2 wymaga --cli-binary-format dla surowego JSON)
aws lambda invoke --function-name my-fn \
--cli-binary-format raw-in-base64-out \
--payload '{"key":"value"}' response.json
# { "StatusCode": 200, "ExecutedVersion": "$LATEST" }
# asynchronicznie
aws lambda invoke --function-name my-fn --invocation-type Event \
--cli-binary-format raw-in-base64-out --payload '{"key":"value"}' response.json
# { "StatusCode": 202 }
InvocationType przyjmuje RequestResponse, Event albo DryRun. DryRun tylko sprawdza parametry i uprawnienia, bez uruchamiania funkcji. --log-type Tail (tylko sync) zwraca w odpowiedzi ostatnie 4 KB logu zakodowane base64. Przy wywołaniu przez alias odpowiedź zawiera ExecutedVersion, czyli wersję, która faktycznie obsłużyła żądanie.
Cykl życia środowiska wykonawczego
| Faza | Co się dzieje | Limit / uwagi |
|---|---|---|
| INIT | start rozszerzeń (Extension init), start runtime (Runtime init), kod statyczny funkcji poza handlerem (Function init) | 10 s; jeśli nie zdąży, Lambda ponawia INIT przy pierwszym wywołaniu z limitem = timeout funkcji. Przy provisioned concurrency / SnapStart init może trwać dłużej (130 s albo timeout, co większe) |
| RESTORE (tylko SnapStart) | wznowienie środowiska ze snapshotu zamiast INIT | after-restore hooki; błąd = log RESTORE_REPORT |
| INVOKE | handler dostaje event; rozszerzenia dostają zdarzenie Invoke | timeout funkcji obejmuje funkcję i rozszerzenia łącznie |
| Zamrożenie | po odpowiedzi środowisko jest zamrażane i czeka na kolejne wywołanie | procesy w tle wznowią się przy następnym wywołaniu, więc kończ je przed wyjściem z handlera |
| SHUTDOWN | po okresie bezczynności (albo co kilka godzin dla aktualizacji) runtime jest zamykany, rozszerzenia dostają Shutdown | 0 ms bez rozszerzeń, 500 ms z wewnętrznym, 2 000 ms z zewnętrznym; potem SIGKILL |
Jeśli funkcja padnie lub przekroczy timeout w trakcie INVOKE, Lambda resetuje środowisko (zachowuje się to jak Shutdown), a kolejne wywołanie robi ponowny INIT („suppressed init”, doliczany do czasu wywołania). Reset nie czyści /tmp.
Rozliczanie INIT: od 1 sierpnia 2025 faza INIT jest rozliczana dla wszystkich konfiguracji, także dla funkcji ZIP na zarządzanych runtime'ach, gdzie wcześniej była darmowa. W starszych materiałach przeczytasz, że „cold start w ZIP jest za darmo”. Dziś to już nieaktualne.
import os, boto3
s3 = boto3.client("s3") # INIT: raz na środowisko, potem reuse
TABLE = os.environ["TABLE_NAME"] # konfiguracja ze zmiennych środowiskowych
def lambda_handler(event, context): # INVOKE: przy każdym wywołaniu
left = context.get_remaining_time_in_millis()
print(context.aws_request_id, context.function_name, left)
return {"statusCode": 200, "body": "ok"}
Pole context (Python / Node.js) | Co zawiera | Kiedy przydatne |
|---|---|---|
get_remaining_time_in_millis() / getRemainingTimeInMillis() | ile ms zostało do timeoutu | przerwij pracę i zapisz postęp przed timeoutem |
aws_request_id / awsRequestId | ID wywołania (jest też w logach START/END/REPORT) | korelacja logów, klucz idempotencji |
invoked_function_arn | ARN użyty do wywołania (z wersją lub aliasem) | logika zależna od aliasu (np. prod) |
function_name, function_version, memory_limit_in_mb | nazwa, wersja, pamięć | diagnostyka |
log_group_name, log_stream_name | gdzie są logi tego środowiska | linki w alertach |
identity, client_context | tożsamość Cognito, kontekst klienta (aplikacje mobilne) | rzadko |
callbackWaitsForEmptyEventLoop (Node.js) | domyślnie true: przy handlerze z callbackiem czeka na pustą pętlę zdarzeń | „funkcja Node.js wisi do timeoutu” (otwarte połączenie) |
Limity, które musisz znać na pamięć
| Zasób | Limit | Kiedy ma znaczenie |
|---|---|---|
| Pamięć | 128–10 240 MB (co 1 MB), domyślnie 128 MB; 1 769 MB = 1 vCPU | więcej pamięci = więcej CPU = krótszy czas |
| Timeout | 1–900 s (15 min), domyślnie 3 s | dłuższe zadania: Step Functions, ECS/Fargate |
| Payload sync (żądanie i odpowiedź) | 6 MB każde | większe dane: S3 + przekazanie klucza |
| Payload streamowanej odpowiedzi | 200 MB (pierwsze 6 MB bez limitu przepustowości, potem 2 MBps) | duże odpowiedzi HTTP |
| Payload async | 1 MB (do października 2025: 256 KB) | S3/SNS/EventBridge → Lambda |
| Zmienne środowiskowe | 4 KB łącznie | większa konfiguracja: Parameter Store / AppConfig |
| Warstwy (layers) | 5 na funkcję | tylko funkcje ZIP |
| Paczka ZIP | 50 MB spakowana (upload bezpośredni; więcej przez S3), 250 MB rozpakowana razem z warstwami | za duże zależności: obraz kontenera |
| Obraz kontenera | 10 GB (rozpakowany, z warstwami) | ML, duże biblioteki |
/tmp (ephemeral storage) | 512–10 240 MB, domyślnie 512 MB | pliki tymczasowe, cache między wywołaniami |
| Concurrency na konto i region | 1 000 (soft, do dziesiątek tysięcy; nowe konta mogą mieć mniej) | throttling 429 |
| Tempo skalowania | 1 000 nowych środowisk co 10 s na funkcję | nagłe skoki ruchu |
| Storage kodu (ZIP + warstwy) w regionie | 300 GB (wcześniej 75 GB) | dużo wersji: usuwaj stare |
| Resource-based policy | 20 KB | wiele add-permission |
| Deskryptory plików / procesy i wątki | 1 024 / 1 024 | wycieki połączeń |
Stare limity w testach próbnych: async payload 256 KB (od października 2025 jest 1 MB), streaming 20 MB (od lipca 2025 jest 200 MB), storage kodu 75 GB (dziś 300 GB). Jeśli pytanie zakłada stary limit („plik 500 KB przez SNS do Lambdy”), wybierz rozwiązanie z S3 i przekazaniem klucza, bo nadal jest poprawne. Uwaga: sama wiadomość SNS wciąż ma limit 256 KB.
Uprawnienia: kto co może
| Polityka | Co robi | Kiedy |
|---|---|---|
| Execution role | rola IAM przyjmowana przez Lambdę; trust policy z lambda.amazonaws.com; uprawnienia funkcji do innych serwisów | funkcja czyta DynamoDB, pisze logi, czyta SQS/Kinesis przez ESM |
| Resource-based policy funkcji | kto może wywołać funkcję albo nią zarządzać; AddPermission lub PutResourcePolicy | S3/SNS/EventBridge/API Gateway wywołują funkcję; inne konto |
Managed: AWSLambdaBasicExecutionRole | zapis do CloudWatch Logs | minimum dla każdej funkcji |
AWSLambdaSQSQueueExecutionRole, AWSLambdaKinesisExecutionRole, AWSLambdaDynamoDBExecutionRole, AWSLambdaMSKExecutionRole | odczyt źródła przez event source mapping | poller działa z uprawnieniami funkcji |
AWSLambdaVPCAccessExecutionRole | tworzenie i usuwanie ENI w VPC | funkcja w VPC (rozdz. 4) |
# pozwól S3 (tylko z tego bucketu i konta) wywołać funkcję
aws lambda add-permission --function-name my-fn \
--statement-id s3-invoke --action lambda:InvokeFunction \
--principal s3.amazonaws.com \
--source-arn arn:aws:s3:::my-bucket --source-account 111122223333
Zasada: przy push (S3, SNS, API Gateway wywołują funkcję) potrzebna jest resource-based policy funkcji. Przy pull (event source mapping czyta SQS lub Kinesis) potrzebna jest execution role z prawem odczytu źródła. Nie wywołuj ręcznie sts:AssumeRole na roli wykonawczej. Lambda przyjmuje ją sama, a klucze tymczasowe trafiają do zarezerwowanych zmiennych środowiskowych (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN), skąd SDK je odczytuje.
Błędy wywołania: co widzi klient
| Sytuacja | Odpowiedź | Co zrobić |
|---|---|---|
| Kod rzucił wyjątek / timeout | HTTP 200 + nagłówek X-Amz-Function-Error, w ciele obiekt błędu (np. errorMessage); w rekordach async: "functionError": "Unhandled" | obsłuż w kodzie, sprawdź logi |
| Brak wolnej concurrency / za dużo żądań | 429 TooManyRequestsException (z retryAfterSeconds) | retry z backoffem, reserved concurrency, podniesienie limitu |
| Payload za duży | 413 RequestTooLargeException | S3 + klucz |
| Brak funkcji / wersji / aliasu | 404 ResourceNotFoundException | sprawdź ARN i kwalifikator |
| Problem z ENI/VPC, KMS, EFS | 502 (ENILimitReachedException, SubnetIPAddressLimitReachedException, KMSAccessDeniedException…), EFS 403/408/410 | konfiguracja VPC, uprawnienia do klucza |
| Błąd usługi Lambda | 500 ServiceException | retry |
- „Lambda sama ponowi wywołanie synchroniczne”: nie. Przy wywołaniu sync o ponowieniu decyduje wywołujący (Twój kod, SDK albo usługa AWS). Lambda ponawia tylko async i event source mappings.
- „Połączenie z bazą otwieraj w handlerze”: każde wywołanie otwiera nowe połączenie, co dokłada latencji i wyczerpuje limit połączeń bazy. Otwieraj je poza handlerem (i/lub użyj RDS Proxy, zob. rozdz. 17).
- „Przechowam sesję użytkownika w zmiennej globalnej lub /tmp”: środowisk jest wiele i mogą zniknąć w każdej chwili. Stan trzymaj w DynamoDB, ElastiCache albo S3.
- „StatusCode 200 = sukces”: przy błędzie funkcji też dostaniesz 200. Sprawdzaj
FunctionError. - „Dam funkcji uprawnienia, żeby S3 mogło ją wywołać”: S3 potrzebuje resource-based policy funkcji (
lambda:InvokeFunctiondlas3.amazonaws.com), a nie uprawnień w roli wykonawczej. - „Timeout 15 min to za mało? Zwiększę limit”: 900 s to twarda granica (poza Lambda Managed Instances). Dłuższe procesy dziel na kroki Step Functions albo uruchamiaj w ECS/Fargate.
Funkcja przy każdym wywołaniu tworzy klienta DynamoDB i łączy się z bazą MySQL. Latencja jest wysoka, a baza zgłasza „too many connections”. Najmniej zmian w kodzie?
reuse, połączenia, latencja
Odpowiedź
Przenieś tworzenie klienta i połączenia poza handler (kod inicjalizacji). Opcjonalnie dodaj RDS Proxy do puli połączeń.
Dlaczego nie: więcej pamięci nie zmniejszy liczby połączeń. Provisioned concurrency usuwa cold starty, ale połączenia w handlerze nadal powstają przy każdym wywołaniu.
Bucket S3 ma wywoływać funkcję przy każdym nowym obiekcie. S3 nie może wywołać funkcji, mimo że rola wykonawcza ma szerokie uprawnienia. Czego brakuje?
S3 → Lambda, uprawnienie do wywołania
Odpowiedź
Resource-based policy funkcji pozwalającą s3.amazonaws.com na lambda:InvokeFunction (z SourceArn bucketu).
Dlaczego nie: uprawnienia w execution role dotyczą tego, co funkcja może robić, a nie tego, kto ją wywołuje. Bucket policy kontroluje dostęp do obiektów, nie do Lambdy.
Funkcja wywoływana przez API Gateway czasem wykonuje się dłużej niż 3 sekundy i kończy błędem „Task timed out after 3.00 seconds”. Najprostsza poprawka?
3 s, timed out, domyślny timeout
Odpowiedź
Zwiększ timeout funkcji (domyślnie 3 s), pamiętając, że integracja API Gateway ma własny limit czasu (rozdz. 25).
Dlaczego nie: zwiększenie pamięci może pomóc tylko przy obciążeniu CPU. Provisioned concurrency nie zmienia czasu działania kodu.
Aplikacja wysyła do funkcji (async, przez SDK) dokumenty JSON po 3 MB. Wywołania kończą się błędem. Rozwiązanie z najmniejszym nakładem?
3 MB, async, payload
Odpowiedź
Zapisz dokument w S3 i przekaż w zdarzeniu tylko bucket i klucz (limit async to 1 MB, a w starszych pytaniach 256 KB).
Dlaczego nie: zmiana na wywołanie sync dałaby 6 MB, ale zmienia semantykę (klient czeka). Kompresja nie daje gwarancji. Zwiększenie limitu przez Service Quotas nie jest możliwe.
Funkcja w Node.js zawsze kończy się timeoutem, choć logika zwraca wynik po 50 ms. Używa handlera z callbackiem i otwartego połączenia z bazą. Co jest przyczyną?
Node.js, callback, timeout mimo wyniku
Odpowiedź
context.callbackWaitsForEmptyEventLoop = true (domyślnie): Lambda czeka na opróżnienie pętli zdarzeń, a otwarte połączenie ją podtrzymuje. Ustaw false albo użyj handlera async.
Dlaczego nie: za mała pamięć albo cold start nie dają stałego timeoutu.
🔬 Głębiej: suppressed init, INIT_REPORT, nowe tryby Lambdy
- Przy provisioned concurrency i SnapStart w logach zawsze pojawia się
INIT_REPORT. Przy zwykłych funkcjach tylko przy błędzie lub timeoucie inicjalizacji. - Lambda może czasem zainicjalizować środowisko z wyprzedzeniem (luka między INIT a INVOKE). Nie polegaj na tym.
- Linia
REPORTw nowym formacie logów ma poleStatus(np.timeout,error) iError Type(np.Runtime.ExitError). - Lambda Managed Instances (funkcje na instancjach EC2 zarządzanych przez Lambdę, z równoległymi wywołaniami w jednym środowisku) i durable functions (wykonania z checkpointami, nawet do roku) to nowe tryby. Mają inne limity (np. 90 min timeout dla async/ESM w Managed Instances). Egzamin DVA-C02 opiera się na klasycznym modelu opisanym wyżej.
- Synchroniczny limit żądań to 10 × concurrency na sekundę (każde środowisko obsługuje do 10 żądań/s). Asynchroniczny ogranicza tylko concurrency.
- Sync (czeka, ponawia klient), async (202, ponawia Lambda), ESM (poller czyta kolejkę lub strumień).
- INIT raz na środowisko (10 s), INVOKE w limicie timeoutu, środowiska są ponownie używane, ale nietrwałe.
- Klientów i połączenia twórz poza handlerem. Stan trzymaj na zewnątrz.
- 128 MB–10 GB pamięci, 15 min, 6 MB sync, 1 MB async, 4 KB env, 5 warstw, 50/250 MB ZIP, 10 GB obraz, 1 000 concurrency.
- Rola wykonawcza = co funkcja może. Resource-based policy = kto może wywołać funkcję.
Lambda: konfiguracja, wersje i concurrency
pamięć, warstwy, aliasy, reserved vs provisioned, SnapStart, URLW Lambdzie ustawiasz kilka parametrów i one decydują o wszystkim. Pamięć to jedyne pokrętło mocy (CPU rośnie razem z nią). Timeout to bezpiecznik. Zmienne środowiskowe to konfiguracja. Warstwy i rozszerzenia to dodatki. Wersje i aliasy to bezpieczne wdrażanie. Concurrency to ile kopii funkcji może działać naraz.
Analogia do concurrency: konto ma parking na 1 000 miejsc wspólny dla wszystkich funkcji. Reserved concurrency to miejsca z tabliczką „tylko dla funkcji X”: nikt inny ich nie zajmie, ale X też nie zaparkuje więcej. Provisioned concurrency to samochody, które już stoją na tych miejscach z włączonym silnikiem (środowiska po INIT), więc ruszają natychmiast, bez cold startu. Płacisz za nie, nawet gdy stoją.
1.2.21.2.64.3.14.3.33.1.1
- Funkcja wolna obliczeniowo? Zwiększ pamięć, bo CPU skaluje się proporcjonalnie (1 769 MB = 1 vCPU). Do dobrania optimum służą AWS Lambda Power Tuning (Step Functions) i AWS Compute Optimizer.
- Reserved concurrency: gwarantuje i jednocześnie ogranicza (max = min). Jest darmowa.
0wyłącza funkcję (throttle). Provisioned concurrency: wstępnie zainicjalizowane środowiska bez cold startu, płatna, tylko na wersji lub aliasie (nigdy na$LATEST), automatyczne skalowanie przez Application Auto Scaling. - Wersja jest niezmienna (kod + większość konfiguracji).
$LATESTjest edytowalna. Alias to wskaźnik na wersję. Weighted alias dzieli ruch między dwie opublikowane wersje (canary), np.AdditionalVersionWeights={"2"=0.1}. - Zmienne środowiskowe (4 KB) są zawsze szyfrowane w spoczynku przez KMS (domyślnie klucz zarządzany przez AWS). Sekrety: customer managed key + helpers „encryption in transit” (funkcja potrzebuje
kms:Decrypt) albo, lepiej, Secrets Manager / Parameter Store. - Warstwy: do 5, rozpakowane do
/opt, wspólne zależności, tylko dla funkcji ZIP. Obraz kontenera (do 10 GB, z ECR) zamiast ZIP, gdy zależności są duże. - SnapStart (Java 11+, Python 3.12+, .NET 8+) skraca cold start przez snapshot środowiska po INIT. Działa tylko na opublikowanych wersjach. Nie łączy się z provisioned concurrency ani EFS.
- Function URL to dedykowany endpoint HTTPS funkcji. Auth type
AWS_IAM(SigV4) alboNONE(publiczny, nadal przez resource-based policy). Działa na aliasie albo$LATEST. - Funkcja w VPC nie ma dostępu do internetu, nawet w publicznej podsieci. Potrzebny jest NAT gateway albo VPC endpoint (rozdz. 4). EFS wymaga VPC.
Pamięć, CPU, timeout, /tmp
Pamięć ustawiasz od 128 MB do 10 240 MB co 1 MB. CPU rośnie proporcjonalnie, a przy 1 769 MB funkcja ma równowartość jednego vCPU. Ponieważ płacisz za GB-sekundy, więcej pamięci często obniża koszt: funkcja kończy się szybciej. Optimum znajdziesz narzędziem Lambda Power Tuning (uruchamia funkcję z różnymi ustawieniami przez Step Functions) albo dzięki rekomendacjom Compute Optimizer (tylko x86_64). Metryka Max Memory Used w linii REPORT pokazuje, ile pamięci naprawdę zużyto.
Timeout: 1–900 s, domyślnie 3 s. Ephemeral storage /tmp: 512–10 240 MB, tymczasowy i unikalny dla każdego środowiska. Do współdzielenia plików między wywołaniami i funkcjami służy EFS.
Zmienne środowiskowe i szyfrowanie
Zmienne definiujesz na $LATEST. Przy publikacji wersji zostają w niej zamrożone. Klucze zaczynają się od litery i mają co najmniej 2 znaki. Łączny rozmiar to 4 KB. Lambda ustawia też zmienne zarezerwowane, których nie nadpiszesz, np. AWS_REGION, _HANDLER, AWS_LAMBDA_FUNCTION_NAME, AWS_LAMBDA_FUNCTION_MEMORY_SIZE, AWS_LAMBDA_INITIALIZATION_TYPE (on-demand, provisioned-concurrency, snap-start…) oraz poświadczenia roli AWS_ACCESS_KEY_ID/AWS_SESSION_TOKEN.
| Opcja | Co robi | Kiedy |
|---|---|---|
| Domyślnie (klucz KMS zarządzany przez AWS) | szyfrowanie w spoczynku, bez żadnych uprawnień KMS | zwykła konfiguracja |
| Customer managed key (at rest) | Twój klucz KMS (kontrola rotacji, audyt); Lambda tworzy grant; zarządzający potrzebują kms:Decrypt, by widzieć wartości | wymóg organizacji „własny klucz” |
| Encryption helpers (in transit) | konsola szyfruje wartość po stronie klienta Twoim kluczem; w konsoli widać szyfrogram; kod musi wywołać kms:Decrypt | „sekret nie może być widoczny w konsoli” |
| Secrets Manager / Parameter Store (SecureString) | sekret poza funkcją, rotacja, odczyt przez SDK lub rozszerzenie | hasła do baz, klucze API (rozdz. 30) |
Warstwy, rozszerzenia, obrazy kontenerów
Layer to archiwum ZIP z bibliotekami, runtime'em lub danymi, rozpakowywane do /opt. Runtime'y mają już w ścieżkach odpowiednie katalogi: python/ (lub python/lib/python3.x/site-packages), nodejs/node_modules. Funkcja może mieć do 5 warstw, a łączny rozmiar po rozpakowaniu (funkcja + warstwy) to 250 MB. Wersje warstwy są niezmienne. Kolejność dodania warstw to kolejność, w jakiej Lambda scala ich zawartość (można ją zmienić: „Merge earlier/later”). Warstwy działają tylko z funkcjami ZIP. Udostępnienie innemu kontu: AddLayerVersionPermission (konsument potrzebuje lambda:GetLayerVersion).
Extensions to procesy działające obok funkcji w tym samym środowisku (np. agenci monitoringu, cache sekretów). Zewnętrzne są osobnymi procesami z /opt/extensions/, zwykle dostarczanymi jako warstwa, i mogą działać po zwróceniu odpowiedzi. Wewnętrzne działają w procesie runtime (wrapper scripts, JAVA_TOOL_OPTIONS). Współdzielą CPU, pamięć i timeout z funkcją. Ile dokładają, pokaże metryka PostRuntimeExtensionsDuration.
Obraz kontenera: budujesz obraz (do 10 GB) i wypychasz go do Amazon ECR. Obraz musi implementować Lambda Runtime API: AWS base images mają wbudowany runtime interface client (RIC), a do lokalnych testów runtime interface emulator (RIE). Obraz celuje w jedną architekturę (x86_64 albo arm64) i działa na systemie plików tylko do odczytu (poza /tmp). Warstw nie dodasz, wszystko pakujesz w obraz. Rola funkcji (lub polityka repozytorium) potrzebuje ecr:BatchGetImage i ecr:GetDownloadUrlForLayer.
Wersje i aliasy
Analogia: wersja to zdjęcie przepisu w danym dniu (już się nie zmieni), $LATEST to brudnopis, a alias prod to karteczka „gotujemy według zdjęcia nr 7”. Wdrożenie polega na przesunięciu karteczki, a rollback na przesunięciu jej z powrotem. Klienci (API Gateway, triggery) wskazują alias, więc niczego u nich nie zmieniasz.
| Pojęcie | Co robi | Kiedy |
|---|---|---|
$LATEST | niepublikowana, edytowalna wersja; każdy deploy kodu ją nadpisuje | dev |
Wersja (publish-version) | niezmienny snapshot kodu, runtime'u, pamięci, warstw i zmiennych; numer rośnie (1, 2, 3…); ARN z sufiksem :7 | wydanie |
| Qualified / unqualified ARN | …:function:my-fn:prod (z kwalifikatorem) / …:function:my-fn (bez, czyli $LATEST) | aliasu nie utworzysz z unqualified ARN |
| Alias | nazwany wskaźnik na wersję (create-alias, update-alias); własny ARN; własne triggery, destinations, provisioned concurrency | prod/staging, stabilny ARN dla klientów |
| Weighted alias | --routing-config AdditionalVersionWeights={"2"=0.05}: 5% na wersję 2; obie wersje opublikowane, ta sama rola i ta sama konfiguracja DLQ (lub brak); nie $LATEST | canary; automatyzacja przez CodeDeploy (rozdz. 35) i SAM (AutoPublishAlias, rozdz. 33) |
Po opublikowaniu wersji jej kod, runtime, architektura, pamięć, warstwy i większość ustawień są niezmienne. Na wersji możesz nadal konfigurować m.in. triggery, destinations, provisioned concurrency i ustawienia async. Przy weighted alias metryki CloudWatch filtrujesz wymiarem ExecutedVersion, a w logach linia START pokazuje wersję. Ruch jest dzielony probabilistycznie, więc przy małym ruchu proporcje mogą odbiegać od ustawionych.
Concurrency: reserved, provisioned, limity konta
Wzór: concurrency = (żądania na sekundę) × (średni czas trwania w sekundach). 100 req/s × 0,5 s = 50 równoległych środowisk. 5 000 req/s × 0,2 s = 1 000.
| Cecha | Reserved concurrency | Provisioned concurrency |
|---|---|---|
| Co robi | rezerwuje część puli konta dla funkcji i jednocześnie ją ogranicza | utrzymuje N zainicjalizowanych środowisk (brak cold startu) |
| Koszt | bezpłatna | płatna (za czas utrzymania i wywołania) |
| Gdzie | na funkcji (wszystkie wersje razem) | na wersji lub aliasie, nie na $LATEST |
| Po przekroczeniu | throttling (429) | nadmiar idzie na on-demand (z cold startem), chyba że reserved ogranicza |
| Typowe pytanie | „funkcja zjada całą pulę i dusi inne” albo „baza downstream wytrzyma max 50 połączeń” | „latencja p99 przez cold start”, „przewidywalny szczyt o 9:00” |
| API / CLI | put-function-concurrency --reserved-concurrent-executions | put-provisioned-concurrency-config; skalowanie: Application Auto Scaling (scheduled albo target tracking na utylizacji) |
- Zarezerwować możesz najwyżej pulę konta minus 100. Te 100 jednostek zawsze zostaje dla funkcji bez rezerwacji.
- Provisioned concurrency nie może przekroczyć reserved concurrency (jeśli obie są ustawione). Gdy suma provisioned na wersjach i aliasach równa się reserved,
$LATESTzostanie wstrzymany (throttle). - Tempo skalowania: każda funkcja może dokładać 1 000 środowisk co 10 sekund (albo 10 000 req/s co 10 s), aż do limitu konta.
- Throttling przy async nie gubi zdarzeń: wracają do kolejki i są ponawiane do 6 godzin. Przy sync klient dostaje 429 i sam musi ponowić.
SnapStart
Analogia: zamiast rano rozpalać grill od zera, robisz zdjęcie gotowej, rozgrzanej kuchni i przy kolejnych zamówieniach „teleportujesz” się do tego stanu. Przy publikacji wersji Lambda robi INIT, zapisuje snapshot pamięci i dysku, a nowe środowiska wznawia ze snapshotu (faza RESTORE).
| Aspekt | SnapStart |
|---|---|
| Runtime'y | Java 11+, Python 3.12+, .NET 8+ (ZIP i obrazy na base images); nie Node.js, Ruby ani OS-only |
| Gdzie | tylko opublikowane wersje i aliasy na nie wskazujące; nie $LATEST |
| Nie łączy się z | provisioned concurrency, EFS, Amazon S3 Files, /tmp > 512 MB |
| Koszt | Java: bez dopłaty. Python/.NET: opłata za cache snapshotu (min. 3 h, dopóki wersja jest aktywna) i za każde przywrócenie |
| Pułapka | unikalność: wartości losowe, ID i połączenia wygenerowane w INIT będą takie same we wszystkich środowiskach; generuj je po przywróceniu (runtime hooks before-checkpoint / after-restore) |
| vs provisioned | provisioned daje najniższą latencję (dwucyfrowe ms), gdy SnapStart nie wystarcza |
Function URL i response streaming
Function URL to stały endpoint HTTPS https://<url-id>.lambda-url.<region>.on.aws przypięty do aliasu albo $LATEST (nie do numerowanej wersji). To najprostszy sposób na webhook czy proste API bez API Gateway. Nie daje jednak tego, co API Gateway: kluczy API z planami użycia, autoryzatorów Lambda i Cognito, walidacji i mapowania żądań, cache, kolejkowania i throttlingu żądań, WebSocketów. CORS konfigurujesz na samym URL.
| AuthType | Co robi | Kiedy |
|---|---|---|
AWS_IAM | żądania podpisane SigV4; wywołujący potrzebuje lambda:InvokeFunctionUrl i lambda:InvokeFunction; to samo konto: polityka tożsamości albo resource-based; inne konto: obie | wywołania serwis–serwis, wewnętrzne |
NONE | Lambda nie uwierzytelnia; resource-based policy musi zezwolić na publiczny dostęp (Principal: "*", warunek lambda:FunctionUrlAuthType) | publiczny webhook (własna weryfikacja w kodzie, np. podpisu HMAC) |
Od października 2025 nowe Function URL wymagają obu akcji: lambda:InvokeFunctionUrl i lambda:InvokeFunction. Starsze materiały pokazują tylko InvokeFunctionUrl. Ograniczenie ruchu na URL ustawiasz przez reserved concurrency (maksymalne RPS = 10 × reserved). Przekroczenie daje HTTP 429.
Response streaming: funkcja wysyła odpowiedź kawałkami, co skraca time-to-first-byte i pozwala na odpowiedzi do 200 MB (pierwsze 6 MB bez limitu, potem 2 MBps). Działa przez Function URL z InvokeMode=RESPONSE_STREAM (domyślnie BUFFERED, max 6 MB) albo API InvokeWithResponseStream. Natywnie wspierają to runtime'y Node.js, a inne języki przez custom runtime lub Lambda Web Adapter. Function URL nie streamuje wewnątrz VPC. Płacisz za cały czas działania, nawet gdy klient się rozłączy.
VPC i EFS
Domyślnie funkcja ma dostęp do internetu i publicznych endpointów AWS, ale nie do prywatnych zasobów w Twoim VPC (RDS, ElastiCache). Po podpięciu do VPC (podsieci + security groups) Lambda tworzy Hyperplane ENI i funkcja widzi zasoby prywatne, ale traci internet. Przywraca go NAT gateway w podsieci publicznej (funkcja w podsieciach prywatnych), a ruch do AWS może iść przez VPC endpoints. Podpięcie funkcji do podsieci publicznej nie daje jej internetu. Rola potrzebuje ec2:CreateNetworkInterface, ec2:DescribeNetworkInterfaces, ec2:DeleteNetworkInterface itd. (managed policy AWSLambdaVPCAccessExecutionRole). Szczegóły i animacja ścieżki pakietu: rozdział 4.
EFS: montujesz system plików pod ścieżką zaczynającą się od /mnt/ przez access point. Funkcja musi być w VPC z mount targetem w każdej używanej AZ. Rola potrzebuje elasticfilesystem:ClientMount (i ClientWrite do zapisu). Kiedy to wybrać: duże modele ML, pliki współdzielone między funkcjami, dane większe niż /tmp lub trwalsze od niego.
Runtime'y i paczki
Runtime'y mają daty wycofania (deprecation). Po tej dacie przez pewien czas można jeszcze tworzyć i aktualizować funkcje, potem jest to blokowane. Amazon Linux 2 kończy wsparcie 30 czerwca 2026, więc runtime'y na AL2 (np. Python 3.10/3.11, Java na AL2, provided.al2) warto przenieść na runtime'y oparte na Amazon Linux 2023. Paczkę ZIP do 50 MB wgrywasz bezpośrednio, większą przez S3 (do 250 MB po rozpakowaniu). Własny runtime to provided.al2023 z plikiem bootstrap.
- „Provisioned concurrency na $LATEST”: niemożliwe. Musisz opublikować wersję albo użyć aliasu.
- „Reserved concurrency usuwa cold starty”: nie. Reserved tylko rezerwuje i ogranicza pulę. Cold starty usuwa provisioned (albo skraca je SnapStart).
- „Zwiększę vCPU w ustawieniach Lambdy”: nie ma takiego ustawienia. CPU zwiększasz pamięcią.
- „Funkcja w publicznej podsieci ma internet”: dokumentacja mówi wprost: podsieć publiczna nie daje funkcji ani internetu, ani publicznego IP. Potrzebujesz prywatnej podsieci + NAT gateway.
- „Weighted alias na 3 wersje albo na $LATEST”: tylko dwie opublikowane wersje.
- „Sekret w zwykłej zmiennej środowiskowej jest niewidoczny”: jest szyfrowany w spoczynku, ale po odszyfrowaniu widać go w konfiguracji funkcji, np. w konsoli. Użyj encryption helpers albo Secrets Manager.
- „Warstwy w funkcji z obrazu kontenera”: nieobsługiwane. Wszystko wchodzi do obrazu.
- „SnapStart razem z provisioned concurrency”: wykluczają się.
Funkcja przetwarzająca obrazy działa 40 s przy 512 MB i jest ograniczona przez CPU. Jak skrócić czas najmniejszym kosztem pracy?
CPU-bound, szybciej
Odpowiedź
Zwiększ pamięć funkcji (CPU rośnie proporcjonalnie) i dobierz wartość np. narzędziem Lambda Power Tuning.
Dlaczego nie: reserved/provisioned concurrency nie przyspieszają pojedynczego wywołania. Dłuższy timeout nie przyspiesza.
Funkcja raportowa w godzinach szczytu zużywa całą concurrency konta, przez co krytyczna funkcja płatności dostaje 429. Co zrobić?
gwarancja dla krytycznej funkcji, inne zjadają pulę
Odpowiedź
Reserved concurrency dla funkcji płatności (gwarantowana pula), ewentualnie także limit (reserved) na funkcji raportowej.
Dlaczego nie: provisioned na raportach pogorszy sytuację i kosztuje. Zwiększenie pamięci nie zmienia concurrency.
API na Lambdzie w Javie ma wysokie p99 przez cold starty o 9:00, gdy startuje ruch biurowy. Jak najtaniej obniżyć latencję startu? (Wymagana bardzo niska, przewidywalna latencja w szczycie).
przewidywalny szczyt, najniższa latencja, Java
Odpowiedź
Provisioned concurrency na aliasie, skalowane harmonogramem Application Auto Scaling (scheduled scaling przed 9:00). Gdy wystarczy „krótszy cold start” bez dopłat, odpowiedzią jest SnapStart (Java bez dodatkowych kosztów).
Dlaczego nie: reserved concurrency nie inicjalizuje środowisk. Cron „rozgrzewający” to stary hack.
Zespół chce kierować 10% ruchu na nową wersję funkcji i szybko wycofać zmianę bez modyfikacji API Gateway.
10% ruchu, wycofanie, bez zmian u klienta
Odpowiedź
Alias (np. prod) z routing config: wersja nowa 0.1, stara jako główna. API Gateway wskazuje alias. Rollback = usunięcie wag. Automatycznie: CodeDeploy LambdaCanary10Percent5Minutes.
Dlaczego nie: dwie funkcje + Route 53 to więcej pracy. $LATEST nie może być w weighted alias.
Funkcja potrzebuje 600 MB bibliotek ML. Paczka ZIP jest odrzucana. Rozwiązanie?
zależności > 250 MB
Odpowiedź
Obraz kontenera w ECR (do 10 GB). Alternatywnie, przy danych lub modelach, EFS montowany w funkcji.
Dlaczego nie: warstwy liczą się do limitu 250 MB po rozpakowaniu. Upload przez S3 podnosi tylko limit paczki spakowanej.
Funkcja w prywatnych podsieciach VPC czyta RDS, ale wywołanie zewnętrznego API płatności kończy się timeoutem. Co dodać?
VPC, internet, timeout
Odpowiedź
NAT gateway w podsieci publicznej i trasę 0.0.0.0/0 z podsieci prywatnych do NAT.
Dlaczego nie: przeniesienie funkcji do podsieci publicznej nie da jej publicznego IP. Gateway endpoint obsługuje tylko S3 i DynamoDB.
Funkcja dostaje 400 req/s, a każde wywołanie trwa średnio 250 ms. Ile concurrency potrzebuje? A jeśli czas wzrośnie do 3 s przez wolną bazę?
Odpowiedź
400 × 0,25 = 100. Przy 3 s: 400 × 3 = 1 200, więcej niż domyślny limit 1 000 na całe konto. Wolny downstream potrafi zamienić spokojną funkcję w throttling całego konta.
🔬 Głębiej: RPS przy provisioned, spillover, warstwy cross-account
- Provisioned concurrency ma też limit żądań: 10 × PC na sekundę na wersję lub alias. Funkcja z PC = 10 przelewa się na on-demand po 10 równoległych wywołaniach albo 100 req/s, zależnie od tego, co nastąpi pierwsze.
- Ustawienie reserved = 0 dla funkcji wywoływanej async powoduje, że nowe zdarzenia idą od razu (bez ponowień) do DLQ lub on-failure destination.
- Funkcja może dalej używać warstwy, nawet gdy jej wersję usunięto lub odebrano dostęp. Nowej funkcji z usuniętą wersją warstwy już nie utworzysz.
- Warstwa „przypina” wersję SDK: runtime ma wbudowany SDK, który może się zmienić bez ostrzeżenia, a warstwa z własną wersją SDK daje stabilność.
- Shutdown z zewnętrznymi rozszerzeniami trwa do 2 s. Przy event source mapping Lambda nie czeka na zakończenie rozszerzeń przed wysłaniem kolejnej paczki, więc rozszerzenia mogą nadal działać i powodować throttling.
- Pamięć = CPU. Timeout max 900 s.
/tmpdo 10 GB. Env 4 KB, szyfrowane KMS. - Warstwy: 5,
/opt, tylko ZIP. Obraz kontenera: 10 GB z ECR. Extensions: procesy obok funkcji. - Wersja niezmienna, alias wskaźnik, weighted alias = 2 wersje, canary.
- Reserved: darmowa gwarancja + limit, 0 = wyłącz. Provisioned: płatna, bez cold startu, tylko wersja/alias. Skalowanie 1 000 środowisk na 10 s.
- SnapStart: Java/Python/.NET, snapshot po INIT, nie z PC ani EFS.
- Function URL:
AWS_IAMalboNONE. VPC zabiera internet, wraca z NAT.
Lambda: zdarzenia, ponowienia i błędy
kto ponawia? DLQ vs destinations, ESM, partial batch, idempotencjaNajczęstsze pytanie o Lambdę na egzaminie brzmi: co się stanie, gdy funkcja rzuci błąd? Odpowiedź zależy wyłącznie od sposobu wywołania. Przy wywołaniu synchronicznym błąd wraca do wywołującego i to on decyduje. Przy asynchronicznym Lambda ma własną kolejkę i sama ponawia. Przy event source mapping poller trzyma paczkę rekordów i ponawia według zasad źródła (kolejka albo strumień).
Analogia: wysyłasz list. Sync to rozmowa telefoniczna: jeśli rozmówca nie zrozumie, sam dzwonisz jeszcze raz. Async to skrzynka pocztowa z listonoszem: listonosz spróbuje doręczyć jeszcze dwa razy, a potem odda list na „poste restante” (DLQ albo on-failure destination). ESM to sekretarka, która bierze z tacy (kolejka) albo z taśmy (strumień) całą garść listów naraz. Z tacy niedoręczone listy wracają po chwili same. Z taśmy nie można wziąć następnego, dopóki obecny nie zostanie załatwiony, bo kolejność jest święta.
1.2.31.2.51.2.71.1.13
- Async: przy błędzie funkcji Lambda ponawia 2 razy (po ~1 min i ~2 min). Przy throttlingu i błędach 5xx zdarzenie wraca do kolejki do 6 godzin. Konfigurujesz
MaximumRetryAttempts(0–2) iMaximumEventAgeInSeconds(60 s–6 h). - DLQ (SQS lub SNS, standard) dostaje tylko samo zdarzenie i tylko po porażce. Destinations (SQS, SNS, Lambda, EventBridge, a S3 tylko przy porażce) dostają rekord wywołania (zdarzenie + odpowiedź lub błąd) i działają przy sukcesie albo porażce. Destinations są nowszym i bogatszym mechanizmem; DLQ to alternatywa dla on-failure destination.
- DLQ i async destinations dotyczą tylko wywołań asynchronicznych. Dla ESM na strumieniach (Kinesis, DynamoDB Streams, Kafka) istnieje osobne on-failure destination na mapowaniu. Dla SQS jako źródła DLQ konfigurujesz na kolejce źródłowej (redrive policy,
maxReceiveCount), a nie na funkcji. - SQS + Lambda: visibility timeout kolejki ≥ 6 × timeout funkcji. Błąd jednej wiadomości zwraca całą paczkę, chyba że włączysz
ReportBatchItemFailuresi zwróciszbatchItemFailures. - Kinesis/DynamoDB Streams: błąd blokuje shard (kolejność!) aż do sukcesu lub wygaśnięcia rekordu. Ratunek:
BisectBatchOnFunctionError,MaximumRetryAttempts,MaximumRecordAgeInSeconds, on-failure destination,ReportBatchItemFailures. Przepustowość zwiększaParallelizationFactor(1–10 paczek na shard). - Wszystkie mechanizmy to at-least-once, więc kod musi być idempotentny (np. Powertools Idempotency z DynamoDB). Lambda wykrywa pętle rekurencyjne (Lambda↔SQS/SNS/S3/EventBridge) i przerywa je po ~16 wywołaniach.
ReportBatchItemFailures + DLQ na kolejce (maxReceiveCount=5), Kinesis = bisect + MaximumRetryAttempts=2 + on-failure destination. Czasy oczekiwania są skrócone. Liczby prób zgadzają się z dokumentacją, poza czasami ilustracyjnymi.Kto ponawia: tabela decyzyjna
| Wywołanie | Błąd funkcji | Throttling (429) / błąd usługi | Gdzie lądują porażki |
|---|---|---|---|
| Sync (API GW, ALB, SDK, Function URL) | wraca do wywołującego; Lambda nie ponawia | 429 do wywołującego (SDK ponawia z backoffem wg swojej konfiguracji) | tam, gdzie zdecyduje Twój kod lub klient |
Async (S3, SNS, EventBridge, --invocation-type Event) | 2 ponowienia (0–2 konfigurowalne), ~1 min, potem ~2 min | powrót do kolejki, backoff 1 s → 5 min, do 6 h (MaximumEventAgeInSeconds) | DLQ (SQS/SNS) albo on-failure destination (SQS, SNS, S3, Lambda, EventBridge) |
| ESM: SQS | cała paczka (lub tylko zgłoszone ID) wraca do kolejki po visibility timeout | backoff pollera | DLQ kolejki po maxReceiveCount (zalecane ≥ 5) |
| ESM: Kinesis / DynamoDB Streams | ponawia całą paczkę do skutku albo wygaśnięcia; shard stoi | j.w. | on-failure destination ESM (SQS, SNS, S3; Kafka dla Kafki) po wyczerpaniu prób lub wieku |
| ESM: MSK / Kafka | j.w. (retry, bisect, max age, destination) | j.w. | on-failure destination (w tym topic Kafki) |
Async: konfiguracja błędów, DLQ i destinations
# ustawienia async na funkcji, wersji albo aliasie
aws lambda put-function-event-invoke-config --function-name my-fn \
--maximum-retry-attempts 1 --maximum-event-age-in-seconds 3600
# destinations (update-* nie kasuje pozostałych ustawień; put-* nadpisuje całość)
aws lambda update-function-event-invoke-config --function-name my-fn \
--destination-config '{"OnSuccess":{"Destination":"arn:aws:sqs:eu-central-1:111122223333:ok"},
"OnFailure":{"Destination":"arn:aws:events:eu-central-1:111122223333:event-bus/ops"}}'
# klasyczna DLQ (atrybut funkcji)
aws lambda update-function-configuration --function-name my-fn \
--dead-letter-config TargetArn=arn:aws:sqs:eu-central-1:111122223333:my-dlq
| Cecha | DLQ | Destinations (async) |
|---|---|---|
| Kiedy | tylko porażka (po ponowieniach albo przekroczeniu wieku) | OnSuccess i/lub OnFailure |
| Cele | SQS standard, SNS standard (nie FIFO) | SQS, SNS (standard), Lambda, EventBridge, S3 (tylko OnFailure) |
| Treść | oryginalne zdarzenie + atrybuty RequestID, ErrorCode, ErrorMessage (1 KB) | rekord JSON: requestContext (np. condition: RetriesExhausted, approximateInvokeCount), requestPayload, responsePayload |
| Uprawnienia (rola wykonawcza) | sqs:SendMessage / sns:Publish | sqs:SendMessage, sns:Publish, lambda:InvokeFunction, events:PutEvents, s3:PutObject + s3:ListBucket |
| Błąd dostarczenia | metryka DeadLetterErrors | metryka DestinationDeliveryFailures |
Ustawienia async (retries, max age, destinations) konfigurujesz osobno na funkcji, wersji lub aliasie. Async może dostarczyć to samo zdarzenie więcej niż raz, nawet bez błędu (kolejka wewnętrzna jest eventually consistent), więc znowu: idempotencja. Jeśli funkcja nie nadąża, zdarzenia mogą się zestarzeć i zostać odrzucone. Odrzucone zdarzenia przechwycisz destination albo DLQ. Reserved concurrency = 0 przy async wysyła nowe zdarzenia od razu do DLQ lub destination, bez ponowień.
Event source mapping: wspólne zasady
Event source mapping (ESM) to zasób Lambdy (CreateEventSourceMapping), w którym pollery czytają źródło, składają paczkę i wywołują funkcję synchronicznie. Paczka jest wysyłana, gdy zajdzie pierwsze z trzech: skończy się okno batchowania (MaximumBatchingWindowInSeconds, 0–300 s), osiągnięty zostanie BatchSize albo payload dojdzie do 6 MB. ESM przetwarza każde zdarzenie co najmniej raz. Uprawnienia do czytania źródła ma rola wykonawcza funkcji.
| Parametr | Co robi | Dotyczy / zakres |
|---|---|---|
BatchSize | max rekordów w paczce | Kinesis, DDB: domyślnie 100, max 10 000; SQS: domyślnie 10, standard do 10 000, FIFO do 10; Kafka/MQ/DocDB: 100 / 10 000. Powyżej 10 (Kinesis/DDB/SQS) okno ≥ 1 s |
MaximumBatchingWindowInSeconds | jak długo zbierać rekordy | 0–300 s; domyślnie 0 (Kinesis/DDB/SQS) albo 500 ms (Kafka, MQ, DocumentDB); dla SQS tylko kolejki standard |
FilterCriteria | filtrowanie rekordów przed wywołaniem (mniej wywołań, mniejszy koszt) | SQS, Kinesis, DDB, MSK/Kafka, MQ; do 5 filtrów (OR; do 10 po podniesieniu limitu) |
FunctionResponseTypes: ReportBatchItemFailures | funkcja zwraca, które rekordy się nie udały | SQS, Kinesis, DDB, MSK, Kafka |
StartingPosition | skąd czytać strumień: TRIM_HORIZON (najstarsze), LATEST (nowe), AT_TIMESTAMP | wymagany dla Kinesis i DDB; AT_TIMESTAMP nie dla DDB |
BisectBatchOnFunctionError | przy błędzie dzieli paczkę na pół i ponawia, żeby wyizolować „trujący” rekord | Kinesis, DDB, MSK, Kafka |
MaximumRetryAttempts | ile ponowień, potem odrzucenie | -1 (nieskończenie, domyślnie) … 10 000 |
MaximumRecordAgeInSeconds | odrzuć rekordy starsze niż N | -1 (domyślnie, do wygaśnięcia) … 604 800 (7 dni) |
DestinationConfig (OnFailure) | gdzie wysłać metadane odrzuconej paczki | SQS, SNS, S3 (+ Kafka topic dla Kafki) |
ParallelizationFactor | ile paczek z jednego sharda naraz (kolejność zachowana per klucz partycji) | Kinesis, DDB; 1–10 |
TumblingWindowInSeconds | agregacja stanu w oknach czasowych | Kinesis, DDB; 0–900 s |
ScalingConfig.MaximumConcurrency | limit równoległych wywołań z danej kolejki | tylko SQS; 2–1 000 |
ProvisionedPollerConfig | dedykowane pollery (min/max) dla stałej, niskiej latencji | SQS, MSK, Kafka (provisioned mode) |
SQS jako źródło
- Visibility timeout kolejki ≥ 6 × timeout funkcji (+ okno batchowania). Lambda nie pozwoli utworzyć ESM, jeśli timeout funkcji przekracza visibility timeout.
- Domyślnie błąd (wyjątek) = cała paczka wraca do kolejki, także wiadomości już przetworzone. Rozwiązanie:
ReportBatchItemFailuresi odpowiedź{"batchItemFailures":[{"itemIdentifier":"<messageId>"}]}. - Pusta lub
nulllistabatchItemFailures= sukces całej paczki. Wyjątek, niepoprawny JSON albo nieistniejące/pusteitemIdentifier= porażka całej paczki. Przy FIFO zatrzymaj przetwarzanie na pierwszym błędzie i zwróć wszystkie pozostałe ID (kolejność). - DLQ ustawiasz na kolejce źródłowej (
maxReceiveCount≥ 5), nie na funkcji. Wiadomości odfiltrowane przezFilterCriteriasą usuwane z kolejki. - Skalowanie (standard): start od 5 równoległych paczek, potem do +300 wywołań na minutę, domyślnie do 1 250 równoległych. FIFO: concurrency ≤ liczba grup wiadomości (
MessageGroupId). Maximum concurrency (2–1 000) chroni downstream i nie pozwala jednej kolejce zjeść puli. Nie ustawiaj jej wyżej niż reserved concurrency funkcji.
def handler(event, context):
failures = []
for rec in event["Records"]:
try:
process(rec["body"])
except Exception:
failures.append({"itemIdentifier": rec["messageId"]})
return {"batchItemFailures": failures} # tylko te wrócą do kolejki
Kinesis i DynamoDB Streams jako źródło
Strumień to taśma z rekordami ułożonymi w kolejności w obrębie sharda. Lambda czyta każdy shard osobno i domyślnie przetwarza jedną paczkę na shard naraz (Kinesis standard iterator: odpytywanie raz na sekundę; DynamoDB Streams: 4 razy na sekundę). Concurrency ≈ liczba shardów × ParallelizationFactor. Więcej przepustowości uzyskasz, dodając shardy albo zwiększając ParallelizationFactor. Enhanced fan-out (Kinesis) daje konsumentowi dedykowane łącze do każdego sharda i niższą latencję.
Domyślnie błąd = ponawianie całej paczki aż do sukcesu albo wygaśnięcia rekordu, a shard stoi (metryka IteratorAge rośnie). Przy domyślnych ustawieniach jeden zły rekord może zablokować shard na cały okres retencji strumienia (Kinesis: domyślnie 24 h, do 365 dni; DynamoDB Streams: 24 h). Dlatego ustaw rozsądne MaximumRetryAttempts i/lub MaximumRecordAgeInSeconds, włącz BisectBatchOnFunctionError i dodaj on-failure destination. Przy ReportBatchItemFailures zwracasz numer sekwencyjny pierwszego nieudanego rekordu, a Lambda robi checkpoint i ponawia od najniższego zgłoszonego numeru.
Tumbling windows (Kinesis, DDB): okna do 900 s, w których funkcja przekazuje sobie state (do 1 MB na shard) między wywołaniami. Na koniec okna przychodzi isFinalInvokeForWindow: true. Odpowiedź bez pola state traktowana jest jako błąd. Zastosowanie: agregaty „na żywo” (sumy na minutę) bez zewnętrznej bazy. DynamoDB Streams: najwyżej 2 funkcje na shard tabeli jednoregionowej (1 przy global tables). LATEST przy tworzeniu mapowania może pominąć zdarzenia, a TRIM_HORIZON ich nie gubi.
Near real time (skill 1.2.7): Kinesis Data Streams + Lambda (ESM), DynamoDB Streams + Lambda (reakcja na zmiany w tabeli), Amazon Data Firehose z transformacją Lambda (wywołanie synchroniczne funkcji na buforze rekordów przed zapisem do S3 itp.), S3 event → Lambda (async). Więcej o samych strumieniach w rozdziale 22.
Filtrowanie zdarzeń
# tylko wiadomości SQS, w których body.type == "order" i amount > 100
aws lambda create-event-source-mapping --function-name my-fn \
--event-source-arn arn:aws:sqs:eu-central-1:111122223333:orders \
--filter-criteria '{"Filters":[{"Pattern":"{\"body\":{\"type\":[\"order\"],\"amount\":[{\"numeric\":[\">\",100]}]}}"}]}'
Klucz pola danych zależy od źródła: body (SQS), data (Kinesis, MQ), dynamodb (DynamoDB Streams). Rekordy niespełniające filtra: SQS je usuwa, Kinesis i DDB je pomijają (iterator idzie dalej), Kafka i MQ je odrzucają. DocumentDB nie obsługuje filtrów. Składnia jest taka sama jak we wzorcach EventBridge (rozdz. 21).
Idempotencja i pętle rekurencyjne
Idempotencja: przetworzenie tego samego zdarzenia drugi raz nie zmienia wyniku. Klasyczny wzorzec: zapis warunkowy w DynamoDB z kluczem idempotencji (np. messageId, ID zamówienia). Powertools for AWS Lambda ma gotowe narzędzie Idempotency: dekoratory @idempotent / @idempotent_function, warstwa persystencji DynamoDBPersistenceLayer, klucz wybierany wyrażeniem JMESPath (event_key_jmespath), wynik zapamiętywany domyślnie na 1 godzinę (expires_after_seconds). Równoległe wywołanie z tym samym kluczem dostaje IdempotencyAlreadyInProgressError.
Recursive loop detection: funkcja zapisuje do tej samej kolejki, tematu lub bucketu, który ją wywołuje, i powstaje nieskończona pętla. Lambda śledzi łańcuch po nagłówkach X-Ray (nie trzeba włączać active tracing) i po ~16 wywołaniach w jednym łańcuchu przerywa kolejne, wysyła zdarzenie do DLQ lub destination (jeśli są ustawione), zwiększa metrykę RecursiveInvocationsDropped i powiadamia. Działa dla pętli przez SQS, SNS, S3, niestandardowe event busy EventBridge i bezpośrednie wywołania Lambda–Lambda. Celową rekursję włączysz przez put-function-recursion-config --recursive-loop Allow. Pętla S3 → Lambda → ten sam bucket to klasyk: zapisuj wynik do innego bucketu lub prefiksu i filtruj powiadomienia.
- „DLQ na funkcji dla źródła SQS”: DLQ funkcji dotyczy tylko async. Dla SQS ustawiasz redrive policy na kolejce źródłowej.
- „Destinations dla wywołań API Gateway”: sync nie ma destinations ani DLQ. Błąd wraca do klienta.
- „OnSuccess destination dla Kinesis ESM”: ESM ma tylko on-failure destination. OnSuccess istnieje tylko przy async.
- „Visibility timeout równy timeoutowi funkcji”: za mało. Zalecenie to 6× (throttling i ponowienia), inaczej wiadomości wracają w trakcie przetwarzania i są duplikowane.
- „Zwiększę batch size, żeby jeden błąd nie blokował”: większa paczka to więcej ponawianych rekordów. Pomaga partial batch response, bisect albo limit prób.
- „Retry attempts = 5 w async”: max to 2. Dłużej trzyma zdarzenia tylko throttling (do 6 h).
- „FIFO jako destination lub DLQ”: nieobsługiwane dla async (tylko standardowe SQS/SNS).
- „Exactly-once dzięki SQS FIFO + Lambda”: ESM to at-least-once. Duplikaty usuwasz idempotencją po swojej stronie.
Funkcja wywoływana przez S3 czasem zawodzi. Zespół chce dostać zdarzenie razem z treścią błędu i stack trace w kolejce SQS do analizy, a o sukcesach informować inny system przez EventBridge.
porażka z kontekstem błędu, sukces gdzie indziej
Odpowiedź
Lambda destinations: OnFailure → SQS, OnSuccess → EventBridge. Rekord zawiera requestPayload i responsePayload z błędem.
Dlaczego nie: DLQ dostaje tylko zdarzenie i krótki komunikat (1 KB), bez sukcesów. CloudWatch Logs subscription to więcej pracy.
Funkcja przetwarza paczki 10 wiadomości z SQS. Jedna wadliwa wiadomość powoduje ponowne przetwarzanie wszystkich 10 i duplikaty w bazie. Co zrobić?
jedna wiadomość, cała paczka wraca
Odpowiedź
Włącz ReportBatchItemFailures i zwracaj batchItemFailures z ID nieudanych wiadomości. Dodaj DLQ na kolejce i idempotencję.
Dlaczego nie: BatchSize=1 pomaga kosztem wydajności. Bisect nie istnieje dla SQS. Dłuższy visibility timeout nie zmienia zachowania.
IteratorAge strumienia Kinesis rośnie od godzin, a jeden shard stoi. Logi pokazują ten sam błąd parsowania co minutę. Jak odblokować przetwarzanie i zachować złe rekordy?
IteratorAge, shard stoi, poison pill
Odpowiedź
Na ESM ustaw BisectBatchOnFunctionError, ograniczone MaximumRetryAttempts (lub MaximumRecordAgeInSeconds) i on-failure destination (SQS/S3), ewentualnie ReportBatchItemFailures.
Dlaczego nie: więcej shardów nie odblokuje zablokowanego sharda. DLQ funkcji nie działa dla ESM. ParallelizationFactor nie omija złego rekordu.
Funkcja konsumuje strumień Kinesis z 4 shardami i nie nadąża, choć ma wolną concurrency. Kolejność per klucz partycji musi zostać zachowana. Najszybsza poprawa bez zmiany strumienia?
nie nadąża, shardy, kolejność per klucz
Odpowiedź
Zwiększ ParallelizationFactor (np. do 5, wtedy 4 × 5 = 20 równoległych paczek; kolejność per klucz zachowana).
Dlaczego nie: reshard to zmiana strumienia. Większy batch size może nie wystarczyć. Provisioned concurrency nie zwiększy liczby pollerów na shard.
Funkcja zapisuje miniaturę do tego samego bucketu S3, który ją wywołuje, i rachunek gwałtownie rośnie. Co zadziałało, a co zrobić?
S3 → Lambda → ten sam bucket
Odpowiedź
Lambda recursive loop detection przerwie łańcuch po ~16 wywołaniach (metryka RecursiveInvocationsDropped). Docelowo zapisuj do innego bucketu albo prefiksu i ustaw filtr prefiksu/sufiksu w powiadomieniu.
Dlaczego nie: reserved concurrency = 1 tylko spowolni pętlę.
Funkcja czyta SQS i zapisuje do bazy, która wytrzyma najwyżej 20 równoległych połączeń. Inne funkcje nie mogą stracić concurrency. Co skonfigurować?
chroń downstream, limit równoległości kolejki
Odpowiedź
Maximum concurrency = 20 na event source mapping SQS (ewentualnie reserved concurrency ≥ 20 na funkcji).
Dlaczego nie: samo reserved = 20 powoduje throttling pollera i ponowienia wiadomości. Mniejszy batch size nie ogranicza równoległości.
🔬 Głębiej: provisioned mode ESM, rzadkie szczegóły
- Provisioned mode ESM (SQS, MSK, Kafka): dedykowane pollery z min/max (SQS: min 2–200, max 2–10 000 według strony ESM; strona konfiguracji SQS podaje 2–2 000, dokumentacja jest niespójna), szybsze skalowanie (do 1 000 concurrency na minutę dla SQS). Wyklucza się z
MaximumConcurrency. Kosztuje dodatkowo. - Przy włączonym
ReportBatchItemFailuresdla SQS Lambda nie zmniejsza tempa odpytywania po błędach. - Przy jednoczesnym bisect i partial batch response paczka jest dzielona w zwróconym numerze sekwencyjnym.
- Okna batchowania dla Kafki/MQ/DocDB (domyślnie 500 ms) nie da się przywrócić do 500 ms po zmianie, trzeba utworzyć mapowanie od nowa.
- Przy pętli rekurencyjnej przez SQS kolejka może dalej ponawiać wiadomość aż do
maxReceiveCount. - Destination S3 zapisuje rekordy pod kluczem
aws/lambda/async/<function-name>/YYYY/MM/DD/…. Przy kluczu KMS potrzebny jestkms:GenerateDataKey.
- Sync: ponawia klient. Async: Lambda 2×, throttling do 6 h. ESM: poller według źródła.
- Destinations (sukces i porażka, pełny rekord) > DLQ (tylko porażka, samo zdarzenie). Oba tylko dla async.
- SQS: VT ≥ 6× timeout,
batchItemFailures, DLQ na kolejce, maximum concurrency. - Strumienie: shard stoi przy błędzie, więc bisect, max retries, max age, on-failure destination.
ParallelizationFactordo 10. - At-least-once wszędzie, więc idempotencja (Powertools + DynamoDB). Pętle przerywane po ~16 wywołaniach.
Kontenery: ECS, Fargate, ECR i EKS
task role vs execution role, porty, placement, ECRKontener to Twoja aplikacja zapakowana razem z zależnościami w obraz (Docker/OCI). AWS daje do tego trzy klocki. Amazon ECR to rejestr, w którym trzymasz obrazy. Amazon ECS to orkiestrator AWS (uruchamia, skaluje i podpina pod load balancer). Amazon EKS to zarządzany Kubernetes. ECS i EKS mogą uruchamiać kontenery na Twoich instancjach EC2 albo na AWS Fargate, czyli bez serwerów do zarządzania.
Analogia: ECR to magazyn gotowych dań w słoikach (obrazy). Task definition to przepis na zestaw: które słoiki, ile CPU i pamięci, jakie porty, jakie zmienne. Task to podany zestaw, czyli działająca kopia przepisu. Service to kierownik sali, który pilnuje, żeby zawsze stało N zestawów, i wymienia te, które się zepsuły. Cluster to sala. Na EC2 sam dostawiasz stoły (instancje), a na Fargate stoły pojawiają się same.
3.1.12.1.33.4.5
- Task role (
taskRoleArn) to uprawnienia Twojej aplikacji w kontenerze (S3, DynamoDB, SQS…). Task execution role (executionRoleArn) to uprawnienia agenta ECS/Fargate: pobranie obrazu z prywatnego ECR, wysyłka logówawslogsdo CloudWatch, pobranie sekretów z Secrets Manager / Parameter Store do zmiennych. Obie role ufająecs-tasks.amazonaws.com. - Fargate: brak instancji do zarządzania, sieć zawsze
awsvpc(każdy task ma własne ENI i IP), płacisz za vCPU i pamięć taska. EC2 launch type: pełna kontrola nad instancjami (GPU, typy instancji, tańsze przy dużym stałym obciążeniu), ale łatki i skalowanie instancji są po Twojej stronie. - Dynamic port mapping (tryb sieci
bridge,hostPortpominięty lub 0) pozwala uruchomić wiele kopii tego samego kontenera na jednej instancji za ALB. ECS sam rejestruje losowe porty w target group. - Placement strategies:
binpack(najmniej instancji, oszczędność),spread(rozłóż po AZ lub instancjach, dostępność),random. Constraints:distinctInstance(każdy task na innej instancji),memberOf(wyrażenie, np. typ instancji). Dotyczą EC2, nie Fargate. - ECR: logowanie
aws ecr get-login-password | docker login --username AWS --password-stdin <konto>.dkr.ecr.<region>.amazonaws.com(token ważny 12 h). Lifecycle policies usuwają stare obrazy. Image scanning: basic (CVE, on push lub ręcznie) albo enhanced (Amazon Inspector, ciągłe). - EKS: gdy zespół zna Kubernetes lub potrzebuje przenośności manifestów. Uprawnienia podów: EKS Pod Identity albo IRSA (IAM roles for service accounts).
ECS od środka: task definition, task, service
| Element | Co robi | Kiedy / uwagi |
|---|---|---|
Task definition (rodzina + rewizja, np. web:7) | JSON: obrazy, cpu/memory, portMappings, environment, secrets, logConfiguration, networkMode, role, wolumeny | każda zmiana tworzy nową rewizję; „wersjonowany przepis” |
| Task | uruchomiona instancja task definition (jeden lub kilka kontenerów) | zadania jednorazowe (RunTask), batch, cron przez EventBridge Scheduler |
| Service | utrzymuje desiredCount tasków, wymienia niezdrowe, integruje się z ELB, robi wdrożenia | długo działające API i workery; typ REPLICA albo DAEMON (jeden task na instancję) |
| Cluster | logiczna grupa tasków i serwisów; capacity providers (Fargate, Fargate Spot, ASG) | środowisko (dev/prod) |
| Container agent (EC2) | proces na instancji, który rejestruje ją w klastrze (ECS_CLUSTER w /etc/ecs/ecs.config) | instancja potrzebuje roli z AmazonEC2ContainerServiceforEC2Role |
{
"family": "web",
"requiresCompatibilities": ["FARGATE"],
"networkMode": "awsvpc",
"cpu": "512", "memory": "1024",
"executionRoleArn": "arn:aws:iam::111122223333:role/ecsTaskExecutionRole",
"taskRoleArn": "arn:aws:iam::111122223333:role/web-app-role",
"containerDefinitions": [{
"name": "app",
"image": "111122223333.dkr.ecr.eu-central-1.amazonaws.com/web:1.4.2",
"portMappings": [{ "containerPort": 8080 }],
"environment": [{ "name": "STAGE", "value": "prod" }],
"secrets": [{ "name": "DB_PASSWORD",
"valueFrom": "arn:aws:secretsmanager:eu-central-1:111122223333:secret:db-pass" }],
"logConfiguration": { "logDriver": "awslogs",
"options": { "awslogs-group": "/ecs/web", "awslogs-region": "eu-central-1",
"awslogs-stream-prefix": "app" } }
}]
}
Task role vs task execution role
| Cecha | Task execution role | Task role |
|---|---|---|
| Kto używa | agent ECS / Fargate (infrastruktura) | Twój kod w kontenerze (SDK, CLI) |
| Do czego | pull obrazu z prywatnego ECR (także cross-account), logi awslogs, secrets z Secrets Manager / SSM, uwierzytelnienie do prywatnego rejestru (repositoryCredentials) | wywołania AWS przez aplikację: S3, DynamoDB, SQS, KMS… |
| Managed policy | AmazonECSTaskExecutionRolePolicy | Twoja, wg least privilege |
| Widoczna w kontenerze? | nie, poświadczenia dostaje tylko agent | tak, przez endpoint poświadczeń (SDK pobiera je automatycznie) |
| Typowy błąd | task nie startuje (nie da się pobrać obrazu lub sekretu), brak logów | aplikacja dostaje AccessDenied |
Gdy task ma task role, SDK w kontenerze używa wyłącznie jej poświadczeń i nie dziedziczy uprawnień roli instancji EC2. Na Fargate profilu instancji w ogóle nie ma. Na EC2 z AMI innym niż ECS-optimized trzeba w agencie włączyć ECS_ENABLE_TASK_IAM_ROLE=true. Rola instancji (container instance role) służy tylko agentowi do rejestracji w klastrze. Ogranicz ją do AmazonEC2ContainerServiceforEC2Role, a uprawnień aplikacji tam nie dawaj.
Fargate vs EC2, sieć i porty
| Opcja | Co robi | Kiedy |
|---|---|---|
| Fargate | serverless: AWS zarządza hostami; awsvpc obowiązkowo; rozmiar taska od 0,25 vCPU / 512 MiB; ephemeral storage min. 20 GiB, do 200 GiB (ephemeralStorage) | „least operational overhead”, zmienny ruch, izolacja na poziomie taska |
| Fargate Spot | zapasowa pojemność ze zniżką; przerwanie z 2-minutowym ostrzeżeniem | zadania odporne na przerwanie (batch, CI) |
| EC2 launch type | Twoje instancje w ASG (capacity provider z managed scaling); dowolne typy, GPU, daemony | stałe, duże obciążenie, specjalny sprzęt, kontrola nad hostem |
Sieć awsvpc | task dostaje własne ENI i prywatne IP; security group per task | zalecana, wymagana na Fargate |
Sieć bridge | wirtualna sieć Dockera; mapowanie statyczne albo dynamiczne (bez hostPort, losowy port z zakresu ephemeral) | wiele kopii kontenera na jednej instancji EC2 za ALB |
Sieć host | kontener używa sieci instancji; brak dynamicznych portów | maksymalna wydajność sieci, jeden kontener na port |
W trybie awsvpc podajesz tylko containerPort, bo hostPort jest ignorowany lub równy containerPort. W bridge pominięty hostPort oznacza, że Docker wybiera losowy wolny port, a ECS aktualizuje target group ALB (i AWS Cloud Map) o IP i port każdego taska. Minusem jest to, że security groups muszą otwierać szeroki zakres portów między ALB a instancjami.
Rozmieszczanie, skalowanie, wdrożenia
| Mechanizm | Co robi | Kiedy |
|---|---|---|
binpack (cpu/memory) | pakuje taski tak, by zostało najmniej wolnego CPU/pamięci; najmniej instancji | „minimalizuj koszty / liczbę instancji” |
spread (np. attribute:ecs.availability-zone, instanceId) | rozkłada równomiernie; domyślna dla serwisów: spread po AZ | wysoka dostępność |
random | losowo | bez wymagań |
distinctInstance | każdy task na innej instancji | „nie więcej niż jeden task na instancję” |
memberOf (cluster query language) | tylko instancje spełniające wyrażenie, np. attribute:ecs.instance-type =~ g4dn.* | GPU, konkretna AZ, wersja Windows |
| Service Auto Scaling | Application Auto Scaling: target tracking (np. średnie CPU/pamięć serwisu, liczba żądań ALB na target), step, scheduled, predictive | skalowanie liczby tasków |
| Cluster auto scaling | capacity provider ASG z managed scaling dokłada i usuwa instancje EC2 | skalowanie hostów (EC2 launch type) |
Rolling update (kontroler ECS) | minimumHealthyPercent (domyślnie 100%) i maximumPercent (domyślnie 200%) dla REPLICA; deployment circuit breaker z automatycznym rollbackiem | domyślne wdrożenia |
| Blue/green, linear, canary | natywne strategie kontrolera ECS albo kontroler CODE_DEPLOY (rozdz. 35); EXTERNAL dla narzędzi zewnętrznych | przesuwanie ruchu, szybki rollback |
Kilka strategii można łączyć w kolejności, np. najpierw spread po AZ, potem binpack po pamięci. Dla zadań uruchamianych ręcznie (standalone) nie ma domyślnego ograniczenia rozmieszczenia. Do debugowania działającego kontenera służy ECS Exec (aws ecs execute-command, oparty na SSM Session Manager).
Amazon ECR
aws ecr create-repository --repository-name web --image-scanning-configuration scanOnPush=true
aws ecr get-login-password --region eu-central-1 \
| docker login --username AWS --password-stdin 111122223333.dkr.ecr.eu-central-1.amazonaws.com
docker build -t web:1.4.2 .
docker tag web:1.4.2 111122223333.dkr.ecr.eu-central-1.amazonaws.com/web:1.4.2
docker push 111122223333.dkr.ecr.eu-central-1.amazonaws.com/web:1.4.2
| Funkcja ECR | Co robi | Kiedy |
|---|---|---|
Token (GetAuthorizationToken) | get-login-password zwraca token na 12 h z uprawnieniami principala IAM | CI/CD (CodeBuild) przed docker push |
| Lifecycle policy | reguły (priorytet: niższy numer = ważniejsza) wygaszające obrazy, np. untagged starsze niż 14 dni albo „zostaw 30 ostatnich”; najpierw podgląd (preview); wykonanie do 24 h | koszt przechowywania, porządek |
| Basic scanning | CVE systemu operacyjnego; ręcznie lub scan on push; wyniki w DescribeImageScanFindings | darmowe podstawy |
| Enhanced scanning | Amazon Inspector: OS + pakiety języków, scan on push i ciągłe skanowanie | „continuously scan for new vulnerabilities” |
| Tag immutability | blokuje nadpisanie tagu (ImageTagAlreadyExistsException) | gwarancja, że :1.4.2 zawsze oznacza ten sam obraz |
| Repository policy | resource-based: kto może pull/push (inne konta, Lambda: ecr:BatchGetImage, ecr:GetDownloadUrlForLayer) | cross-account |
| Replication, pull through cache | kopiowanie do innych regionów i kont; cache obrazów z rejestrów publicznych | multi-region, limity Docker Hub |
Amazon EKS w pigułce
EKS to zarządzana płaszczyzna sterowania Kubernetes (control plane). Węzły to do wyboru: EKS Auto Mode (AWS zarządza węzłami), managed node groups, węzły self-managed albo Fargate (pod bez węzła). Wdrażasz manifestami Kubernetes (kubectl, Helm). Uprawnienia AWS dla podów nadajesz przez EKS Pod Identity (powiązanie roli IAM z kontem serwisowym w namespace) albo starszy mechanizm IRSA (OIDC). Na egzaminie EKS wybierasz, gdy pada słowo „Kubernetes”. W pozostałych przypadkach („najmniej pracy”, „natywnie AWS”) wygrywa zwykle ECS na Fargate.
- „Dodaj uprawnienia S3 do task execution role”: aplikacja z nich nie skorzysta. Uprawnienia aplikacji należą do task role.
- „Task nie może pobrać obrazu, więc dodaj uprawnienia ECR do task role”: obraz pobiera agent, więc uprawnienia muszą być w execution role (i droga sieciowa do ECR: NAT albo interface VPC endpoints).
- „Uprawnienia aplikacji w roli instancji EC2”: działa, ale łamie least privilege, bo wszystkie taski na hoście dostają te same uprawnienia. Właściwa odpowiedź to task role.
- „Placement strategy binpack na Fargate”: strategie i ograniczenia dotyczą EC2 launch type.
- „Dwie kopie kontenera na porcie 80 na jednej instancji”: kolizja portów. Rozwiązaniem jest dynamic port mapping (bridge) albo
awsvpc. - „docker login hasłem IAM”: używasz tokenu z
get-login-password, a użytkownik to zawszeAWS. - „Hasło do bazy w
environmenttask definition”: jest jawne w definicji. UżyjsecretszvalueFrom(Secrets Manager / Parameter Store).
Aplikacja w tasku Fargate dostaje AccessDenied przy zapisie do DynamoDB. Execution role ma AmazonECSTaskExecutionRolePolicy i dodatkowo dynamodb:PutItem. Poprawka?
aplikacja, AccessDenied, execution role
Odpowiedź
Utwórz task role z dynamodb:PutItem i ustaw taskRoleArn w task definition.
Dlaczego nie: execution role używa tylko agent. Klucze w zmiennych środowiskowych łamią dobre praktyki.
Serwis ECS na EC2 ma uruchamiać kilka kopii tego samego kontenera (port 8080) na każdej instancji za ALB. Co skonfigurować?
wiele kopii na instancji, ALB
Odpowiedź
Dynamic port mapping: tryb bridge, containerPort 8080, bez hostPort. ECS rejestruje losowe porty w target group. (Alternatywa: tryb awsvpc, w którym każdy task ma własne IP).
Dlaczego nie: tryb host nie obsługuje dynamicznych portów, więc działa jeden kontener na port. Statyczne hostPort: 8080 daje kolizję.
Zespół chce minimalizować liczbę instancji EC2 w klastrze ECS przy rozmieszczaniu tasków.
najmniej instancji, koszt
Odpowiedź
Placement strategy binpack (po pamięci lub CPU).
Dlaczego nie: spread rozkłada taski, czyli działa odwrotnie. distinctInstance wymusza po jednym tasku na instancję.
Pipeline CodeBuild ma wypychać obrazy do ECR. Krok docker push kończy się błędem uwierzytelnienia. Czego brakuje?
push, auth, ECR
Odpowiedź
Logowania do ECR: aws ecr get-login-password | docker login --username AWS --password-stdin <registry> (i uprawnień ecr:GetAuthorizationToken oraz push w roli CodeBuild).
Dlaczego nie: polityka repozytorium sama nie zaloguje Dockera. Klucze dostępu w buildspec to zła praktyka.
Repozytorium ECR rośnie bez końca. Mają zostać tylko obrazy z ostatnich 30 tagów, a nieotagowane mają znikać po 7 dniach. Najmniej pracy?
automatyczne czyszczenie obrazów
Odpowiedź
ECR lifecycle policy z dwiema regułami (untagged sinceImagePushed 7 dni; imageCountMoreThan 30).
Dlaczego nie: Lambda z cronem to własny kod. Reguła S3 lifecycle nie działa na ECR.
Firma chce uruchamiać kontenery bez zarządzania serwerami, łatkami i skalowaniem hostów, z jak najmniejszym nakładem pracy. Zespół nie zna Kubernetes.
bez serwerów, najmniej pracy, bez Kubernetes
Odpowiedź
Amazon ECS na AWS Fargate.
Dlaczego nie: ECS na EC2 wymaga zarządzania instancjami. EKS to Kubernetes. Beanstalk z Dockerem też działa, ale ECS/Fargate jest natywną odpowiedzią przy kontenerach.
Task nie startuje, bo nie udaje się pobrać sekretu wskazanego w secrets. Która rola i jaki dostęp sieciowy są potrzebne? (Podpowiedź: kto wstrzykuje sekret do zmiennej, zanim kontener ruszy? Agent, czyli execution role z secretsmanager:GetSecretValue, plus droga sieciowa do Secrets Manager: NAT albo interface endpoint).
🔬 Głębiej: zarezerwowane porty, DAEMON, Windows
- Zarezerwowane porty instancji kontenera: 22 (SSH), 2375 i 2376 (Docker), 51678–51680 (agent ECS). Domyślny zakres ephemeral Dockera to
49153–65535, jeśli parametr jądra jest niedostępny. - Serwis DAEMON: domyślne
minimumHealthyPercentwynosi 0% (CLI/SDK/API), amaximumPercent100%. - Kontenery Windows muszą mieć wersję systemu zgodną z hostem, a ograniczenie
memberOf(attribute:ecs.os-family == …)pilnuje dopasowania. - Ephemeral storage powyżej 20 GiB na Fargate wymaga platformy 1.4.0+ (Linux).
- Execution role = agent (ECR pull, logi, sekrety). Task role = aplikacja (S3, DynamoDB…).
- Fargate: bez serwerów,
awsvpc. EC2: kontrola, dynamic port mapping wbridge. binpack= mniej instancji,spread= dostępność (domyślnie po AZ),distinctInstance= po jednym na hosta.- ECR:
get-login-password(12 h), lifecycle policy, scan basic/enhanced, tag immutability. - EKS = Kubernetes, uprawnienia podów przez Pod Identity / IRSA.
Dane: DynamoDB, S3, RDS, cache
Ta część to najgęściej punktowany kawałek egzaminu po Lambdzie: arytmetyka RCU/WCU, Query kontra Scan, indeksy, Streams, TTL, DAX, a potem S3 (klasy, wersjonowanie, presigned URL, multipart, szyfrowanie), RDS/Aurora i strategie cache. Po niej rozpoznasz każde pytanie „który magazyn danych i z jaką opcją”.
DynamoDB: klucze, spójność i pojemność
policz RCU, zanim policzy cię fakturaWyobraź sobie szatnię z setkami wieszaków. Numerek, który dostajesz (partition key), mówi szatniarzowi, przy którym wieszaku szukać — nie musi przeglądać całej sali. Jeśli na jednym wieszaku wisi kilka rzeczy, układa je w kolejności według drugiej etykiety (sort key). DynamoDB działa tak samo: haszuje klucz partycji, żeby trafić w konkretną partycję (fizyczny kawałek tabeli), a wewnątrz partycji trzyma elementy posortowane po kluczu sortowania.
Tabela (table) składa się z elementów (items), a element z atrybutów (attributes). Schemat jest elastyczny: wymagany jest tylko klucz główny (primary key). Klucz główny jest prosty (sam partition key) albo złożony (partition key + sort key) — wtedy unikalna musi być dopiero para tych wartości.
Pojemność (throughput) liczysz w jednostkach: RCU (read capacity unit) i WCU (write capacity unit). Jedno RCU to jeden silnie spójny odczyt na sekundę elementu do 4 KB (albo dwa odczyty ostatecznie spójne). Jedno WCU to jeden zapis na sekundę elementu do 1 KB. Cała reszta tego rozdziału to konsekwencje tych dwóch zdań.
1.3.11.3.21.3.51.3.6
- Rachunek RCU/WCU: odczyt zaokrąglasz w górę do 4 KB, zapis do 1 KB; eventual = połowa strong, transactional = dwa razy strong (dla zapisu: dwa razy zwykły).
- Odczyty są domyślnie ostatecznie spójne (eventually consistent); silnie spójne włączasz parametrem
ConsistentRead=truei płacisz dwa razy więcej. - On-demand = płacisz za żądanie, zero planowania, dobry dla nieprzewidywalnego ruchu; provisioned (+ auto scaling) = przewidywalny ruch i niższy koszt.
- Klucz partycji o wysokiej kardynalności (high-cardinality: userId, orderId), nie „status” czy „data”. Gorący klucz →
ProvisionedThroughputExceededException, nawet gdy tabela ma zapas pojemności. - Maksymalny rozmiar elementu: 400 KB (liczą się też nazwy atrybutów). Większe dane → S3 + wskaźnik w DynamoDB.
Rachunek RCU/WCU — reguły i przykłady
Algorytm egzaminacyjny jest zawsze ten sam: (1) zaokrąglij rozmiar elementu w górę (odczyt do wielokrotności 4 KB, zapis do 1 KB), (2) podziel przez 4 KB albo 1 KB, (3) pomnóż przez liczbę operacji na sekundę, (4) dla eventual podziel przez 2, dla transakcji pomnóż przez 2. Zaokrąglasz rozmiar elementu, a nie wynik końcowy — 10 elementów po 1 KB czytanych osobno (GetItem) to 10 × 1 RCU, nie 3 RCU.
| Scenariusz | Rachunek | Wynik |
|---|---|---|
| 80 odczytów/s, 3 KB, strong (przykład z dokumentacji) | 3 KB → 4 KB = 1 RCU × 80 | 80 RCU |
| 10 odczytów/s, 6 KB, eventual | 6 KB → 8 KB = 2 RCU × 10 = 20 ÷ 2 | 10 RCU |
| 10 odczytów/s, 6 KB, strong | 2 RCU × 10 | 20 RCU |
| 10 odczytów/s, 6 KB, transactional | 2 RCU × 10 × 2 | 40 RCU |
| 100 zapisów/s, 512 B (przykład z dokumentacji) | 0,5 KB → 1 KB = 1 WCU × 100 | 100 WCU |
| 5 zapisów/s, 2,5 KB | 2,5 KB → 3 KB = 3 WCU × 5 | 15 WCU |
| 5 zapisów/s, 2,5 KB, transactional | 3 WCU × 5 × 2 | 30 WCU |
| Query zwraca 10 elementów po 1 KB, eventual | Query sumuje rozmiary: 10 KB → 12 KB = 3 RCU ÷ 2 | 1,5 RCU (jedno żądanie) |
- Query i Scan liczą się inaczej niż
GetItem: DynamoDB sumuje rozmiar wszystkich przeczytanych elementów i dopiero tę sumę zaokrągla do 4 KB. Dlatego Query po wielu małych elementach jest dużo tańszy niż tyle samoGetItem. BatchGetItemiBatchWriteItemliczą każdy element osobno, tak jakby był pojedynczymGetItem/PutItem.UpdateItemzużywa WCU według większego z rozmiarów „przed” i „po” — nawet jeśli zmieniasz jeden atrybut dużego elementu.- Odczyt elementu, który nie istnieje, też zużywa RCU. Nieudany zapis warunkowy (
ConditionExpression= false) też zużywa WCU. - Ile faktycznie zużyło żądanie? Parametr
ReturnConsumedCapacity=TOTAL(suma) alboINDEXES(z rozbiciem na tabelę i indeksy).
Aplikacja czyta 25 elementów po 9 KB na sekundę (silnie spójnie) i zapisuje 12 elementów po 1,5 KB na sekundę. Ile RCU i WCU potrzebuje tabela w trybie provisioned? Ile, gdyby odczyty mogły być ostatecznie spójne?
Odpowiedź
Odczyt: 9 KB → 12 KB = 3 RCU × 25 = 75 RCU (strong). Eventual: 75 ÷ 2 = 37,5 → 38 RCU. Zapis: 1,5 KB → 2 KB = 2 WCU × 12 = 24 WCU.
Spójność odczytu
| Opcja | Co robi | Kiedy |
|---|---|---|
| Eventually consistent (domyślnie) | Może nie zawierać zapisu zakończonego przed chwilą; kosztuje 0,5 RCU / 4 KB. | Większość odczytów: katalogi, profile, listy. |
Strongly consistent (ConsistentRead=true) | Zwraca najnowszy zatwierdzony stan; 1 RCU / 4 KB. Dostępne dla tabeli i LSI, nie dla GSI. | „Read-after-write”: saldo, stan zamówienia tuż po zapisie. |
Transactional (TransactGetItems) | Spójny obraz wielu elementów naraz; 2 RCU / 4 KB. | Odczyt kilku elementów, które muszą do siebie pasować. |
On-demand czy provisioned
| Tryb | Co robi | Kiedy |
|---|---|---|
| On-demand | Płacisz za każde żądanie (read/write request units). Nowa tabela przyjmuje od razu do 4 000 zapisów/s i 12 000 odczytów/s; ruch do dwukrotności poprzedniego szczytu obsługuje natychmiast. Opcjonalnie ustawisz maksymalną przepustowość tabeli/GSI, żeby ograniczyć koszty. | Nowa aplikacja, nieznany lub skokowy ruch, „least operational overhead”. |
| Provisioned | Deklarujesz RCU/WCU; płacisz za zadeklarowaną pojemność godzinowo, nawet jeśli jej nie używasz. | Przewidywalny, stały ruch; optymalizacja kosztów (też reserved capacity). |
| Provisioned + auto scaling | Application Auto Scaling z polityką target tracking: docelowe wykorzystanie 20–90%, min/max pojemności, osobno dla tabeli i każdego GSI. Reaguje, gdy zużycie przekracza cel przez dwie kolejne minuty. | Ruch zmienny, ale z trendem dobowym; nie chroni przed nagłym skokiem w ciągu sekund. |
Zmiana trybu: z provisioned na on-demand możesz przełączyć tabelę do czterech razy w 24-godzinnym oknie, a z on-demand na provisioned — w dowolnym momencie. W starszych testach próbnych spotkasz regułę „przełączenie raz na 24 godziny” — dziś obowiązuje limit z dokumentacji. Pojemność provisioned podnosisz dowolnie często (UpdateTable), ale zmniejszenia są limitowane: na początku doby UTC masz 4, potem przybywa jedno na godzinę (do 27 na dobę).
Domyślne limity przepustowości: 40 000 RCU i 40 000 WCU na tabelę (w on-demand: 40 000 read/write request units) oraz 80 000 RCU/WCU na konto w trybie provisioned; do 2 500 tabel na region. Wszystkie te limity da się podnieść przez Service Quotas.
Partycje, gorące klucze i throttling
Każda partycja ma twardy sufit: 3 000 RCU i 1 000 WCU. Jeśli wszystkie zapisy idą na jeden klucz (np. status = "NEW" albo dzisiejsza data), cała tabela może mieć 10 000 WCU, a i tak dostaniesz throttling na jednej partycji. Dwa mechanizmy łagodzą problem automatycznie:
- Burst capacity — DynamoDB odkłada do 300 sekund niewykorzystanej pojemności i zużywa ją przy krótkim skoku.
- Adaptive capacity — włączone zawsze, bez opłat; przesuwa pojemność do gorących partycji, a bardzo gorący element potrafi odizolować w osobnej partycji (wciąż do limitu 3 000 RCU / 1 000 WCU).
Gdy to nie wystarcza, projektujesz klucz: write sharding — dodajesz sufiks losowy (np. 2024-07-09.1 … .200) albo wyliczany z innego atrybutu (wtedy wiesz, gdzie szukać przy odczycie). Ceną jest odczyt: żeby zebrać dzień, musisz odpytać wszystkie sufiksy i scalić wyniki. Gorące klucze znajdziesz w CloudWatch Contributor Insights for DynamoDB (najczęściej używane i najczęściej dławione klucze), a samo dławienie w metrykach ReadThrottleEvents, WriteThrottleEvents i ThrottledRequests.
| Błąd | Co znaczy | Co robisz |
|---|---|---|
ProvisionedThroughputExceededException | Przekroczona pojemność provisioned tabeli/indeksu albo partycji. | SDK ponawia automatycznie z exponential backoff; ty: lepszy klucz, auto scaling, on-demand, DAX dla odczytów. |
ThrottlingException | M.in. przekroczona skonfigurowana maksymalna przepustowość on-demand lub limit partycji/konta. | Backoff, podniesienie limitu, rozproszenie klucza. |
RequestLimitExceeded | Przekroczony limit przepustowości na poziomie konta. | Service Quotas, backoff. |
Elementy, typy i serializacja
Typy skalarne: S (string), N (number), B (binary), BOOL, NULL; dokumentowe: M (map), L (list); zbiory: SS, NS, BS. Klucz partycji ma od 1 do 2048 bajtów, klucz sortowania od 1 do 1024 bajtów, zagnieżdżenie do 32 poziomów. Niskopoziomowe API mówi „DynamoDB JSON”, w którym każda wartość niesie typ:
{ "pk": {"S": "USER#42"}, "sk": {"S": "ORDER#2024-07-09"},
"total": {"N": "129.90"}, "tags": {"SS": ["gift","express"]},
"address": {"M": {"city": {"S": "Kraków"}}} }
Serializację (umiejętność 1.3.5) robią za ciebie warstwy wyżej: w JavaScript DynamoDBDocumentClient (marshall/unmarshall), w Pythonie zasób boto3.resource('dynamodb') albo TypeSerializer, w Javie Enhanced Client (dawniej DynamoDBMapper). Przy serializacji uważaj na rozmiar: nazwy atrybutów też wchodzą do limitu 400 KB, więc krótkie nazwy oszczędzają WCU. Duże obiekty (zdjęcia, PDF) kładziesz do S3, a w DynamoDB trzymasz klucz obiektu.
- „Dodaj RCU do tabeli” przy throttlingu jednego klucza — kusi, bo throttling kojarzy się z pojemnością tabeli, ale limit 3 000/1 000 jest na partycję. Poprawka to klucz o wysokiej kardynalności lub write sharding.
- Zaokrąglanie wyniku zamiast elementu — 3 elementy po 1,5 KB zapisane osobno to 3 × 2 = 6 WCU, nie 5.
- Eventual przy transakcjach — transakcyjny odczyt zawsze kosztuje 2 RCU / 4 KB; nie ma „transakcji ostatecznie spójnej”.
- „On-demand nigdy nie dławi” — dławi, gdy ruch więcej niż podwoi poprzedni szczyt w ciągu 30 minut, gdy przekroczysz skonfigurowane maksimum albo limit partycji.
- Silna spójność na GSI — niemożliwa; tylko tabela i LSI.
- „Elementy do 4 KB” — 4 KB to jednostka rozliczenia odczytu, a limit elementu to 400 KB.
Aplikacja czyta 50 elementów po 7 KB na sekundę, a wynik nie musi uwzględniać zapisów sprzed sekundy. Ile RCU zaprovisionować?
7 KB · 50/s · „nie musi uwzględniać” = eventually consistent
Odpowiedź
50 RCU. 7 KB → 8 KB = 2 RCU (strong) × 50 = 100; eventual ÷ 2 = 50.
Dlatego nie: 100 (to strong), 88 (zaokrąglenie 7 KB do 7/4 bez zaokrąglenia rozmiaru), 200 (transactional).
Tabela zamówień ma klucz partycji orderDate (dzień). W godzinach szczytu zapisy są dławione, choć CloudWatch pokazuje, że tabela zużywa 20% zaprovisionowanych WCU. Co zrobić?
throttling przy niskim zużyciu tabeli = gorąca partycja
Odpowiedź
Zmienić klucz partycji na atrybut o wysokiej kardynalności (np. orderId) albo dodać sufiks (write sharding). Wszystkie zapisy dnia trafiają do jednej partycji z limitem 1 000 WCU.
Dlatego nie: podniesienie WCU (limit partycji zostaje), DAX (cache tylko odczytów), strongly consistent reads (nie dotyczy zapisów).
Startup uruchamia nową aplikację, nie zna wzorca ruchu i chce zminimalizować zarządzanie pojemnością. Jaki tryb wybrać?
nieznany ruch · least operational overhead
Odpowiedź
On-demand. Bez planowania pojemności, płatność za żądanie.
Dlatego nie: provisioned z auto scalingiem (wciąż trzeba ustawić min/max i cel, reaguje z opóźnieniem), reserved capacity (wymaga przewidywalnego ruchu).
Ruch tabeli provisioned jest stabilny w ciągu dnia, ale rośnie wieczorem dwukrotnie i spada w nocy. Zespół chce płacić mniej bez ręcznych zmian.
przewidywalny trend · bez ręcznych zmian
Odpowiedź
Auto scaling (Application Auto Scaling, target tracking, np. 70%).
Dlatego nie: ręczne UpdateTable z crona (limit zmniejszeń, praca operacyjna), on-demand (przy przewidywalnym ruchu zwykle droższy), DAX (nie zmienia WCU).
Po zapisie profilu użytkownik od razu odświeża stronę i czasem widzi stare dane. Aplikacja używa GetItem z domyślnymi parametrami. Najprostsza poprawka?
read-after-write · domyślne parametry
Odpowiedź
ConsistentRead=true w tym odczycie. Domyślny odczyt jest ostatecznie spójny.
Dlatego nie: GSI (tylko eventual), DAX (cache ostatecznie spójny, pogorszy problem), transakcja (drożej, niepotrzebnie).
ProjectionExpression zmniejsza zużycie RCU?🔬 Głębiej: jednostki binarne, reserved capacity, warm throughput
DynamoDB liczy w jednostkach binarnych: 1 KB = 1024 bajty, 1 MB = 1024 KB. Element 4 096 bajtów to dokładnie 1 RCU, a 4 097 bajtów to już 2 RCU (strong).
Reserved capacity to zniżka za zobowiązanie do określonej pojemności provisioned na rok lub (w wybranych regionach) trzy lata — odpowiedź na pytanie „stały ruch, jak najniższy koszt”.
Jeśli spodziewasz się dużego jednorazowego skoku w on-demand (np. premiera), możesz wcześniej zwiększyć ruch stopniowo albo skorzystać z ustawienia warm throughput, żeby tabela była gotowa. Reguła „dwukrotność poprzedniego szczytu, a większy wzrost rozłóż na 30 minut” wciąż jest tym, co sprawdza egzamin.
- RCU: 4 KB, strong = 1, eventual = 0,5, transactional = 2. WCU: 1 KB, standard = 1, transactional = 2. Zaokrąglasz rozmiar elementu w górę.
- Domyślnie eventual;
ConsistentRead=truedla tabeli i LSI; GSI tylko eventual. - On-demand: nieznany ruch, zero zarządzania; provisioned + auto scaling (20–90%): przewidywalny ruch, taniej.
- Partycja: 3 000 RCU / 1 000 WCU; burst 300 s; adaptive capacity automatycznie; klucz o wysokiej kardynalności albo write sharding.
- Element do 400 KB; większe dane do S3 + wskaźnik.
DynamoDB API: Query, Scan, warunki i transakcje
Scan to odkurzacz — wciąga wszystko, płacisz za worekWróć do szatni. Query to podejście do jednego wieszaka (jedna wartość partition key) i zdjęcie kurtek z zakresu numerków (warunek na sort key). Scan to obejście całej sali i obejrzenie każdego wieszaka. Filtr (FilterExpression) nie skraca spaceru — szatniarz i tak ogląda każdą kurtkę, tylko część odkłada z powrotem. Dlatego płacisz za to, co przeczytano, a nie za to, co zwrócono.
Podstawowe operacje na pojedynczym elemencie to GetItem, PutItem (tworzy albo zastępuje cały element), UpdateItem (zmienia wybrane atrybuty, a gdy elementu nie ma — tworzy go, czyli upsert) i DeleteItem. Do tego operacje wsadowe (BatchGetItem, BatchWriteItem), transakcje (TransactGetItems, TransactWriteItems) i PartiQL — SQL-owa nakładka na to samo API.
Warunki i zmiany opisujesz wyrażeniami (expressions): KeyConditionExpression (który klucz), FilterExpression (co odrzucić po odczycie), ProjectionExpression (które atrybuty zwrócić), ConditionExpression (kiedy zapis ma się udać) i UpdateExpression (co zmienić). Nazwy i wartości podstawiasz przez ExpressionAttributeNames (#n, np. dla słów zastrzeżonych jak status) i ExpressionAttributeValues (:v).
1.3.31.3.51.3.6
- Query wymaga równości na partition key, czyta jedną kolekcję elementów; Scan czyta całą tabelę. Gdy da się zrobić Query (ewentualnie na indeksie) — rób Query.
- Jedno wywołanie Query/Scan zwraca najwyżej 1 MB danych (limit liczony przed filtrem); kolejna strona:
LastEvaluatedKey→ExclusiveStartKey. FilterExpressioniProjectionExpressionnie zmniejszają zużycia RCU.- Szybszy Scan dużej tabeli: parallel scan (
Segment+TotalSegments); łagodniejszy dla tabeli: mniejszyLimiti pauzy. - Zapobieganie nadpisaniu:
ConditionExpressionzattribute_not_exists(pk); współbieżne aktualizacje: optimistic locking z atrybutem wersji; licznik: atomic counter (SET n = n + :inc). BatchWriteItem: do 25 Put/Delete (bez Update), nie jest atomowy, zwracaUnprocessedItems. Transakcje: do 100 elementów, 4 MB, wszystko albo nic, koszt 2×.
Query i Scan w szczegółach
| Cecha | Query | Scan |
|---|---|---|
| Co czyta | Elementy z jedną wartością partition key (opcjonalnie zakres sort key) | Każdy element tabeli lub indeksu |
| Warunek klucza | KeyConditionExpression: PK tylko =; SK: = < <= > >=, BETWEEN, begins_with | Brak; filtr może dotyczyć dowolnych atrybutów, także kluczy |
| Kolejność | Posortowane po SK; rosnąco domyślnie, malejąco: ScanIndexForward=false | Brak gwarancji kolejności |
| Limit strony | 1 MB na wywołanie (przed filtrem); Limit = maks. liczba ocenionych elementów (też przed filtrem); kontynuacja przez LastEvaluatedKey | |
| Spójność | Domyślnie eventual; ConsistentRead=true dla tabeli i LSI (nie dla GSI) | |
| Koszt | Suma rozmiarów przeczytanych elementów kolekcji | Suma rozmiarów wszystkich przeczytanych elementów |
| Liczniki | ScannedCount = ocenione przed filtrem; Count = po filtrze. Duży ScannedCount przy małym Count = marnotrawstwo. | |
W Query filtr nie może dotyczyć atrybutów klucza (od tego jest KeyConditionExpression). Select=COUNT zwraca tylko liczbę elementów — przydatne, ale RCU są takie same. SDK mają paginatory (np. get_paginator('query') w boto3), które same przekazują LastEvaluatedKey; więcej o stronicowaniu w rozdziale o SDK.
# boto3 — Query z ręcznym stronicowaniem
kwargs = dict(TableName="Orders",
KeyConditionExpression="pk = :u AND begins_with(sk, :p)",
FilterExpression="#s = :st", # status to słowo zastrzeżone
ExpressionAttributeNames={"#s": "status"},
ExpressionAttributeValues={":u": {"S": "USER#2"}, ":p": {"S": "ORDER#"},
":st": {"S": "SHIPPED"}},
ProjectionExpression="sk, total")
while True:
page = ddb.query(**kwargs)
handle(page["Items"])
if "LastEvaluatedKey" not in page: break
kwargs["ExclusiveStartKey"] = page["LastEvaluatedKey"]
Parallel scan: każdy wątek/worker wywołuje Scan z tym samym TotalSegments i innym Segment (0 … N−1). Skraca czas, ale zjada pojemność szybciej — przy dużym Scanie na produkcyjnej tabeli rozważ mniejszy Limit, osobną tabelę/indeks albo eksport do S3 (bez zużycia RCU, rozdział 14).
Zapisy warunkowe, optimistic locking i liczniki
| Technika | Co robi | Kiedy |
|---|---|---|
ConditionExpression + attribute_not_exists(pk) | Put udaje się tylko, jeśli elementu o tym kluczu nie ma; inaczej ConditionalCheckFailedException (i zużyte WCU). | „Nie nadpisuj istniejącego użytkownika”, idempotentne tworzenie. |
Optimistic locking (atrybut version) | Czytasz element z wersją N; zapisujesz z warunkiem version = N i ustawiasz N+1. Jeśli ktoś cię uprzedził — warunek nie przejdzie, czytasz ponownie. W Javie robi to adnotacja @DynamoDBVersionAttribute. | Dwóch użytkowników edytuje ten sam dokument; „lost update”. |
| Atomic counter | UpdateItem z SET views = views + :one (albo ADD) — zwiększa bez odczytu, bez konfliktów. Nie jest idempotentny: ponowienie po timeoutcie może policzyć dwa razy. | Liczniki odsłon, polubień; nie dla pieniędzy. |
Warunek na wartości (balance >= :amt) | Zapis tylko przy spełnionej regule biznesowej. | Nie dopuść do ujemnego salda. |
# Optimistic locking ręcznie (AWS CLI)
aws dynamodb update-item --table-name Docs \
--key '{"pk":{"S":"DOC#7"}}' \
--update-expression "SET body = :b, version = version + :one" \
--condition-expression "version = :expected" \
--expression-attribute-values '{":b":{"S":"nowa treść"},":one":{"N":"1"},":expected":{"N":"3"}}' \
--return-values UPDATED_NEW
UpdateExpression ma cztery klauzule: SET (ustaw/zwiększ, list_append, if_not_exists), REMOVE (usuń atrybut), ADD (dodaj do liczby lub zbioru), DELETE (usuń wartości ze zbioru).
ReturnValues | Co zwraca | Gdzie |
|---|---|---|
NONE (domyślnie) | Nic | Put, Update, Delete |
ALL_OLD | Cały element sprzed zmiany | Put, Update, Delete |
UPDATED_OLD / UPDATED_NEW | Tylko zmienione atrybuty przed / po | Update |
ALL_NEW | Cały element po zmianie | Update |
Gdy zapis warunkowy się nie uda, ReturnValuesOnConditionCheckFailure=ALL_OLD zwraca aktualny element w wyjątku — bez dodatkowego GetItem.
Operacje wsadowe i transakcje
| Operacja | Limity | Semantyka |
|---|---|---|
BatchGetItem | do 100 elementów, do 16 MB, wiele tabel | Każdy element jak osobny GetItem; nieprzetworzone wracają w UnprocessedKeys. |
BatchWriteItem | do 25 Put/Delete, do 16 MB, wiele tabel | Bez Update i bez warunków; każdy Put/Delete atomowy osobno, całość nie; nieprzetworzone w UnprocessedItems. |
TransactWriteItems | do 100 akcji (Put, Update, Delete, ConditionCheck) na różnych elementach, do 4 MB, jedno konto i region | ACID, wszystko albo nic; 2 WCU / 1 KB; konflikt → TransactionCanceledException. |
TransactGetItems | do 100 elementów, 4 MB | Spójny obraz kilku elementów; 2 RCU / 4 KB. |
UnprocessedItems/UnprocessedKeys ponawiasz z exponential backoff — natychmiastowe ponowienie zwykle znowu trafi w throttling. W starszych pytaniach spotkasz limit transakcji 25 elementów; obecnie dokumentacja podaje 100 unikalnych elementów i 4 MB. Transakcja nie może dwa razy dotknąć tego samego elementu, a w global tables gwarancje ACID obowiązują tylko w regionie, w którym nastąpił zapis.
Idempotencja transakcji: ClientRequestToken sprawia, że powtórzone TransactWriteItems (np. po timeoutcie sieci) nie wykona się drugi raz. Token jest ważny 10 minut; ten sam token z innymi parametrami daje IdempotentParameterMismatch.
{ "TransactItems": [
{ "Update": { "TableName": "Accounts", "Key": {"pk": {"S": "ACC#1"}},
"UpdateExpression": "SET balance = balance - :a",
"ConditionExpression": "balance >= :a",
"ExpressionAttributeValues": {":a": {"N": "100"}} } },
{ "Update": { "TableName": "Accounts", "Key": {"pk": {"S": "ACC#2"}},
"UpdateExpression": "SET balance = balance + :a",
"ExpressionAttributeValues": {":a": {"N": "100"}} } } ],
"ClientRequestToken": "transfer-2024-07-09-0001" }
PartiQL
PartiQL to SQL-owa składnia do DynamoDB: ExecuteStatement (jedno polecenie), BatchExecuteStatement (wsad) i ExecuteTransaction (transakcja). Pod spodem działa to samo API, z tymi samymi kosztami. SELECT bez warunku równości (lub IN) na partition key w WHERE zamienia się w pełny Scan; politykę IAM można ustawić tak, żeby takie zapytania były zabronione.
SELECT sk, total FROM "Orders" WHERE pk = 'USER#2' AND begins_with(sk, 'ORDER#') -- Query
SELECT * FROM "Orders" WHERE total > 100 -- pełny Scan!
- „Dodaj FilterExpression, żeby zmniejszyć zużycie RCU” — filtr działa po odczycie; RCU bez zmian. Zmniejsza je tylko lepszy klucz/indeks (Query zamiast Scan).
- „ProjectionExpression obniży koszt” — obniża transfer, nie RCU.
- Parallel scan „dla oszczędności” — jest szybszy, nie tańszy; może wręcz zdławić tabelę.
- BatchWriteItem z UpdateItem — nie istnieje; Batch to tylko Put i Delete. Aktualizacje wielu elementów atomowo →
TransactWriteItems. - Atomic counter do salda konta — ponowienie może zdublować operację; użyj zapisu warunkowego lub transakcji z
ClientRequestToken. Limit= liczba zwróconych elementów — to liczba ocenionych przed filtrem; z filtrem możesz dostać mniej (nawet 0) i wciąż miećLastEvaluatedKey.- Pusty wynik = koniec danych — koniec jest dopiero wtedy, gdy w odpowiedzi nie ma
LastEvaluatedKey.
Raport nocny robi Scan tabeli 200 GB i trwa za długo. Tabela ma zapas pojemności w nocy. Jak skrócić czas przy najmniejszych zmianach w kodzie?
Scan dużej tabeli · szybciej · zapas pojemności
Odpowiedź
Parallel scan z TotalSegments = N i workerami po jednym Segment.
Dlatego nie: FilterExpression (nie przyspiesza odczytu), większy Limit (strona i tak max 1 MB), strongly consistent reads (wolniej i drożej).
Dwóch pracowników jednocześnie edytuje ten sam rekord klienta; zmiany jednego znikają. Jak temu zapobiec w DynamoDB bez blokad?
lost update · bez blokad
Odpowiedź
Optimistic locking: atrybut wersji + ConditionExpression „version = oczekiwana”. Przegrany dostaje ConditionalCheckFailedException i czyta ponownie.
Dlatego nie: strongly consistent read (nie chroni zapisu), transakcja na jednym elemencie bez warunku (nie wykrywa konfliktu), DAX (cache).
Przelew musi jednocześnie zmniejszyć saldo konta A i zwiększyć saldo konta B (różne elementy), a przy braku środków nie zmienić niczego. Którego API użyć?
wszystko albo nic · wiele elementów · warunek
Odpowiedź
TransactWriteItems z warunkiem balance >= :a na koncie A.
Dlatego nie: BatchWriteItem (nieatomowy, bez Update i warunków), dwa UpdateItem (brak atomowości), Streams + Lambda (asynchronicznie).
BatchWriteItem z 25 elementami zwraca sukces HTTP 200, ale 6 elementów nie zostało zapisanych. Co powinien zrobić kod?
200 OK, ale część nie zapisana
Odpowiedź
Odczytać UnprocessedItems i ponowić je z exponential backoff.
Dlatego nie: ponowić cały wsad natychmiast (duplikuje pracę, znowu throttling), zmienić na transakcję (inna semantyka, 2× koszt), zignorować.
Funkcja ma zwrócić nową wartość licznika zamówień po jego zwiększeniu, bez dodatkowego odczytu.
wartość po aktualizacji · jedno wywołanie
Odpowiedź
UpdateItem z SET n = n + :one i ReturnValues=UPDATED_NEW.
Dlatego nie: ALL_OLD (stara wartość), GetItem po zapisie (dodatkowe wywołanie, eventual), PutItem (zastąpi cały element).
🔬 Głębiej: snapshot Scanu, Select, transakcje a inne operacje
Scan z ConsistentRead=true gwarantuje, że zobaczysz wszystkie zapisy zakończone przed jego startem, ale nie daje izolacji migawkowej — zapisy w trakcie Scanu mogą (lub nie) się pojawić.
Select przyjmuje ALL_ATTRIBUTES, ALL_PROJECTED_ATTRIBUTES, SPECIFIC_ATTRIBUTES i COUNT. Transakcja może zostać anulowana także wtedy, gdy koliduje z inną trwającą transakcją na tym samym elemencie; metryka TransactionConflict w CloudWatch pokazuje takie konflikty.
- Query: równość na PK + warunek SK, posortowane; Scan: cała tabela. Strona = 1 MB przed filtrem; dalej
LastEvaluatedKey. - Filtr i projekcja nie obniżają RCU; parallel scan przyspiesza, nie oszczędza.
attribute_not_existsprzeciw nadpisaniu; wersja + warunek = optimistic locking; atomic counter nie jest idempotentny.- Batch: 100 Get / 25 Put-Delete, 16 MB,
Unprocessed*+ backoff. Transakcje: 100 elementów, 4 MB, 2× koszt,ClientRequestToken10 min. - PartiQL bez równości na PK = pełny Scan.
DynamoDB: indeksy, Streams, TTL, DAX i global tables
drugi klucz, dziennik zmian i pamięć podręcznaKsiążka ma jeden spis treści (klucz główny tabeli). Gdy chcesz szukać po nazwiskach bohaterów, potrzebujesz indeksu na końcu książki. LSI (local secondary index) to dodatkowy porządek wewnątrz tego samego rozdziału: ten sam partition key, inny sort key. GSI (global secondary index) to zupełnie nowy spis: dowolny partition key i sort key, przez całą tabelę — w praktyce kopia wybranych atrybutów w osobnej „tabeli”, aktualizowana asynchronicznie.
DynamoDB Streams to dziennik zmian: każdy Put, Update i Delete zostawia rekord, który może przeczytać np. Lambda (wyzwalacz, trigger). TTL to data przydatności: wpisujesz czas wygaśnięcia, a DynamoDB sam usuwa przeterminowane elementy, bez zużycia WCU. DAX to pamięć podręczna w pamięci RAM przed tabelą (mikrosekundy zamiast milisekund). Global tables to ta sama tabela w kilku regionach z zapisem w każdym z nich.
1.3.41.3.61.3.71.3.8
- LSI: tylko przy tworzeniu tabeli, ten sam partition key, strong lub eventual, limit 10 GB na wartość partition key, max 5. GSI: w dowolnym momencie, dowolne klucze, tylko eventual, własna pojemność, domyślnie do 20.
- Za mało WCU na GSI → dławione są zapisy do tabeli bazowej (back-pressure).
- Streams: rekordy przez 24 godziny, typy widoku
KEYS_ONLY,NEW_IMAGE,OLD_IMAGE,NEW_AND_OLD_IMAGES; Lambda czyta przez event source mapping. - TTL: atrybut typu Number w sekundach epoch (Unix); usuwanie „w ciągu kilku dni”, bez WCU; wygasłe, a nieusunięte elementy wciąż widać — filtruj je.
- DAX: cache dla ostatecznie spójnych odczytów DynamoDB, mikrosekundy, API zgodne z DynamoDB (minimalne zmiany w kodzie); silnie spójne odczyty idą do tabeli.
- PITR: odtworzenie do dowolnej sekundy z ostatnich do 35 dni, zawsze do nowej tabeli. Eksport do S3 nie zużywa RCU.
GSI
LSI
LSI kontra GSI
| Cecha | GSI | LSI |
|---|---|---|
| Klucz | Dowolny PK (+ opcjonalny SK), z atrybutów S/N/B | Ten sam PK co tabela + inny SK (zawsze złożony) |
| Kiedy tworzysz | Przy tworzeniu tabeli lub później (UpdateTable); można usunąć | Tylko w CreateTable; nie dodasz ani nie usuniesz później |
| Zasięg zapytania | Cała tabela, wszystkie partycje | Jedna wartość partition key |
| Spójność | Tylko eventual | Eventual lub strong |
| Pojemność | Własna (provisioned RCU/WCU lub on-demand); zapisy do tabeli zużywają WCU indeksu | Z tabeli bazowej |
| Atrybuty spoza projekcji | Niedostępne — dostajesz tylko to, co rzutowane | Dociągane z tabeli automatycznie (dodatkowe odczyty, fetches) |
| Limit rozmiaru | Brak | 10 GB na wartość partition key (tabela + wszystkie LSI) |
| Ile na tabelę | Domyślnie 20 (quota) | 5 |
| Unikalność kluczy indeksu | Nie jest wymagana — kilka elementów może mieć tę samą wartość klucza indeksu | |
Projekcje (ProjectionType): KEYS_ONLY (klucze tabeli i indeksu — najmniejszy, najtańszy), INCLUDE (klucze + wskazane atrybuty; łącznie najwyżej 100 takich atrybutów we wszystkich indeksach tabeli), ALL (całe elementy — największa elastyczność, największy koszt zapisu i składowania). Rzutuj to, czego zapytanie potrzebuje: w GSI brakującego atrybutu nie dociągniesz.
Indeks rzadki (sparse index): GSI zawiera tylko elementy, które mają atrybut(y) klucza indeksu. Jeśli atrybut isOpen mają tylko otwarte zgłoszenia, GSI na nim to tania lista „otwartych” bez Scanu. Nowość: klucze GSI mogą być złożone z wielu atrybutów (do czterech w partition key i do czterech w sort key), zamiast ręcznie sklejanych kluczy typu TOURNAMENT#WINTER#REGION#EU.
Back-pressure GSI: indeksy aktualizują się asynchronicznie, ale jeśli GSI nie nadąża (za mało WCU, gorąca partycja indeksu — np. GSI po status z trzema wartościami), DynamoDB dławi zapisy do tabeli bazowej. Wyjątek wskazuje GSI (powód np. IndexWriteProvisionedThroughputExceeded), choć ty piszesz do tabeli. Reguła: WCU każdego GSI co najmniej takie jak zapisy, które do niego trafiają, i klucz GSI o wysokiej kardynalności.
DynamoDB Streams i Kinesis Data Streams
StreamViewType | Co trafia do rekordu | Kiedy |
|---|---|---|
KEYS_ONLY | Tylko atrybuty klucza zmienionego elementu | Wystarczy wiedzieć, co się zmieniło; dane i tak doczytasz. |
NEW_IMAGE | Cały element po zmianie | Replikacja do wyszukiwarki, cache, agregaty. |
OLD_IMAGE | Cały element przed zmianą | Archiwizacja usuniętych, audyt. |
NEW_AND_OLD_IMAGES | Oba obrazy | Diff, audyt zmian, „co dokładnie się zmieniło”. |
- Rekordy żyją 24 godziny; każdy rekord pojawia się w strumieniu dokładnie raz, w kolejności zmian danego elementu. Strumień dzieli się na shardy; na jeden shard projektuj najwyżej dwóch równoczesnych czytelników (w tabeli nie-globalnej).
- Lambda czyta strumień przez event source mapping (batch, ponowienia, bisekcja,
ReportBatchItemFailures, filtry zdarzeń) — szczegóły w rozdziale 10. - Alternatywa: Kinesis Data Streams for DynamoDB — retencja do 1 roku, więcej konsumentów (enhanced fan-out), Firehose do S3; gdy 24 h i dwóch czytelników to za mało (Kinesis).
TTL: automatyczne wygasanie
Włączasz TTL na tabeli i wskazujesz atrybut (np. expireAt) typu Number z czasem w sekundach epoch (np. 1767225600). Inny format (ISO-string, milisekundy) jest ignorowany; wartość starsza niż 5 lat w przeszłości też. Usuwanie działa w tle, zwykle w ciągu kilku dni po wygaśnięciu, i nie zużywa WCU. W starszych materiałach spotkasz „w ciągu 48 godzin” — dokumentacja mówi dziś o kilku dniach.
- Wygasłe, ale jeszcze nieusunięte elementy wciąż zwracają Get/Query/Scan i liczą się do składowania — odfiltruj je (
FilterExpression: expireAt > :now). - Usunięcie przez TTL trafia do Streams jako usunięcie serwisowe:
userIdentity.type = "Service",principalId = "dynamodb.amazonaws.com"— tak odróżnisz je od skasowania przez użytkownika (np. archiwizacja przez Lambdę do S3). - Element znika też z LSI i GSI, jak przy zwykłym Delete.
DAX kontra ElastiCache
DAX (DynamoDB Accelerator) to klaster cache w twoim VPC, zgodny z API DynamoDB: podmieniasz klienta SDK na klienta DAX i reszta kodu zostaje. Ma dwa niezależne bufory: item cache (wyniki GetItem/BatchGetItem, domyślny TTL 5 minut) i query cache (wyniki Query/Scan według parametrów). Zapisy przechodzą przez DAX do tabeli (write-through) i aktualizują item cache, ale nie unieważniają query cache.
| Opcja | Co robi | Kiedy |
|---|---|---|
| DAX | Cache tylko dla DynamoDB; eventual reads z mikrosekundowym czasem; strongly consistent i TransactGetItems przekazuje do tabeli bez cache'owania. | „Read-heavy DynamoDB, mikrosekundy, minimalne zmiany kodu”, gorące klucze odczytu. |
| ElastiCache (Valkey/Redis OSS/Memcached) | Cache ogólnego przeznaczenia; ty decydujesz, co i jak cache'ujesz (wyniki obliczeń, sesje, rankingi). | Cache dla RDS, agregaty, sesje, struktury danych; rozdział 18. |
Global tables, kopie zapasowe, eksport
- Global tables (wersja 2019.11.21, Current): repliki w wielu regionach, zapis w każdym (active-active). Domyślnie MREC (multi-Region eventual consistency): replikacja asynchroniczna, zwykle w ciągu sekundy, konflikty rozstrzyga last writer wins. Opcjonalnie MRSC (multi-Region strong consistency) — silnie spójne odczyty między regionami; równoległy zapis tego samego elementu w innym regionie kończy się
ReplicatedWriteConflictException(można ponowić). Transakcje są ACID tylko w regionie zapisu. - On-demand backup: pełna kopia na żądanie (DynamoDB albo AWS Backup), bez wpływu na wydajność i dostępność tabeli.
- PITR (point-in-time recovery): ciągłe kopie, odtworzenie do dowolnej sekundy z okresu 1–35 dni (domyślnie 35); odtwarzasz zawsze do nowej tabeli (także w innym regionie).
- Export to S3: z dowolnego momentu w oknie PITR (więc PITR musi być włączony), pełny lub przyrostowy, format DynamoDB JSON lub Amazon Ion, bez zużycia RCU — potem Athena po stronie S3.
- Import from S3: CSV, DynamoDB JSON lub Ion (także GZIP/ZSTD) do nowej tabeli, bez zużycia WCU.
Dostęp na poziomie elementów i atrybutów
Polityka IAM może ograniczyć użytkownika do elementów, których partition key równa się jego identyfikatorowi: warunek dynamodb:LeadingKeys (z modyfikatorem ForAllValues) i zmienna polityki, np. ${cognito-identity.amazonaws.com:sub} dla tożsamości z Cognito identity pool. dynamodb:Attributes ogranicza widoczne atrybuty (najwyższego poziomu), a dynamodb:Select i dynamodb:ReturnValues domykają furtki (odczyt bez projekcji zwróciłby wszystko). Pełny wzorzec multi-tenant: rozdział 31, tożsamości: Cognito.
{ "Effect": "Allow",
"Action": ["dynamodb:GetItem", "dynamodb:Query", "dynamodb:PutItem", "dynamodb:UpdateItem"],
"Resource": "arn:aws:dynamodb:*:*:table/GameScores",
"Condition": { "ForAllValues:StringEquals": {
"dynamodb:LeadingKeys": ["${cognito-identity.amazonaws.com:sub}"] } } }
- „Dodaj LSI do istniejącej tabeli” — niemożliwe; LSI tylko przy
CreateTable. Na istniejącej tabeli: GSI (albo nowa tabela i migracja). - „Strongly consistent read z GSI” — GSI obsługuje tylko eventual; potrzebujesz strong → LSI albo tabela.
- Throttling tabeli przy wolnych WCU tabeli — sprawdź WCU i klucz GSI (back-pressure), nie tylko tabelę.
- „TTL usuwa dokładnie o czasie” — usuwa w ciągu dni; aplikacja musi filtrować wygasłe.
- TTL w milisekundach lub jako string ISO — ignorowany; musi być Number w sekundach epoch.
- DAX dla silnie spójnych odczytów / do cache'owania RDS — DAX nie przyspiesza strong reads i działa tylko z DynamoDB.
- „Streams przechowują zmiany 7 dni” — 24 godziny; dłużej → Kinesis Data Streams for DynamoDB.
- „PITR odtwarza tabelę na miejscu” — zawsze do nowej tabeli.
Tabela Orders (PK customerId, SK orderDate) działa od roku. Teraz trzeba szybko wyszukiwać zamówienia po productId. Co zrobić?
istniejąca tabela · inny partition key
Odpowiedź
Dodać GSI z partition key productId.
Dlatego nie: LSI (tylko przy tworzeniu i z tym samym PK), Scan z filtrem (koszt całej tabeli), nowa tabela ręcznie (więcej pracy).
Po każdej zmianie ceny produktu trzeba zapisać do audytu starą i nową wartość. Jak skonfigurować strumień?
stara i nowa wartość
Odpowiedź
DynamoDB Streams z NEW_AND_OLD_IMAGES + Lambda.
Dlatego nie: KEYS_ONLY/NEW_IMAGE (brak starej wartości), CloudTrail (rejestruje wywołania API, nie przetwarza zmian elementów), Scan porównujący snapshoty.
Sesje użytkowników w DynamoDB mają wygasać po 24 godzinach bez dodatkowego kodu i kosztów zapisu. Co robisz?
automatyczne wygasanie · bez WCU
Odpowiedź
Włączyć TTL na atrybucie expireAt (Number, sekundy epoch = teraz + 86 400) i filtrować wygasłe przy odczycie.
Dlatego nie: Lambda z crona robiąca Scan + Delete (koszt RCU/WCU, kod), Streams (nie usuwa), DAX TTL (dotyczy cache, nie tabeli).
Aplikacja gamingowa robi miliony powtarzalnych odczytów tych samych elementów DynamoDB i potrzebuje odpowiedzi w mikrosekundach. Zespół chce minimalnych zmian w kodzie.
mikrosekundy · DynamoDB · minimalne zmiany
Odpowiedź
DAX. API-kompatybilny klient, item cache.
Dlatego nie: ElastiCache (trzeba napisać logikę cache), więcej RCU (wciąż milisekundy), GSI (nie przyspiesza odczytu).
Po błędnym wdrożeniu skrypt nadpisał dane 2 godziny temu. Jak odzyskać stan sprzed incydentu z najmniejszą utratą danych?
konkretny moment · ostatnie godziny
Odpowiedź
PITR — odtworzenie do sekundy przed incydentem do nowej tabeli, potem przełączenie aplikacji lub skopiowanie danych.
Dlatego nie: on-demand backup (tylko jeśli zrobiony tuż przed), Streams (24 h, ale trzeba by odtwarzać ręcznie), eksport do S3 (nie odtwarza tabeli).
Zespół analityków chce uruchamiać zapytania SQL na pełnych danych tabeli produkcyjnej bez wpływu na jej wydajność.
analityka · bez wpływu na tabelę
Odpowiedź
Export to S3 (wymaga PITR) + Athena. Eksport nie zużywa RCU.
Dlatego nie: Scan (zużywa RCU), parallel scan (jeszcze szybciej zużywa), PartiQL SELECT bez klucza (to też Scan).
Masz GSI z partition key status (wartości: NEW, PAID, SHIPPED) i 5 000 zapisów/s do tabeli. Co się stanie z zapisami do tabeli, nawet jeśli GSI ma 10 000 WCU? Wskazówka: limit partycji 1 000 WCU dotyczy także partycji indeksu — trzy wartości klucza to w praktyce trzy gorące partycje, a back-pressure dławi tabelę.
🔬 Głębiej: tworzenie GSI na dużej tabeli, Streams i global tables, item collection
Dodanie GSI do istniejącej tabeli uruchamia backfill — DynamoDB wypełnia indeks istniejącymi elementami; na dużej tabeli trwa to długo, a indeks potrzebuje w tym czasie WCU.
Item collection to wszystkie elementy o tej samej wartości partition key w tabeli i jej LSI. Przy LSI przekroczenie 10 GB blokuje dalsze zapisy do tej kolekcji (błąd ItemCollectionSizeLimitExceededException); ReturnItemCollectionMetrics pozwala obserwować rozmiar.
W global tables usunięcie przez TTL jest identyfikowalne w Streams tylko w regionie, w którym nastąpiło; repliki widzą je jak zwykłą replikowaną zmianę. Pierwsze usunięcie TTL nie zużywa WCU, ale replikacja usunięcia do innych regionów już tak.
- LSI: przy CreateTable, ten sam PK, strong OK, 10 GB/PK, max 5. GSI: kiedykolwiek, dowolny klucz, tylko eventual, własne WCU, back-pressure.
- Projekcje: KEYS_ONLY / INCLUDE / ALL; GSI nie dociąga atrybutów; indeks rzadki = tania lista podzbioru.
- Streams: 24 h, 4 typy widoku, Lambda przez ESM; dłużej → Kinesis Data Streams for DynamoDB.
- TTL: Number, sekundy epoch, usuwanie w ciągu dni, bez WCU, w Streams jako Service.
- DAX: mikrosekundy, eventual, item cache TTL 5 min, query cache nieunieważniany. Global tables: MREC (last writer wins) / MRSC.
- PITR 35 dni → nowa tabela; eksport do S3 bez RCU; import do nowej tabeli bez WCU;
dynamodb:LeadingKeysdla izolacji użytkowników.
Amazon S3 dla dewelopera
nieskończony magazyn z kluczem do każdej szufladyS3 to przechowalnia bagażu bez limitu miejsca. Zasobnik (bucket) to przechowalnia o globalnie unikalnej nazwie w jednym regionie, obiekt (object) to walizka, a klucz (key), np. photos/2024/cat.jpg, to numer na kwicie. „Foldery” są tylko prefiksami w nazwie klucza. Każda walizka ma metadane (systemowe, jak Content-Type, i własne x-amz-meta-*) oraz opcjonalne tagi.
Od strony dewelopera S3 to API HTTP: PutObject, GetObject, HeadObject, DeleteObject, ListObjectsV2, CopyObject i multipart upload. Odczyt po zapisie jest silnie spójny (strong read-after-write consistency) we wszystkich regionach: po udanym PUT lub DELETE kolejny GET i LIST widzą zmianę.
Cała reszta rozdziału to pokrętła wokół tej przechowalni: klasy (jak szybko i jak tanio), lifecycle (automatyczne przenoszenie i kasowanie), wersjonowanie i replikacja (ochrona przed pomyłką i awarią regionu), zdarzenia (reakcja na nowe pliki), presigned URL i multipart (bezpieczny i szybki upload z klienta), wydajność, CORS i hosting stron. Bezpieczeństwo i szyfrowanie: następny rozdział.
1.3.61.3.74.3.5
- Presigned URL: czasowy dostęp do jednego obiektu (GET lub PUT) bez dawania użytkownikowi poświadczeń AWS; działa z uprawnieniami tego, kto podpisał; IAM user + SigV4 — do 7 dni, rola/STS — najwyżej do wygaśnięcia sesji.
- Multipart upload: zalecany od ok. 100 MB, wymagany powyżej 5 GB (limit pojedynczego PUT); części 5 MiB–5 GiB, max 10 000 części.
- Klasy i minimalne okresy: Standard-IA i One Zone-IA 30 dni, Glacier Instant/Flexible 90 dni, Deep Archive 180 dni; nieznany wzorzec dostępu → Intelligent-Tiering.
- Replikacja (CRR/SRR) wymaga wersjonowania w obu zasobnikach; istniejące obiekty → S3 Batch Replication.
- Zdarzenia S3 → Lambda/SQS/SNS (nie SQS FIFO) albo EventBridge (wszystkie zdarzenia, zaawansowane filtry, wiele celów).
- Wydajność: co najmniej 3 500 zapisów i 5 500 odczytów/s na prefiks — więcej prefiksów = więcej przepustowości; daleko od regionu → Transfer Acceleration.
Spójność
PUT nowego obiektu, nadpisanie i DELETE są silnie spójne — także LIST. Dwa równoczesne PUT pod ten sam klucz: wygrywa żądanie z najnowszym znacznikiem czasu; S3 nie daje blokad obiektów dla współbieżnych zapisów (jeśli to problem, zbuduj blokadę w aplikacji, np. w DynamoDB, albo użyj zapisów warunkowych). Konfiguracje zasobnika (np. włączenie wersjonowania, polityki) są ostatecznie spójne — chwilę po zmianie stara konfiguracja może jeszcze działać. W starszych materiałach spotkasz „eventual consistency dla nadpisań i DELETE” — to już nieaktualne.
Klasy składowania
| Klasa | Do czego | AZ | Min. okres | Min. rozmiar rozl. | Dostęp |
|---|---|---|---|---|---|
| S3 Standard | Często używane dane | ≥ 3 | — | — | milisekundy |
| S3 Intelligent-Tiering | Nieznany/zmienny wzorzec dostępu; automatyczne przenoszenie między warstwami; opłata za monitoring, bez opłat za pobranie; obiekty < 128 KB nie są monitorowane | ≥ 3 | — | — | ms (warstwy archiwalne opcjonalne, asynchroniczne) |
| S3 Standard-IA | Rzadko używane, ale potrzebne od ręki | ≥ 3 | 30 dni | 128 KB | ms, opłata za GB pobrania |
| S3 One Zone-IA | Dane, które da się odtworzyć (kopie, miniatury); tańsze, odporność jednej AZ | 1 | 30 dni | 128 KB | ms |
| S3 Express One Zone | Jednocyfrowe milisekundy, obciążenia wrażliwe na opóźnienie (zasobniki katalogowe) | 1 | — | — | jednocyfrowe ms |
| S3 Glacier Instant Retrieval | Archiwum czytane raz na kwartał, ale od ręki | ≥ 3 | 90 dni | 128 KB | ms |
| S3 Glacier Flexible Retrieval | Archiwum, minuty–godziny | ≥ 3 | 90 dni | — | Expedited 1–5 min, Standard 3–5 h, Bulk 5–12 h |
| S3 Glacier Deep Archive | Najtańsze, dostęp rzadziej niż raz w roku | ≥ 3 | 180 dni | — | Standard do 12 h, Bulk do 48 h |
Wszystkie obecne klasy (poza przestarzałym Reduced Redundancy Storage, 99,99%) są projektowane na 11 dziewiątek trwałości (99,999999999%); różnią się dostępnością, kosztem i czasem dostępu. Obiekt z Glacier Flexible/Deep Archive trzeba najpierw przywrócić (RestoreObject) — powstaje tymczasowa kopia. Usunięcie lub przeniesienie obiektu przed minimalnym okresem = opłata za resztę tego okresu.
Lifecycle: przenoszenie i wygasanie
| Akcja reguły | Co robi | Kiedy |
|---|---|---|
| Transition | Przenosi bieżące wersje do tańszej klasy po N dniach (tylko „w dół wodospadu”: Standard → IA → Glacier → Deep Archive) | Logi: 30 dni Standard, potem IA, po roku Glacier |
| Expiration | Usuwa bieżące wersje po N dniach (w zasobniku z wersjonowaniem dodaje delete marker) | Pliki tymczasowe, logi z retencją |
| NoncurrentVersionTransition / Expiration | To samo dla starych (niebieżących) wersji | Wersjonowanie bez rosnącego rachunku |
| AbortIncompleteMultipartUpload | Usuwa części niedokończonych uploadów po N dniach | Zawsze, gdy klienci robią multipart |
Reguły filtrujesz prefiksem, tagami i rozmiarem obiektu (ObjectSizeGreaterThan/ObjectSizeLessThan). Od września 2024 domyślnie obiekty mniejsze niż 128 KB nie są przenoszone do żadnej klasy (opłata za przejście byłaby większa niż oszczędność) — chyba że dodasz filtr rozmiaru.
Wersjonowanie i delete markers
- Stany zasobnika: bez wersjonowania → włączone → zawieszone (suspended). Po włączeniu nie wrócisz do „bez wersjonowania”, możesz tylko zawiesić.
- Obiekty sprzed włączenia mają wersję
null. Nadpisanie tworzy nową wersję; stare zostają (i kosztują). DELETEbezversionIdnie kasuje danych — dodaje delete marker; zwykły GET zwraca wtedy 404. Odzyskanie pliku = usunięcie delete markera. Trwałe usunięcie =DELETEz konkretnymversionId(opcjonalnie chronione przez MFA Delete, rozdział 16).
Replikacja
| Opcja | Co robi | Kiedy |
|---|---|---|
| CRR (Cross-Region Replication) | Asynchroniczna kopia nowych obiektów do zasobnika w innym regionie | DR, zgodność, mniejsze opóźnienie dla odległych użytkowników |
| SRR (Same-Region Replication) | Kopia w tym samym regionie (np. inne konto) | Agregacja logów, kopia produkcja → test, suwerenność danych |
| S3 RTC (Replication Time Control) | SLA: 99,9% obiektów w ciągu 15 minut, metryki i powiadomienia | Wymóg przewidywalnego czasu replikacji |
| S3 Batch Replication | Replikuje istniejące obiekty i te, których replikacja się nie udała | Replikacja włączona po fakcie |
- Wymagania: wersjonowanie w źródle i celu, rola IAM, przez którą S3 replikuje, przy innym koncie — polityka zasobnika docelowego; jeśli źródło ma Object Lock, cel też musi go mieć.
- Domyślnie (konfiguracja z
Filter) delete markery nie są replikowane — można włączyć delete marker replication. Usunięcia konkretnej wersji nigdy nie są replikowane (ochrona przed złośliwym kasowaniem). - Brak replikacji łańcuchowej: obiekty, które same są replikami z innej reguły, nie są dalej replikowane (A → B → C nie działa; do tego Batch Replication). Konfiguracje zasobnika (lifecycle, powiadomienia) też się nie replikują.
- Replikowane są obiekty zaszyfrowane SSE-S3, SSE-KMS (z dodatkową konfiguracją kluczy) i SSE-C.
Zdarzenia: S3 Event Notifications kontra EventBridge
| Opcja | Co robi | Kiedy |
|---|---|---|
| Event notifications → Lambda, SQS (standard), SNS | Wybrane typy zdarzeń (np. s3:ObjectCreated:*, s3:ObjectRemoved:*) z filtrem prefiks/sufiks; reguły nie mogą się nakładać | Prosty wyzwalacz: miniatura po uploadzie |
| Amazon EventBridge | Po włączeniu dostaje wszystkie zdarzenia zasobnika; zaawansowane filtry (metadane, rozmiar), wiele celów, archiwum i replay, cele niedostępne bezpośrednio (np. SQS FIFO, Step Functions) | Kilka konsumentów, złożone filtrowanie, FIFO, EventBridge |
Powiadomienia są dostarczane co najmniej raz (at least once), zwykle w sekundach, czasem po minucie lub dłużej — konsument musi być idempotentny. Uwaga na pętlę: Lambda wyzwalana przez upload do zasobnika X, która zapisuje wynik do tego samego zasobnika, wywoła samą siebie. Rozwiązanie: osobny zasobnik wynikowy albo prefiks wyjściowy poza filtrem. Do wysyłania jednego zdarzenia do wielu kolejek: S3 → SNS → wiele SQS (fan-out) albo EventBridge.
Presigned URL
Presigned URL to bilet do szatni podpisany przez ciebie: każdy, kto go ma, może do czasu wygaśnięcia wykonać tę jedną operację (GET albo PUT) na tym jednym kluczu z twoimi uprawnieniami. Klient nie potrzebuje poświadczeń AWS. Typowy wzorzec: backend (Lambda) generuje URL do PUT, przeglądarka wysyła plik prosto do S3 — bez przepychania pliku przez API Gateway (limity rozmiaru) i bez obciążania serwera.
| Kto podpisuje | Maksymalna ważność |
|---|---|
| IAM user (klucze długoterminowe), SigV4 | do 7 dni (CLI: --expires-in domyślnie 3600 s, max 604 800 s) |
| Rola IAM / poświadczenia STS (np. Lambda, EC2) | do wygaśnięcia sesji — nawet jeśli poprosisz o dłużej |
| Konsola S3 | od 1 minuty do 12 godzin |
# CLI — link do pobrania ważny 1 godzinę
aws s3 presign s3://reports/2024/q2.pdf --expires-in 3600
# Python — link do wysłania pliku (PUT)
url = s3.generate_presigned_url("put_object",
Params={"Bucket": "uploads", "Key": "u/42/avatar.png", "ContentType": "image/png"},
ExpiresIn=300)
URL przestaje działać także wtedy, gdy poświadczenia, którymi go podpisano, zostaną unieważnione lub wygasną. Jeśli podpisujący nie ma uprawnienia s3:GetObject/s3:PutObject, URL wygeneruje się bez błędu, ale żądanie dostanie 403. Wiek podpisu możesz ograniczyć w polityce zasobnika warunkiem s3:signatureAge.
Multipart, Transfer Acceleration, byte-range i prefiksy
- Multipart upload:
CreateMultipartUpload→UploadPart(części 1–10 000, równolegle, w dowolnej kolejności) →CompleteMultipartUpload(alboAbortMultipartUpload). Zalety: przepustowość (równoległość), odporność (ponawiasz tylko nieudaną część), pauza i wznowienie. Pojedynczy PUT: do 5 GB; multipart: obiekt do ok. 50 TB (48,8 TiB). Konsola wgra plik do 160 GB. Wysokopoziomoweaws s3 cpi Transfer Manager w SDK robią multipart automatycznie. - Niedokończony upload nie wygasa sam — jego części leżą i kosztują, a nie widać ich w zwykłym listingu. Lekarstwo: reguła lifecycle
AbortIncompleteMultipartUpload. - Transfer Acceleration: upload/download przez najbliższą lokalizację brzegową CloudFront i sieć AWS; endpoint
<bucket>.s3-accelerate.amazonaws.com; nazwa zasobnika bez kropek; dodatkowa opłata. Odpowiedź na „użytkownicy z innego kontynentu wysyłają duże pliki wolno”. - Byte-range fetches: nagłówek
Rangew GET pobiera fragment obiektu — równoległe pobieranie dużych plików, ponowienie tylko fragmentu, odczyt nagłówka pliku bez pobierania całości. - Prefiksy: co najmniej 3 500 PUT/COPY/POST/DELETE i 5 500 GET/HEAD na sekundę na prefiks, bez limitu liczby prefiksów. Przy przekroczeniu dostajesz 503 Slow Down — rozłóż klucze na więcej prefiksów i ponawiaj z backoffem. Dla treści czytanych masowo: CloudFront.
CORS i hosting statycznej strony
Strona z https://app.example.com pobiera skryptem pliki z https://assets.s3.amazonaws.com — to inny origin, więc przeglądarka wymaga nagłówków CORS. Konfigurację CORS ustawiasz na zasobniku, z którego pobierasz (docelowym), nie na tym, który hostuje stronę. Bez niej w konsoli przeglądarki widzisz błąd CORS, choć sam obiekt jest dostępny.
[ { "AllowedOrigins": ["https://app.example.com"],
"AllowedMethods": ["GET", "PUT"],
"AllowedHeaders": ["*"],
"ExposeHeaders": ["ETag"],
"MaxAgeSeconds": 3000 } ]
Static website hosting: włączasz na zasobniku, ustawiasz index document i error document; strona jest pod endpointem http://<bucket>.s3-website-<region>.amazonaws.com (albo s3-website.<region>). Endpoint strony nie obsługuje HTTPS — HTTPS i własna domena: CloudFront (z OAC, rozdział 27) albo Amplify Hosting. Publiczna strona wymaga zdjęcia Block Public Access i polityki zezwalającej na s3:GetObject; przy SSE-KMS potrzebujesz CloudFront.
Zapytania do danych w S3: S3 Select, Object Lambda, Athena
| Opcja | Co robi | Status / kiedy |
|---|---|---|
| Amazon Athena | Serverless SQL na plikach w S3 (CSV, JSON, Parquet, ORC), katalog w AWS Glue Data Catalog; płacisz za przeskanowane dane (min. 10 MB na zapytanie). Taniej i szybciej: partycjonowanie (np. dt=2024-07-09/), formaty kolumnowe, kompresja. | Ad-hoc SQL po logach, eksportach DynamoDB, danych z Firehose. |
| S3 Select | SQL na pojedynczym obiekcie po stronie S3 | Niedostępny dla nowych klientów; istniejący mogą używać dalej. W starszych pytaniach bywa poprawną odpowiedzią na „pobierz tylko część danych z CSV”; dziś: Athena lub byte-range. |
| S3 Object Lambda | Funkcja Lambda modyfikuje obiekt w locie przy GET (np. redakcja PII) | Od 7 listopada 2025 dostępna tylko dla dotychczasowych klientów (i wybranych partnerów). W starszych testach — odpowiedź na „różne widoki tego samego obiektu”. |
- Presigned URL z Lambdy ważny 7 dni — Lambda podpisuje poświadczeniami roli, więc link wygaśnie razem z sesją roli. 7 dni tylko dla IAM usera z SigV4.
- „Włącz replikację, a istniejące pliki się skopiują” — replikacja obejmuje nowe obiekty; istniejące → Batch Replication.
- Replikacja bez wersjonowania — niemożliwa; oba zasobniki muszą mieć wersjonowanie.
- SQS FIFO jako cel powiadomienia S3 — nieobsługiwane; użyj EventBridge.
- „DELETE w zasobniku z wersjonowaniem usuwa plik” — dodaje delete marker; dane zostają i kosztują.
- Lifecycle do One Zone-IA dla jedynej kopii ważnych danych — jedna AZ; tylko dla danych odtwarzalnych.
- CORS ustawiony na zasobniku strony — musi być na zasobniku, z którego przeglądarka pobiera zasoby.
- HTTPS na endpoincie S3 website — nieobsługiwany; CloudFront.
- Pojedynczy PUT pliku 8 GB — limit 5 GB; multipart.
Aplikacja mobilna ma pozwolić użytkownikom wysyłać zdjęcia do prywatnego zasobnika S3 bez przechodzenia przez backend i bez dawania im poświadczeń AWS.
bezpośredni upload · bez poświadczeń · prywatny zasobnik
Odpowiedź
Backend generuje presigned URL do PutObject z krótkim czasem ważności.
Dlatego nie: publiczny zapis w polityce (niebezpieczne), klucze IAM w aplikacji (wyciekną), upload przez API Gateway (limit rozmiaru payloadu, koszt).
Wysyłanie plików 3 GB z zagranicznych biur do zasobnika w eu-central-1 trwa długo i często się przerywa.
duże pliki · daleko · przerwania
Odpowiedź
Multipart upload (ponawianie części) + S3 Transfer Acceleration.
Dlatego nie: CloudFront jako cache (to dla pobierania; upload przez TA), większa instancja klienta, replikacja CRR (dotyczy kopiowania między zasobnikami).
Pliki logów są potrzebne codziennie przez 30 dni, potem sporadycznie przez rok (dostęp od ręki), potem muszą być przechowywane 7 lat najtaniej, jak się da.
wiek obiektu · przewidywalny wzorzec · najtaniej
Odpowiedź
Lifecycle: Standard → po 30 dniach Standard-IA (lub Glacier Instant Retrieval) → po roku Glacier Deep Archive → Expiration po 7 latach.
Dlatego nie: Intelligent-Tiering (dla nieznanego wzorca; tu wzorzec jest znany), One Zone-IA (jedna AZ), ręczny skrypt.
Po uploadzie obrazu trzy niezależne systemy (miniatury, moderacja, indeks wyszukiwania) muszą dostać zdarzenie; jeden z nich wymaga kolejki FIFO.
wielu konsumentów · FIFO
Odpowiedź
Włączyć EventBridge na zasobniku i trzy reguły z celami (w tym SQS FIFO).
Dlatego nie: event notification bezpośrednio do SQS FIFO (nieobsługiwane), trzy powiadomienia z tym samym filtrem (nakładające się reguły są niedozwolone).
Aplikacja zapisuje 20 000 obiektów/s pod prefiksem uploads/ i dostaje błędy 503 Slow Down.
503 · jeden prefiks · wysokie tempo
Odpowiedź
Rozłożyć klucze na wiele prefiksów (np. uploads/a1/, uploads/b7/…) i ponawiać z exponential backoff. Limit dotyczy prefiksu, nie zasobnika.
Dlatego nie: Transfer Acceleration (opóźnienie sieci, nie tempo żądań), drugi zasobnik w innym regionie (niepotrzebne), wersjonowanie.
Frontend na https://shop.example.com pobiera fonty z zasobnika S3 i dostaje błąd CORS w przeglądarce.
przeglądarka · inny origin
Odpowiedź
Dodać konfigurację CORS na zasobniku z fontami: AllowedOrigins = https://shop.example.com, AllowedMethods = GET.
Dlatego nie: polityka zasobnika (to autoryzacja, nie CORS), publiczne ACL, CORS na zasobniku strony.
- Frontend prosi API (API Gateway + Lambda) o URL dla pliku: nazwa, typ, rozmiar.
- Lambda waliduje (typ, rozmiar, użytkownik), buduje klucz
u/<userId>/<uuid>i zwraca presigned URL do PUT, ważny kilka minut. - Przeglądarka robi PUT bezpośrednio do S3 (zasobnik ma CORS dla originu aplikacji).
- Zdarzenie
s3:ObjectCreated:Putwyzwala Lambdę przetwarzającą, która zapisuje wynik pod innym prefiksem lub w innym zasobniku (bez pętli). - Lifecycle czyści
AbortIncompleteMultipartUploadi tymczasowe prefiksy.
🔬 Głębiej: Requester Pays, zapisy warunkowe, metadane, Storage Lens
Requester Pays: za transfer i żądania płaci pobierający (musi wysłać nagłówek x-amz-request-payer) — do udostępniania dużych zbiorów danych.
Zapisy warunkowe w S3: PutObject i CompleteMultipartUpload obsługują warunki (np. „zapisz tylko, jeśli klucz nie istnieje” przez If-None-Match), co pomaga przy współbieżnych zapisach.
Metryki: liczba błędów 503 w zaawansowanych metrykach S3 Storage Lens albo w logach dostępu (server access logging), które możesz analizować Atheną.
- Silna spójność read-after-write dla PUT/DELETE/LIST; konfiguracje zasobnika ostatecznie spójne.
- Klasy: IA 30 dni / 128 KB, Glacier IR i Flexible 90 dni, Deep Archive 180 dni; nieznany wzorzec → Intelligent-Tiering.
- Wersjonowanie: tylko włączone/zawieszone; DELETE = delete marker. Replikacja wymaga wersjonowania; istniejące obiekty → Batch Replication; RTC = 15 min.
- Zdarzenia at least once; FIFO i wielu konsumentów → EventBridge; uważaj na pętle.
- Presigned URL: IAM user do 7 dni, rola do końca sesji. Multipart od 100 MB, wymagany > 5 GB, części 5 MiB–5 GiB, 10 000 części.
- 3 500/5 500 żądań/s na prefiks; TA dla odległych klientów; byte-range dla równoległych pobrań; CORS na zasobniku docelowym; website bez HTTPS.
S3: szyfrowanie, polityki i blokady
kto trzyma klucz i kto otwiera drzwiSzyfrowanie to sejf, a pytanie egzaminacyjne brzmi prawie zawsze: kto trzyma klucz? Przy SSE-S3 klucze ma i obraca AWS — wygodnie i za darmo. Przy SSE-KMS kluczem jest klucz KMS: AWS szyfruje za ciebie, ale ty kontrolujesz politykę klucza, rotację i widzisz każde użycie w CloudTrail. Przy SSE-C przynosisz własny klucz w każdym żądaniu, a S3 go nie przechowuje. Przy szyfrowaniu po stronie klienta (client-side encryption) S3 dostaje już zaszyfrowane bajty i nigdy nie widzi klucza ani danych jawnych.
Szyfrowanie w spoczynku (at rest) chroni dane na dyskach, szyfrowanie w tranzycie (in transit) — po drodze (TLS/HTTPS). Od 5 stycznia 2023 każdy nowy obiekt w S3 jest szyfrowany co najmniej SSE-S3, bez dopłat; TLS wymuszasz polityką zasobnika z warunkiem aws:SecureTransport.
Drzwi do zasobnika pilnują: polityka zasobnika (bucket policy, polityka zasobu), polityki IAM tożsamości, Block Public Access (bezpiecznik nad wszystkim, co publiczne), Object Ownership (wyłączone ACL), access points (osobne „wejścia” z własnymi politykami) oraz Object Lock i MFA Delete przeciw kasowaniu. Logika oceny polityk (explicit deny wygrywa) jest w rozdziale o IAM.
2.2.12.2.32.1.5
- „Audyt użycia klucza / kontrola rotacji i dostępu do klucza” → SSE-KMS (klucz zarządzany przez klienta, customer managed key). „Najmniejszy wysiłek, bez kosztów” → SSE-S3. „Własny klucz spoza AWS, S3 szyfruje” → SSE-C. „Dane zaszyfrowane, zanim opuszczą aplikację” → client-side. „Dwie warstwy szyfrowania (compliance)” → DSSE-KMS.
- SSE-KMS przy dużym ruchu: każde żądanie to wywołanie KMS (
GenerateDataKey/Decrypt) → limity KMS i koszt; S3 Bucket Keys obniżają liczbę wywołań KMS nawet o 99%. - SSE-C: nagłówki
x-amz-server-side-encryption-customer-algorithm,-key,-key-MD5; tylko HTTPS; od kwietnia 2026 SSE-C jest domyślnie zablokowane w nowych zasobnikach. - Wymuszenie HTTPS:
Denyz"Bool": {"aws:SecureTransport": "false"}. Wymuszenie konkretnego szyfrowania:Denyz warunkiem nas3:x-amz-server-side-encryption. - Ochrona przed usunięciem/nadpisaniem (WORM, regulacje) → Object Lock (compliance mode: nawet root nie skasuje). Dodatkowe potwierdzenie trwałego kasowania → MFA Delete.
s3:x-amz-server-side-encryption); nie zakładamy tu dodatkowych warunków typu Null.Opcje szyfrowania w spoczynku
| Opcja | Co robi | Kiedy |
|---|---|---|
SSE-S3 (x-amz-server-side-encryption: AES256) | S3 szyfruje AES-256 kluczami, którymi sam zarządza; domyślne dla każdego zasobnika; bez opłat | Wymóg „szyfrowanie w spoczynku” bez dalszych warunków |
SSE-KMS (aws:kms + opcjonalnie x-amz-server-side-encryption-aws-kms-key-id, -context) | Klucz danych z KMS; klucz AWS managed (aws/s3) albo customer managed; użycie w CloudTrail; zapis wymaga kms:GenerateDataKey, odczyt kms:Decrypt | Kontrola i audyt klucza, rozdział obowiązków, dostęp między kontami (tylko customer managed key) |
DSSE-KMS (aws:kms:dsse) | Dwie niezależne warstwy AES-256 z kluczami KMS | Regulacje wymagające wielowarstwowego szyfrowania |
| SSE-C | Klucz (256-bit) przesyłasz w każdym PUT i GET; S3 szyfruje i odrzuca klucz, trzyma tylko solony HMAC do weryfikacji; tylko HTTPS; brak obsługi w konsoli; zgubiony klucz = utracone dane | Klucze muszą pozostać poza AWS, ale szyfrować ma S3 |
| Client-side encryption | Szyfrujesz przed wysłaniem (Amazon S3 Encryption Client, często z kluczem KMS); S3 przechowuje szyfrogram | „S3/AWS nie może zobaczyć danych jawnych”, szyfrowanie end-to-end |
- Default encryption zasobnika ustawiasz na SSE-S3, SSE-KMS lub DSSE-KMS. Zmiana domyślnego szyfrowania nie zmienia istniejących obiektów — trzeba je skopiować (np.
CopyObjectlub S3 Batch Operations). - S3 Bucket Keys: S3 pobiera z KMS krótkotrwały klucz na poziomie zasobnika i z niego wyprowadza klucze danych — mniej wywołań
GenerateDataKey/Decrypt, koszt KMS niższy nawet o 99%. Kontekst szyfrowania staje się ARN-em zasobnika, nie obiektu — polityki oparte na ARN obiektu w kontekście przestają działać. - Limity KMS: operacje kryptograficzne na kluczach symetrycznych mają wspólny limit na konto i region — 10 000, 20 000 albo 100 000 żądań/s zależnie od regionu. Przy przekroczeniu S3 zwraca błąd throttlingu z KMS. Rozwiązania: Bucket Keys, podniesienie limitu (Service Quotas), backoff. W starszych testach spotkasz niższe wartości tych limitów — limity KMS rosły; zasady KMS: rozdział 29.
- Klucz
aws/s3(AWS managed) nie pozwala udostępnić obiektów innemu kontu — do cross-account potrzebny customer managed key z odpowiednią polityką klucza. - SSE szyfruje dane obiektu, nie metadane — nie wkładaj sekretów do
x-amz-meta-*.
SSE-C od kwietnia 2026: w nowych zasobnikach (i istniejących na kontach bez obiektów SSE-C) SSE-C jest domyślnie zablokowane. Aby go używać, ustawiasz w konfiguracji szyfrowania zasobnika BlockedEncryptionTypes na NONE (PutBucketEncryption). Starsze pytania zakładają, że SSE-C działa od ręki — w odpowiedziach nadal liczy się zasada „klucz klienta w nagłówkach, HTTPS, S3 nie przechowuje klucza”.
Polityki wymuszające TLS i szyfrowanie
{ "Version": "2012-10-17",
"Statement": [
{ "Sid": "DenyInsecureTransport", "Effect": "Deny", "Principal": "*",
"Action": "s3:*",
"Resource": ["arn:aws:s3:::my-bucket", "arn:aws:s3:::my-bucket/*"],
"Condition": { "Bool": { "aws:SecureTransport": "false" } } },
{ "Sid": "DenyNotSSEKMS", "Effect": "Deny", "Principal": "*",
"Action": "s3:PutObject", "Resource": "arn:aws:s3:::my-bucket/*",
"Condition": { "StringNotEquals": { "s3:x-amz-server-side-encryption": "aws:kms" } } } ] }
Druga instrukcja to klasyczny wzorzec „wymuś SSE-KMS”. Pułapka: odrzuca każde PutObject bez nagłówka — także od klientów, którzy polegają na domyślnym szyfrowaniu SSE-KMS zasobnika. Dziś prościej ustawić default encryption na SSE-KMS (i ewentualnie wymusić konkretny klucz warunkiem na s3:x-amz-server-side-encryption-aws-kms-key-id). Wariant z "Null": {"s3:x-amz-server-side-encryption-aws-kms-key-id": "true"} odrzuca żądania, które nie wskazują klucza KMS.
Dostęp publiczny, ACL i access points
| Ustawienie Block Public Access | Co robi |
|---|---|
BlockPublicAcls | Odrzuca ustawienie publicznych ACL (w PutBucketAcl, PutObjectAcl, PutObject) |
IgnorePublicAcls | Ignoruje istniejące publiczne ACL |
BlockPublicPolicy | Odrzuca polityki zasobnika/access pointa dające publiczny dostęp |
RestrictPublicBuckets | Przy publicznej polityce wpuszcza tylko principalów AWS z konta właściciela i usługi AWS |
- Nowe zasobniki, access pointy i obiekty domyślnie nie pozwalają na dostęp publiczny. BPA ustawisz na poziomie konta, zasobnika, access pointa i AWS Organizations; ustawienie bardziej restrykcyjne wygrywa. Publiczna strona WWW wymaga świadomego wyłączenia BPA (albo lepiej: CloudFront + OAC, zasobnik prywatny — rozdział 27).
- Object Ownership = Bucket owner enforced (domyślnie): ACL wyłączone, właściciel zasobnika jest właścicielem każdego obiektu, także wgranego przez inne konto. Dostęp dajesz politykami. Pozostałe tryby (Bucket owner preferred, Object writer) włączają ACL — tylko gdy naprawdę potrzebujesz uprawnień per obiekt.
- Access points: nazwane punkty dostępu do jednego zasobnika, każdy z własną polityką i ustawieniem sieci (Internet albo tylko z określonego VPC — wybierane przy tworzeniu, potem niezmienne). Upraszczają jedną gigantyczną politykę zasobnika na wiele małych (np. per zespół lub aplikacja); polityka zasobnika może delegować kontrolę dostępu do access pointów.
- Dostęp między kontami do obiektów: polityka zasobnika (zasób) zezwala kontu B, a polityka IAM w koncie B zezwala użytkownikowi — potrzebne obie. Przy SSE-KMS dochodzi polityka klucza KMS.
Object Lock i MFA Delete
| Opcja | Co robi | Kiedy |
|---|---|---|
| Object Lock — compliance mode | Wersji obiektu nie nadpisze ani nie usunie nikt, łącznie z rootem, do końca retencji; trybu nie zmienisz, retencji nie skrócisz | Regulacje (SEC 17a-4, FINRA), WORM |
| Object Lock — governance mode | Chroni przed większością użytkowników; wybrani z s3:BypassGovernanceRetention + nagłówek x-amz-bypass-governance-retention:true mogą zmienić/usunąć | Ochrona przed pomyłką z awaryjnym „wytrychem”, testy retencji |
| Legal hold | Blokada bez daty końca, do ręcznego zdjęcia; niezależna od retencji | Spór prawny, dochodzenie |
| MFA Delete | Wymaga kodu MFA do trwałego usunięcia wersji i do zmiany stanu wersjonowania; włącza tylko właściciel (root), przez CLI/API, nie konsolę | Dodatkowa ochrona przed kasowaniem wersji |
Object Lock działa tylko z włączonym wersjonowaniem i blokuje konkretne wersje obiektu.
- SSE-S3 przy wymogu audytu użycia klucza — kluczami SSE-S3 nie zarządzasz i nie widzisz ich użycia w CloudTrail; potrzebne SSE-KMS.
- SSE-C przez HTTP — S3 odrzuca; klucz wysłany jawnym tekstem uznaj za skompromitowany.
- SSE-C, „bo chcemy kontrolować klucz” — jeśli klucz może być w AWS, kontrolę i audyt daje SSE-KMS z customer managed key, bez przesyłania klucza w każdym żądaniu.
- Throttling KMS przy dużym ruchu SSE-KMS — kusi zmiana na SSE-C; właściwa odpowiedź: S3 Bucket Keys (lub podniesienie limitu KMS).
- AWS managed key
aws/s3i dostęp z innego konta — nie zadziała; customer managed key. - „Zmiana default encryption zaszyfruje stare obiekty” — dotyczy tylko nowych zapisów.
- Governance mode „chroni przed rootem” — chroni compliance mode; governance da się obejść uprawnieniem.
- MFA Delete z konsoli — włączasz przez CLI/API, jako root.
Dział bezpieczeństwa wymaga, żeby obiekty w S3 były szyfrowane kluczem, którego rotację kontroluje firma, a każde użycie klucza było widoczne w logach audytowych. Najmniej pracy?
kontrola rotacji · audyt użycia klucza · najmniej pracy
Odpowiedź
Default encryption SSE-KMS z customer managed key (z Bucket Key).
Dlatego nie: SSE-S3 (brak kontroli i audytu klucza), SSE-C (zarządzanie i przesyłanie kluczy po stronie aplikacji), client-side (najwięcej pracy).
Po przejściu na SSE-KMS aplikacja wgrywająca tysiące małych plików na sekundę dostaje błędy throttlingu, a rachunek KMS rośnie. Co zmienić?
SSE-KMS · duży wolumen · throttling KMS
Odpowiedź
Włączyć S3 Bucket Keys. Mniej wywołań KMS, niższy koszt.
Dlatego nie: SSE-C (zmienia model kluczy), wyłączenie szyfrowania (niemożliwe, SSE-S3 jest bazowe), większa liczba prefiksów (limit dotyczy KMS, nie S3).
Audyt wykazał, że część klientów łączy się z zasobnikiem przez HTTP. Jak wymusić szyfrowanie w tranzycie?
in transit · zasobnik
Odpowiedź
Polityka zasobnika z Deny dla "aws:SecureTransport": "false".
Dlatego nie: default encryption (to szyfrowanie w spoczynku), SSE-KMS (to samo), Block Public Access (dotyczy publicznego dostępu).
Firma musi przechowywać raporty finansowe przez 7 lat tak, by nikt — także administrator z kontem root — nie mógł ich usunąć ani zmienić.
nikt, także root · WORM · regulacje
Odpowiedź
S3 Object Lock w compliance mode z retencją 7 lat (wersjonowanie włączone).
Dlatego nie: governance mode (da się obejść uprawnieniem), MFA Delete (root z MFA wciąż usunie), polityka Deny (root/administrator może ją zmienić).
Trzy zespoły korzystają z jednego zasobnika danych, każdy z innymi uprawnieniami i jeden tylko z prywatnego VPC. Polityka zasobnika stała się nieczytelna.
wiele aplikacji · osobne uprawnienia · VPC
Odpowiedź
S3 Access Points — po jednym na zespół, z własną polityką; dla zespołu z VPC access point z network origin = VPC.
Dlatego nie: trzy kopie danych w trzech zasobnikach (duplikacja), ACL (wyłączone, przestarzałe), presigned URL (czasowe, per obiekt).
Klucz warunku s3:x-amz-server-side-encryption w polityce i nagłówek HTTP x-amz-server-side-encryption widoczny w CloudTrail to dwie różne nazwy tej samej informacji: pierwsza żyje w przestrzeni kluczy warunków IAM, druga w protokole HTTP.
🔬 Głębiej: kontekst szyfrowania, zewnętrzne magazyny kluczy, warunki sieciowe
SSE-KMS przekazuje do KMS kontekst szyfrowania (domyślnie ARN obiektu, a z Bucket Key — ARN zasobnika); możesz go użyć w warunkach polityki klucza. Klucze w external key store (XKS) dają kontrolę nad materiałem poza AWS, ale wtedy to ty odpowiadasz za ich dostępność.
Polityka zasobnika może ograniczać dostęp do ruchu z konkretnego VPC endpointu (aws:SourceVpce) lub VPC (aws:SourceVpc) — zobacz rozdział o VPC.
- SSE-S3 domyślnie od 01.2023; SSE-KMS = kontrola i audyt klucza (+ Bucket Keys na limity i koszt KMS); DSSE-KMS = dwie warstwy; SSE-C = klucz w nagłówkach, tylko HTTPS, od 04.2026 domyślnie zablokowane; client-side = S3 nie widzi danych jawnych.
- TLS:
Deny+aws:SecureTransport=false. Szyfrowanie:Deny+s3:x-amz-server-side-encryption(uwaga na klientów bez nagłówka). - BPA domyślnie włączone; Object Ownership = Bucket owner enforced (ACL wyłączone); access points = osobne polityki i opcjonalnie tylko-VPC.
- Object Lock (wymaga wersjonowania): compliance = nikt, governance = z uprawnieniem bypass, legal hold bez daty. MFA Delete: root, CLI/API.
RDS i Aurora: relacyjna baza bez administratora
zapasowy kierowca a dodatkowe kasyRestauracja ma jednego szefa kuchni (instancję główną, primary). Multi-AZ to zastępca stojący w drugiej kuchni (inna strefa dostępności), który robi dokładnie to samo co szef w tej samej chwili (replikacja synchroniczna) — ale nie wydaje dań gościom. Gdy szef zasłabnie, zastępca przejmuje kuchnię. Read replica to dodatkowe okienka wydawania: obsługują tylko odczyty, dostają zamówienia z lekkim opóźnieniem (replikacja asynchroniczna) i nie przejmą kuchni same.
Amazon RDS to zarządzane bazy MySQL, PostgreSQL, MariaDB, Oracle, SQL Server i Db2: AWS robi kopie zapasowe, łatki, failover. Aurora to silnik AWS zgodny z MySQL i PostgreSQL, z rozproszoną warstwą składowania (kopie danych w trzech AZ) i do 15 replik czytających z tego samego wolumenu. Aurora Serverless (dawniej „v2”) skaluje moc w jednostkach ACU w locie, nawet do zera.
Z perspektywy dewelopera najważniejsze są trzy rzeczy: jak się połączyć (endpointy), jak się uwierzytelnić bez haseł w kodzie (IAM DB auth, Secrets Manager) i jak nie zatopić bazy połączeniami z setek Lambd (RDS Proxy).
1.3.62.3.24.3.1
- Multi-AZ = wysoka dostępność (synchroniczny standby, automatyczny failover przez zmianę DNS, zwykle 60–120 s); standby w Multi-AZ DB instance nie obsługuje odczytów.
- Read replicas = skalowanie odczytów (asynchronicznie, możliwe opóźnienie, do 15 na instancję, także w innym regionie); replikę można ręcznie wypromować na samodzielną bazę (DR).
- Aurora: cluster endpoint (zapis), reader endpoint (odczyty rozkładane między repliki), custom endpoint (podzbiór instancji), instance endpoint (diagnostyka).
- IAM database authentication (MySQL, MariaDB, PostgreSQL): token zamiast hasła, ważny 15 minut, połączenie po SSL/TLS.
- Lambda + RDS i „too many connections” → RDS Proxy (pula połączeń, szybszy failover, sekrety z Secrets Manager).
Multi-AZ, Multi-AZ DB cluster i read replicas
| Opcja | Co robi | Kiedy |
|---|---|---|
| Multi-AZ DB instance | Jeden synchroniczny standby w innej AZ; nie czyta; failover automatyczny (DNS endpointu przełącza się na standby, aplikacja musi połączyć się ponownie) | „High availability”, „automatic failover” |
| Multi-AZ DB cluster | Writer + dwa czytelne standby w różnych AZ, replikacja półsynchroniczna | HA i trochę skalowania odczytów (MySQL/PostgreSQL) |
| Read replica | Asynchroniczna kopia tylko do odczytu; do 15 na instancję źródłową; w tym samym lub innym regionie; możliwa promocja do samodzielnej bazy | Skalowanie odczytów, raporty, DR między regionami |
| Automated backups | Codzienny snapshot + logi transakcji; przywrócenie do dowolnego punktu w okresie retencji 0–35 dni (0 wyłącza; domyślnie 7 dni w konsoli, 1 dzień w API/CLI) | Pomyłka w danych, odtworzenie do nowej instancji |
Aplikacja używa jednego endpointu bazy — po failoverze nazwa zostaje, zmienia się adres za nią. Dlatego klient z długim cache DNS (np. JVM) może łączyć się ze starym adresem; ustaw krótki TTL DNS. Odczyty z repliki mogą być nieaktualne (replica lag) — „read-after-write” kieruj na primary.
Aurora
- Wolumen klastra (cluster volume) trzyma kopie danych w trzech AZ i rośnie automatycznie (do 256 TiB w nowszych wersjach). Repliki Aurora (do 15) czytają ten sam wolumen; opóźnienie zwykle znacznie poniżej 100 ms.
- Gdy writer pada, Aurora promuje jedną z replik (failover) — repliki są jednocześnie skalowaniem odczytów i zapasem.
- Endpointy: cluster (writer) endpoint — zapisy, DDL; reader endpoint — odczyty, Aurora rozkłada połączenia między repliki; custom endpoint — wybrany podzbiór instancji (np. większe repliki dla raportów); instance endpoint — konkretna instancja (diagnostyka, strojenie).
- Aurora Serverless: pojemność w ACU (ok. 2 GiB RAM + CPU + sieć), zakres od 0 do 256 ACU, skok co 0,5 ACU; przy minimum 0 ACU instancja automatycznie się pauzuje bez połączeń. Dla zmiennego lub nieznanego ruchu, środowisk dev/test, wielu najemców. W starszych pytaniach spotkasz „Aurora Serverless v1” (skalowanie skokowe, pauza) — dokumentacja mówi dziś po prostu o Aurora serverless (dawne v2).
Uwierzytelnianie: IAM DB auth i Secrets Manager
IAM database authentication (MariaDB, MySQL, PostgreSQL): aplikacja z rolą IAM generuje token uwierzytelniający podpisany SigV4 (ważny 15 minut) i używa go zamiast hasła; ruch musi być szyfrowany SSL/TLS. Rola potrzebuje akcji rds-db:connect na zasobie użytkownika bazy. Zalety: brak haseł w kodzie, centralne zarządzanie w IAM.
TOKEN=$(aws rds generate-db-auth-token --hostname mydb.xxxx.eu-central-1.rds.amazonaws.com \
--port 3306 --username app_user --region eu-central-1)
mysql --host=mydb.xxxx.eu-central-1.rds.amazonaws.com --user=app_user \
--password="$TOKEN" --ssl-ca=global-bundle.pem --enable-cleartext-plugin
Secrets Manager: RDS może sam zarządzać hasłem głównego użytkownika w Secrets Manager (--manage-master-user-password) i rotować je co 7 dni domyślnie, bez zmian w aplikacji, o ile ta pobiera sekret w runtime (np. przez Lambda extension z cache). Porównanie z Parameter Store i rotacja: rozdział 30.
RDS Proxy i Lambda
Każde środowisko wykonawcze Lambdy otwiera własne połączenie. Przy skoku ruchu setki środowisk = setki połączeń i „too many connections”. RDS Proxy trzyma pulę połączeń do bazy i dzieli ją między klientów, kolejkuje lub dławi nadmiar zamiast przewracać bazę, a przy failoverze sam łączy się ze standby — aplikacja widzi krótszą przerwę.
- Proxy działa w tym samym VPC co baza i nie jest publicznie dostępny; Lambda musi być w VPC (VPC, konfiguracja Lambdy).
- Klienci uwierzytelniają się do proxy przez IAM albo poświadczenia z Secrets Manager (do 200 sekretów na proxy); proxy łączy się z bazą poświadczeniami z Secrets Manager (lub IAM).
- Wzorzec w Lambdzie: połączenie (do proxy) tworzone poza handlerem, żeby kolejne wywołania w tym samym środowisku je reużywały (model wykonania).
- „Multi-AZ, żeby odciążyć odczyty” — standby w Multi-AZ DB instance nie przyjmuje ruchu; do odczytów read replicas (albo Multi-AZ DB cluster / Aurora).
- „Read replica zapewni automatyczny failover” — w RDS replikę promujesz ręcznie; automatyczny failover daje Multi-AZ (w Aurorze — repliki).
- Read-after-write z repliki — replikacja asynchroniczna; świeże dane czytaj z primary/writer endpoint.
- Zapis na reader endpoint Aurory — repliki są tylko do odczytu; zapisy na cluster endpoint.
- Token IAM DB auth jak hasło długoterminowe — ważny 15 minut; generuj przy nawiązywaniu połączenia.
- Więcej pamięci Lambdy na „too many connections” — problem to liczba połączeń; RDS Proxy (i ewentualnie reserved concurrency).
- Hasło DB w zmiennej środowiskowej Lambdy — działa, ale „najbezpieczniej + rotacja” = Secrets Manager.
Aplikacja e-commerce na RDS MySQL ma wolne raporty, które obciążają bazę w godzinach szczytu i spowalniają zamówienia. Co zrobić?
odczyty obciążają primary · raporty
Odpowiedź
Utworzyć read replica i kierować na nią zapytania raportowe.
Dlatego nie: Multi-AZ (standby nie czyta), większa instancja (droższe, nie rozdziela ruchu), ElastiCache (raporty ad hoc słabo się cache'ują).
Baza RDS musi przetrwać awarię strefy dostępności z automatycznym przełączeniem i bez utraty zatwierdzonych transakcji.
awaria AZ · automatycznie · bez utraty danych
Odpowiedź
Multi-AZ deployment (synchroniczny standby).
Dlatego nie: read replica (asynchroniczna, ręczna promocja), snapshoty (odtworzenie trwa, utrata danych od snapshotu), cross-Region replica (inny problem: DR regionu).
Funkcje Lambda przy skokach ruchu powodują błędy „too many connections” w Aurora PostgreSQL.
Lambda · połączenia · skoki
Odpowiedź
RDS Proxy między Lambdą a Aurorą.
Dlatego nie: zwiększenie max_connections (przesuwa problem), DAX (tylko DynamoDB), SQS przed bazą (zmienia architekturę, nie rozwiązuje odczytów synchronicznych).
Zespół chce, żeby aplikacja na EC2 łączyła się z RDS PostgreSQL bez przechowywania hasła, korzystając z roli instancji.
bez hasła · rola IAM
Odpowiedź
IAM database authentication — rds-db:connect w roli, token z generate-db-auth-token, połączenie TLS.
Dlatego nie: hasło w Parameter Store (wciąż hasło), Secrets Manager (dobre, ale wciąż hasło — pytanie mówi „bez hasła”), klucze dostępowe IAM w pliku.
Aplikacja dev/test na Aurorze jest używana kilka godzin dziennie, w nocy wcale. Jak minimalizować koszt bez zarządzania instancjami?
nieregularny ruch · bezczynność · koszt
Odpowiedź
Aurora Serverless z minimalną pojemnością 0 ACU (auto-pause).
Dlatego nie: provisioned z read replicas (płacisz cały czas), ręczne zatrzymywanie (praca operacyjna), Multi-AZ (HA, nie oszczędność).
🔬 Głębiej: replika w innym regionie, Aurora Global Database, opłaty
Cross-Region read replica daje bazę gotową do promocji w innym regionie (DR) i niższe opóźnienie odczytów dla odległych użytkowników. Aurora ma do tego Aurora Global Database (klastry w wielu regionach, jeden region główny przyjmujący zapisy, automatyczna synchronizacja zmian).
Read replica jest rozliczana jak zwykła instancja; za transfer danych replikacji między źródłem a repliką w tym samym regionie nie płacisz.
- Multi-AZ = HA: synchroniczny standby, automatyczny failover przez DNS (60–120 s), standby nie czyta.
- Read replicas = skalowanie odczytów: asynchronicznie, do 15, cross-Region, ręczna promocja.
- Aurora: 3 AZ, do 15 replik, writer/reader/custom/instance endpoints; Serverless 0–256 ACU z auto-pause.
- IAM DB auth: token 15 min, TLS,
rds-db:connect. Secrets Manager: rotacja (domyślnie co 7 dni dla haseł zarządzanych przez RDS). - Lambda + relacyjna baza → RDS Proxy (pula, failover, Secrets Manager/IAM, w VPC).
Cache, ElastiCache i wyspecjalizowane magazyny
ściągawka w kieszeni zamiast bibliotekiCache to ściągawka w kieszeni. Zamiast za każdym razem iść do biblioteki (bazy danych), zaglądasz do kieszeni — milisekunda zamiast spaceru. Kłopoty są dwa: ściągawka może być nieaktualna (ktoś zmienił książkę), a kieszeń ma ograniczone miejsce. Strategie cache to różne odpowiedzi na pytanie, kiedy przepisywać do ściągawki.
Lazy loading (cache-aside): najpierw zaglądasz do cache; jeśli nie ma (cache miss), czytasz z bazy i dopisujesz do cache. Write-through: przy każdym zapisie do bazy od razu aktualizujesz cache. TTL (time to live) to data ważności wpisu — po niej klucz znika i kolejny odczyt pobierze świeżą wartość.
Amazon ElastiCache to zarządzany cache w pamięci z silnikami Valkey, Redis OSS i Memcached, w wersji serverless albo jako klaster węzłów. Obok niego egzamin pyta o magazyny „do konkretnego wzorca dostępu”: OpenSearch Service (wyszukiwanie pełnotekstowe, analiza logów) i Athena (SQL na plikach w S3). Cache dla DynamoDB to DAX, cache na brzegu — CloudFront, cache odpowiedzi API — API Gateway.
1.3.81.3.94.3.6
- Lazy loading: w cache tylko to, co czytane; awaria węzła nie psuje aplikacji; wady: kara za miss (trzy podróże) i nieaktualne dane.
- Write-through: dane w cache nigdy nie są nieaktualne; wady: kara przy każdym zapisie (dwie podróże), brakujące dane po awarii/skalowaniu, cache churn (dane nigdy nieczytane).
- Najlepiej: oba + TTL — lazy loading łapie braki, write-through odświeża, TTL ogranicza nieaktualność i zapełnienie.
- Valkey/Redis OSS: struktury danych (sorted sets → rankingi), replikacja i HA (Multi-AZ), pub/sub, kopie zapasowe. Memcached: najprostszy model, wielowątkowość, skalowanie przez dodawanie węzłów, bez replikacji.
- Sesje użytkowników przy wielu instancjach aplikacji (bezstanowe serwery) → ElastiCache (albo DynamoDB), nie sticky sessions.
- Wyszukiwanie pełnotekstowe, logi, dashboardy → OpenSearch; zapytania SQL ad hoc po danych w S3 → Athena.
Lazy loading
Write-through
Strategie cache
| Strategia | Co robi | Plusy | Minusy |
|---|---|---|---|
| Lazy loading / cache-aside | GET z cache → miss → odczyt z bazy → SET do cache | Cache trzyma tylko czytane dane; awaria węzła = tylko wolniej | Miss = 3 podróże (cache, baza, zapis do cache); nieaktualne dane do czasu wygaśnięcia |
| Write-through | Zapis do bazy + zapis do cache przy każdej zmianie | Brak nieaktualnych danych; czytelnik nie płaci za miss | Każdy zapis wolniejszy (2 podróże); po awarii/dodaniu węzła brakuje danych; churn — w cache dane, których nikt nie czyta |
| TTL (dodatek do obu) | Każdy klucz wygasa po N sekundach (Valkey/Redis OSS: także milisekundy; Memcached: sekundy) | Ogranicza nieaktualność i zajętość pamięci | Za krótki TTL = dużo missów; za długi = stare dane |
# lazy loading + write-through + TTL (Python, Valkey/Redis OSS)
def get_user(uid):
v = cache.get(f"user:{uid}")
if v is not None:
return json.loads(v) # hit
row = db.query("SELECT * FROM users WHERE id=%s", uid) # miss → baza
cache.setex(f"user:{uid}", 300, json.dumps(row)) # TTL 300 s
return row
def update_user(uid, data):
db.update("users", uid, data)
cache.setex(f"user:{uid}", 300, json.dumps(data)) # write-through
Gdzie cache'ować (umiejętność 4.3.6)? Warstwy od klienta do bazy: przeglądarka (nagłówki Cache-Control), CloudFront (treść statyczna i odpowiedzi na brzegu), cache stage'u API Gateway (odpowiedzi REST API, TTL), pamięć procesu (zmienne poza handlerem Lambdy), ElastiCache (współdzielony cache aplikacji), DAX (przed DynamoDB). Im bliżej klienta, tym taniej i szybciej, ale trudniej unieważnić.
ElastiCache: silniki i tryby
| Cecha | Valkey / Redis OSS | Memcached |
|---|---|---|
| Typy danych | Złożone: string, list, set, sorted set, hash, bitmap, HyperLogLog… | Proste (klucz → wartość) |
| Replikacja i HA | Tak (repliki, automatyczny failover) | Nie |
| Partycjonowanie | Tak w trybie cluster mode enabled (shardy, online resharding) | Tak (dane rozłożone na węzły) |
| Pub/Sub | Tak | Nie |
| Kopie zapasowe / przywracanie | Tak | Tylko w ElastiCache Serverless |
| Wielowątkowość | Nie (w porównaniu silników) | Tak — duże wielordzeniowe węzły |
| Kiedy | Rankingi, sesje z HA, kolejki/liczniki, pub/sub, trwałość, Multi-AZ | Najprostszy cache obiektów, skalowanie poziome przez dodawanie/usuwanie węzłów |
- ElastiCache Serverless: cache gotowy w niecałą minutę, bez planowania pojemności — skaluje się sam według pamięci, CPU i sieci. Klaster węzłów (node-based): sam wybierasz typy i liczbę węzłów.
- Nazewnictwo: dokumentacja mówi dziś „ElastiCache (Redis OSS)” i „ElastiCache for Valkey” (otwartoźródłowy Valkey pod Linux Foundation, węzły ok. 20% tańsze niż Redis OSS); w starszych pytaniach zobaczysz „ElastiCache for Redis” — to ten sam typ odpowiedzi.
- ElastiCache działa zwykle w twoim VPC (Serverless może też mieć publiczny endpoint z IAM i TLS); dostęp kontrolujesz grupami bezpieczeństwa (VPC). Lambda łącząca się przez prywatny endpoint musi być w tym VPC.
Sesje i inne wzorce
Gdy aplikacja działa na wielu instancjach za load balancerem (albo w Lambdzie), stan sesji nie może żyć w pamięci jednej instancji. Trzymasz go w ElastiCache (szybko, TTL = czas sesji) albo w DynamoDB (trwale, TTL tabeli). Sticky sessions na ALB (rozdział 5) to obejście, które psuje rozkład obciążenia i gubi sesję przy awarii instancji. Inne klasyki: sorted set jako ranking graczy w czasie rzeczywistym, liczniki (INCR), limiter żądań, pub/sub.
Magazyny do wzorców dostępu: OpenSearch i Athena
| Opcja | Co robi | Kiedy |
|---|---|---|
| Amazon OpenSearch Service | Zarządzane klastry OpenSearch (domeny) lub OpenSearch Serverless: indeksy, wyszukiwanie pełnotekstowe, agregacje, OpenSearch Dashboards | Wyszukiwarka w aplikacji, analiza logów, monitoring w czasie rzeczywistym, clickstream |
| Amazon Athena | Serverless SQL na plikach w S3, płatność za przeskanowane dane | Zapytania ad hoc i raporty po logach/eksportach bez ładowania danych |
| DynamoDB | Klucz-wartość/dokument, przewidywalne milisekundy przy każdej skali | Znane wzorce dostępu po kluczu |
| RDS/Aurora | Relacje, JOIN-y, transakcje SQL | Złożone zapytania relacyjne, istniejące aplikacje SQL |
Typowe połączenie: DynamoDB jako źródło prawdy + wyszukiwanie pełnotekstowe w OpenSearch. Dane przenosisz zero-ETL (DynamoDB plugin dla OpenSearch Ingestion) albo samodzielnie przez DynamoDB Streams + Lambda. Pytanie „wyszukaj produkty po fragmencie opisu” to nie Scan z contains() — to OpenSearch.
- „Write-through, żeby oszczędzić pamięć cache” — odwrotnie: write-through cache'uje wszystko, co zapisane (churn); oszczędny jest lazy loading.
- „Lazy loading gwarantuje świeże dane” — nie; dodaj TTL albo write-through.
- Memcached, gdy potrzebna replikacja/Multi-AZ albo sorted sets — Memcached tego nie ma; Valkey/Redis OSS.
- DAX do cache'owania RDS — DAX tylko dla DynamoDB; dla RDS ElastiCache.
- Sticky sessions jako „rozwiązanie” sesji — działa, ale nie jest bezstanowe ani odporne; egzamin preferuje zewnętrzny magazyn sesji.
- Athena do wyszukiwarki w aplikacji — Athena to analityka ad hoc (sekundy, płatność za skan), nie niskolatencyjne wyszukiwanie; to OpenSearch.
- OpenSearch jako główna baza transakcyjna — to indeks wyszukiwania i analityki, źródło prawdy trzymaj w bazie.
Strona z profilami użytkowników czyta je z RDS miliony razy dziennie, a zmieniają się rzadko. Zespół chce odciążyć bazę i trzymać w cache tylko faktycznie czytane profile.
read-heavy · tylko czytane dane
Odpowiedź
ElastiCache z lazy loading (cache-aside) i TTL.
Dlatego nie: write-through (cache'uje też nieczytane), DAX (tylko DynamoDB), read replica (pomaga, ale pytanie mówi o cache z czytanymi danymi).
Ceny produktów muszą być w cache zawsze aktualne zaraz po zmianie, a odczyty nie mogą płacić kary za miss.
zawsze aktualne · bez kary przy odczycie
Odpowiedź
Write-through (zwykle z TTL, żeby ograniczyć churn).
Dlatego nie: sam lazy loading (nieaktualne do wygaśnięcia), krótki TTL bez write-through (dużo missów), CloudFront (cache na brzegu, inna warstwa).
Gra mobilna potrzebuje rankingu top 100 graczy aktualizowanego w czasie rzeczywistym przy dużej liczbie zapisów wyników, z wysoką dostępnością.
ranking · czas rzeczywisty · HA
Odpowiedź
ElastiCache (Valkey lub Redis OSS) — sorted sets, z replikami Multi-AZ.
Dlatego nie: Memcached (brak sorted sets i replikacji), Scan DynamoDB z sortowaniem w kodzie (koszt, opóźnienie), Athena (analityka ad hoc).
Aplikacja na kilku instancjach EC2 za ALB gubi koszyki użytkowników, gdy ALB kieruje żądanie do innej instancji. Rozwiązanie bez sticky sessions?
wiele instancji · stan sesji · bezstanowo
Odpowiedź
Przenieść sesje do ElastiCache (lub DynamoDB) z TTL.
Dlatego nie: sticky sessions (wykluczone w pytaniu, gubi sesję przy awarii), EBS współdzielony (nie tak działa), lokalne pliki.
Sklep chce wyszukiwania produktów po słowach z opisu, z tolerancją literówek i fasetami, a produkty są w DynamoDB.
pełnotekstowe · fasety · DynamoDB
Odpowiedź
Amazon OpenSearch Service zasilany z DynamoDB (zero-ETL przez OpenSearch Ingestion lub Streams + Lambda).
Dlatego nie: Scan z contains (koszt, brak rankingu trafności), GSI (dopasowanie po kluczu, nie po słowach), Athena (ad hoc SQL na S3).
🔬 Głębiej: thundering herd przy wygasaniu, eviction, cluster mode
Gdy popularny klucz wygasa, wiele żądań jednocześnie trafia na miss i uderza w bazę. Pomaga losowy rozrzut TTL (jitter), odświeżanie przed wygaśnięciem albo blokada „tylko jeden odświeża” — ta sama idea co jitter przy ponowieniach (rozdział 1).
Gdy pamięć się kończy, silnik usuwa klucze według skonfigurowanej polityki eviction (parametr maxmemory-policy). Valkey/Redis OSS w cluster mode enabled dzieli dane na shardy (skalowanie zapisu i pamięci); w trybie disabled masz jeden shard z replikami.
- Lazy loading: tylko czytane dane, odporne na awarię węzła, ale miss = 3 podróże i nieaktualność.
- Write-through: zawsze świeże, ale kara przy zapisie, brakujące dane po awarii, churn. Łącz oba + TTL.
- Valkey/Redis OSS: struktury, HA, pub/sub, backup; Memcached: prosty, wielowątkowy, bez replikacji. Serverless albo węzły.
- Sesje bezstanowej aplikacji → ElastiCache/DynamoDB. Wyszukiwanie i logi → OpenSearch; SQL ad hoc na S3 → Athena.
Integracja i zdarzenia
Kolejki, tematy, szyny zdarzeń, strumienie i maszyny stanów, czyli wszystko, czym usługi rozmawiają ze sobą asynchronicznie. Po tej części rozpoznasz, kiedy pytanie chce SQS, SNS, EventBridge, Kinesis, Step Functions albo AppSync, i znasz limity, na których opierają się odpowiedzi.
Amazon SQS: kolejka, która wybacza
wiadomość czeka, aż ktoś ją odbierze i skasujeWyobraź sobie szatnię w teatrze. Oddajesz płaszcz (producer wysyła wiadomość), szatniarz wiesza go na wieszaku (kolejka), a ktoś później go odbiera (consumer). Szatniarz nie musi wiedzieć, kto przyjdzie po płaszcz ani kiedy. Na tym polega decoupling: producent i konsument nie muszą działać w tym samym czasie ani w tym samym tempie.
Amazon SQS (Simple Queue Service) to w pełni zarządzana kolejka typu pull. Konsument sam pyta kolejkę o wiadomości (ReceiveMessage), przetwarza je i musi je jawnie skasować (DeleteMessage). SQS nie wie, czy przetwarzanie się udało. Jeśli konsument nie skasuje wiadomości, ta po pewnym czasie wróci do kolejki i ktoś odbierze ją ponownie.
Ten „pewien czas” to visibility timeout. Po odebraniu wiadomość nie znika, tylko staje się na chwilę niewidoczna dla innych konsumentów (jest „in flight”). Domyślnie trwa to 30 sekund, maksymalnie 12 godzin. Jeśli konsument w tym czasie nie zdąży jej skasować, wiadomość znów jest widoczna i trafia do kogoś innego. Dlatego SQS standard daje at-least-once delivery: ta sama wiadomość może przyjść więcej niż raz, więc przetwarzanie powinno być idempotentne.
1.1.81.1.31.1.4
- Standard: prawie nieograniczona przepustowość, at-least-once, best-effort ordering (kolejność niegwarantowana). FIFO: ścisła kolejność w obrębie
MessageGroupId, exactly-once processing (deduplikacja w oknie 5 minut), nazwa kolejki kończy się na.fifo. - Visibility timeout: domyślnie 30 s, od 0 s do 12 h. Przetwarzanie trwa dłużej niż timeout → wiadomość wraca i jest przetwarzana podwójnie. Naprawa: zwiększ timeout albo wołaj
ChangeMessageVisibilityw trakcie pracy. - Long polling (
ReceiveMessageWaitTimeSeconds/WaitTimeSeconds> 0, max 20 s) zmniejsza liczbę pustych odpowiedzi i koszt. Short polling (0 s, domyślnie) pyta tylko część serwerów i od razu odpowiada, nawet pustą odpowiedzią. - Retencja: domyślnie 4 dni, od 60 s do 14 dni. Delay: 0–15 min (delay queue dla całej kolejki albo message timer dla jednej wiadomości; FIFO ma tylko opóźnienie na poziomie kolejki).
- Rozmiar wiadomości: obecnie do 1 MiB (od sierpnia 2025). W starszych pytaniach i testach próbnych zobaczysz limit 256 KB. Większe ładunki (do 2 GB) przez SQS Extended Client Library, która trzyma treść w S3, a w kolejce tylko wskaźnik.
- DLQ +
maxReceiveCountw redrive policy izolują „trujące” wiadomości (poison pill). DLQ musi być tego samego typu (FIFO → FIFO) oraz w tym samym koncie i regionie. Redrive odsyła je z powrotem. - Batch API (
SendMessageBatch,DeleteMessageBatch,ChangeMessageVisibilityBatch) do 10 wiadomości na wywołanie: mniej wywołań, niższy koszt. - Skalowanie konsumentów EC2: Auto Scaling na podstawie głębokości kolejki (
ApproximateNumberOfMessagesVisible, a najlepiej backlog per instance). Lambda jako konsument: event source mapping.
Kolejka (source queue)
Konsumenci
DLQ (dead-letter queue)
Standard kontra FIFO
| Cecha | Standard | FIFO |
|---|---|---|
| Dostarczenie | at-least-once (czasem duplikaty) | exactly-once processing: duplikaty wysłane w ciągu 5 min są odrzucane |
| Kolejność | best-effort | ściśle FIFO w obrębie MessageGroupId; różne grupy idą równolegle |
| Przepustowość | prawie nieograniczona liczba wywołań API na sekundę | 300 wywołań/s na akcję (Send/Receive/Delete); z paczkami po 10 → 3 000 wiadomości/s. High throughput mode znacznie więcej (skaluje się partycjami) |
| Wymagane pola przy wysyłce | brak (opcjonalnie MessageGroupId → fair queues) | MessageGroupId obowiązkowe; MessageDeduplicationId albo włączone content-based deduplication |
| Opóźnienie | delay queue + message timers | tylko delay na poziomie kolejki (bez per-message timers) |
| Nazwa | dowolna | musi kończyć się .fifo; typu kolejki nie zmienisz po utworzeniu |
Deduplikacja w FIFO. Jeśli wyślesz wiadomość z tym samym MessageDeduplicationId w ciągu 5 minut, SQS przyjmie wywołanie, ale nie doda duplikatu. Zamiast podawać ID ręcznie, możesz włączyć content-based deduplication (ContentBasedDeduplication=true). Wtedy SQS liczy SHA-256 z treści (body) wiadomości, bez atrybutów. Dwie wiadomości o tej samej treści, ale różnych atrybutach, zostaną uznane za duplikat.
Grupy wiadomości. MessageGroupId działa jak osobny pas na autostradzie. Wewnątrz pasa obowiązuje kolejność, a różne pasy (np. jeden na klienta albo zamówienie) są przetwarzane równolegle przez różnych konsumentów. Jedna grupa = jeden konsument naraz, więc jeśli wszystko wyślesz z jednym ID grupy, nie zrównoleglisz przetwarzania.
High throughput FIFO włączasz atrybutami DeduplicationScope=messageGroup i FifoThroughputLimit=perMessageGroupId. Limit dotyczy wtedy grupy, nie całej kolejki, więc potrzebujesz wielu różnych MessageGroupId.
Atrybuty kolejki, które warto znać
| Opcja | Co robi | Kiedy |
|---|---|---|
VisibilityTimeout | Jak długo odebrana wiadomość jest niewidoczna. Domyślnie 30 s, 0 s – 12 h | Ustaw powyżej typowego czasu przetwarzania. Dla Lambdy: ≥ 6 × timeout funkcji (szczegóły) |
ReceiveMessageWaitTimeSeconds | Domyślny czas long pollingu, 0–20 s (0 = short polling) | Dużo pustych odpowiedzi, wysoki koszt, „reduce number of API calls” |
MessageRetentionPeriod | Jak długo SQS trzyma wiadomość: 60 s – 14 dni, domyślnie 4 dni | Konsument bywa wyłączony dłużej niż 4 dni → podnieś do 14 dni |
DelaySeconds | Delay queue: każda nowa wiadomość jest niewidoczna przez 0–900 s (15 min) | Trzeba „odczekać”, zanim konsument coś zobaczy. Dłuższe planowanie → EventBridge Scheduler |
MaximumMessageSize | Limit rozmiaru przyjmowanych wiadomości, max 1 MiB | Chcesz odrzucać za duże wiadomości |
RedrivePolicy | deadLetterTargetArn + maxReceiveCount | Wiadomości, które ciągle się nie udają, mają trafić do DLQ |
RedriveAllowPolicy | Które kolejki źródłowe mogą używać tej kolejki jako DLQ (allowAll / byQueue / denyAll) | Kontrola, kto wrzuca do Twojej DLQ |
SqsManagedSseEnabled / KmsMasterKeyId | Szyfrowanie SSE-SQS (domyślne dla nowych kolejek) albo SSE-KMS | „Audyt użycia klucza”, własny klucz KMS → SSE-KMS |
KmsDataKeyReusePeriodSeconds | Jak długo SQS używa tego samego klucza danych przed ponownym wywołaniem KMS: 60 s – 24 h, domyślnie 300 s | Za dużo wywołań KMS lub throttling KMS → wydłuż |
FifoQueue, ContentBasedDeduplication, DeduplicationScope, FifoThroughputLimit | Ustawienia FIFO opisane wyżej | Kolejność, deduplikacja, high throughput |
Kod: wysyłka, long polling, kasowanie
# Python (boto3)
sqs = boto3.client("sqs")
sqs.send_message(QueueUrl=url, MessageBody=json.dumps(order),
DelaySeconds=0, # message timer (tylko standard)
MessageAttributes={"type": {"DataType": "String", "StringValue": "order"}})
# FIFO: dodaj MessageGroupId (obowiązkowe) i MessageDeduplicationId (albo content-based dedup)
sqs.send_message(QueueUrl=fifo_url, MessageBody=body,
MessageGroupId="customer-42", MessageDeduplicationId="order-1001")
resp = sqs.receive_message(QueueUrl=url, MaxNumberOfMessages=10, # max 10 na wywołanie
WaitTimeSeconds=20, # long polling, max 20 s
VisibilityTimeout=60) # nadpisuje VT kolejki dla tych wiadomości
for m in resp.get("Messages", []):
process(m)
sqs.delete_message(QueueUrl=url, ReceiptHandle=m["ReceiptHandle"]) # bez tego wiadomość wróci
DeleteMessage i ChangeMessageVisibility przyjmują receipt handle z ostatniego odbioru, a nie MessageId. Każdy odbiór daje nowy receipt handle.
Visibility timeout w szczegółach
ChangeMessageVisibilityustawia nowy timeout liczony od chwili wywołania, nie od odbioru. Łączny limit to 12 h od pierwszego odbioru.ChangeMessageVisibilityzVisibilityTimeout=0natychmiast oddaje wiadomość innym konsumentom („nie dam rady, weź ktoś inny”).- Zmiana dotyczy tylko tego odbioru. Przy następnym odbiorze wiadomość znów dostaje timeout kolejki.
- Wiadomości „in flight” (odebrane, nieskasowane): w kolejce standard ok. 120 000. Po przekroczeniu short polling zwraca błąd
OverLimit, a long polling po prostu nic nie zwraca. Kolejka FIFO też ma limit 120 000 (w starszych materiałach: 20 000).
Dead-letter queue i redrive
DLQ to zwykła kolejka, którą wskazujesz w redrive policy kolejki źródłowej. Każdy odbiór zwiększa licznik ApproximateReceiveCount. Gdy wiadomość została odebrana maxReceiveCount razy i nadal nie jest skasowana, SQS przenosi ją do DLQ. Zbyt niskie maxReceiveCount (np. 1) wyśle do DLQ wiadomości, które padły na chwilowym błędzie.
- DLQ musi być w tym samym koncie i regionie i tego samego typu (DLQ kolejki FIFO jest FIFO, DLQ standard jest standard).
- Retencja: w kolejce standard wiadomość zachowuje pierwotny znacznik czasu dodania, więc w DLQ żyje krócej. Ustaw retencję DLQ dłuższą niż kolejki źródłowej. W FIFO znacznik zeruje się przy przeniesieniu.
- DLQ redrive (konsola albo API
StartMessageMoveTask,ListMessageMoveTasks,CancelMessageMoveTask) przenosi wiadomości z DLQ z powrotem do kolejki źródłowej lub innej kolejki tego samego typu, gdy naprawisz błąd. - Alarm CloudWatch na
ApproximateNumberOfMessagesVisiblekolejki DLQ > 0 to klasyczny sposób, by dowiedzieć się o porażkach.
Duże wiadomości, batching, purge, bezpieczeństwo
- Extended Client Library (Java, Python) zapisuje ładunek w S3 (do 2 GB) i wysyła do kolejki referencję. To typowa odpowiedź na „wiadomość większa niż limit SQS”.
- Batch: do 10 wiadomości w
SendMessageBatch/DeleteMessageBatch/ChangeMessageVisibilityBatch;ReceiveMessagezwraca max 10 (MaxNumberOfMessages). Odpowiedź batch może być częściowo udana, więc sprawdzaj listęFailed. Łączny rozmiar paczki też nie może przekroczyć limitu rozmiaru wiadomości. - Atrybuty wiadomości: do 10 na wiadomość (metadane obok treści).
PurgeQueuekasuje wszystkie wiadomości bez możliwości odzyskania. Trwa do 60 s, a kolejne wywołanie w tym czasie zwracaPurgeQueueInProgress.- Szyfrowanie: w tranzycie HTTPS. At rest SSE-SQS (klucze zarządzane przez SQS, domyślnie włączone dla nowych kolejek) albo SSE-KMS (klucz AWS managed
aws/sqslub customer managed). Producent do kolejki SSE-KMS potrzebujekms:GenerateDataKeyikms:Decrypt, konsumentkms:Decrypt. Żeby usługi AWS wysyłające do kolejki (np. SNS, EventBridge, powiadomienia S3) działały z zaszyfrowaną kolejką, utwórz customer managed key i dodaj w jego key policy uprawnienia dla principala tej usługi. - Access policy (resource-based policy kolejki): dostęp innego konta albo usługi, np.
sqs:SendMessagedlasns.amazonaws.comz warunkiemaws:SourceArn(fan-out). Wymuszenie TLS:Denyprzyaws:SecureTransport=false.
Skalowanie konsumentów
Flota EC2 czytająca z kolejki skaluje się w Auto Scaling group na podstawie długości kolejki. AWS zaleca metrykę backlog per instance (ApproximateNumberOfMessages / liczba instancji InService) z target tracking, a nie surowe ApproximateNumberOfMessagesVisible. Liczbę oczekujących wiadomości możesz policzyć metric math, bez publikowania własnej metryki. W pytaniach często wystarczy jednak odpowiedź „alarm/target tracking na ApproximateNumberOfMessagesVisible”. Elastic Beanstalk ma do tego gotowy worker environment. Lambda skaluje pollery sama (ESM).
Metryki: ApproximateNumberOfMessagesVisible (czeka), ApproximateNumberOfMessagesNotVisible (in flight), ApproximateAgeOfOldestMessage (konsumenci nie nadążają), NumberOfEmptyReceives (warto włączyć long polling).
- „Włącz FIFO, żeby uniknąć duplikatów z wolnego konsumenta” — przyczyną jest za krótki visibility timeout. Naprawa: wydłuż VT albo wołaj
ChangeMessageVisibility, i rób przetwarzanie idempotentnym. - „Ustaw
DelaySeconds, żeby konsument miał więcej czasu” — delay opóźnia pierwsze pojawienie się wiadomości. Czas na przetworzenie daje visibility timeout. - „Long polling = dłuższy visibility timeout” — to dwa różne parametry.
WaitTimeSeconds(max 20 s) mówi, jak długo czekasz na wiadomość. VT mówi, jak długo wiadomość jest ukryta po odebraniu. - „Retencja 30 dni” — maksimum to 14 dni. Dłużej przechowujesz w S3 albo DynamoDB.
- „Message timer na kolejce FIFO” — FIFO nie obsługuje opóźnień pojedynczych wiadomości, tylko delay całej kolejki.
- „Standard queue jako DLQ dla FIFO” albo DLQ w innym regionie — niedozwolone.
- „Podnieś limit rozmiaru wiadomości do 5 MB” — nie da się. Powyżej 1 MiB (dawniej 256 KB) zostaje Extended Client Library + S3.
- „FIFO 3 000 wiadomości/s bez batchingu” — 3 000 wiadomości/s to 300 wywołań × 10 wiadomości. Bez paczek i bez high throughput mode masz 300 wywołań/s.
- Content-based dedup bierze pod uwagę atrybuty — nie bierze, liczy SHA-256 tylko z body.
Aplikacja odczytuje zlecenia z SQS. Przetwarzanie zajmuje zwykle 20 s, ale czasem do 3 minut. Logi pokazują, że część zleceń jest wykonywana dwa razy. Jak to naprawić najmniejszym kosztem?
czasem dłużej, przetwarzane dwa razy
Odpowiedź
Zwiększyć visibility timeout powyżej najdłuższego czasu przetwarzania albo przedłużać go z kodu przez ChangeMessageVisibility. Wiadomość wraca, bo VT (domyślnie 30 s) wygasa w trakcie pracy.
Dlaczego nie: FIFO nie pomoże, bo duplikat powstaje po stronie odbioru. DelaySeconds opóźnia tylko pierwsze pojawienie się wiadomości. Long polling dotyczy oczekiwania na wiadomość.
Konsumenci często dostają puste odpowiedzi z ReceiveMessage, a rachunek za SQS rośnie. Co zmienić?
empty responses, reduce cost
Odpowiedź
Włączyć long polling: ReceiveMessageWaitTimeSeconds na kolejce albo WaitTimeSeconds w wywołaniu, maksymalnie 20 s.
Dlaczego nie: zwiększenie VT nie zmniejsza pustych odpowiedzi. FIFO nie ma tu znaczenia. Delay queue nawet pogorszy sytuację.
System płatności wysyła do SQS zdarzenia, które muszą być przetwarzane w kolejności dla każdego klienta, bez duplikatów, a różni klienci mają być obsługiwani równolegle. Co wybrać?
kolejność per klient, bez duplikatów, równolegle
Odpowiedź
Kolejka FIFO z MessageGroupId = ID klienta oraz deduplikacją (MessageDeduplicationId albo content-based).
Dlaczego nie: kolejka standard nie gwarantuje kolejności. Jeden wspólny MessageGroupId wymusi przetwarzanie wszystkiego seryjnie. Kinesis też zachowuje kolejność, ale nie deduplikuje i jest strumieniem, a nie kolejką zadań.
Producent musi wysyłać przez SQS dokumenty o rozmiarze do 50 MB. Jakie rozwiązanie wymaga najmniej kodu?
więcej niż limit wiadomości
Odpowiedź
Amazon SQS Extended Client Library (Java/Python): treść trafia do S3, w kolejce jest wskaźnik.
Dlaczego nie: limitu 1 MiB (w starszych pytaniach 256 KB) nie da się podnieść. Kompresja nie zagwarantuje zmieszczenia 50 MB. Dzielenie wiadomości na części wymaga więcej kodu i sklejania.
Jedna uszkodzona wiadomość w kolejce co chwilę wywala konsumenta, który ją ponawia bez końca. Jak ją odizolować i później ponownie przetworzyć po poprawce?
poison message, isolate, reprocess
Odpowiedź
DLQ z redrive policy (maxReceiveCount, np. 3–5), a po naprawie DLQ redrive (StartMessageMoveTask) do kolejki źródłowej.
Dlaczego nie: PurgeQueue kasuje wszystko. Skrócenie retencji traci dane. Ręczne kasowanie w kodzie ukrywa błąd.
Flota EC2 przetwarza wiadomości z SQS. W szczycie kolejka rośnie, a nocą instancje stoją bezczynnie. Jak skalować flotę?
scale on queue depth
Odpowiedź
Auto Scaling group z target tracking na „backlog per instance” (liczba wiadomości / instancje InService) albo na ApproximateNumberOfMessagesVisible.
Dlaczego nie: CPU nie mówi, ile pracy czeka. Scheduled scaling nie reaguje na nieprzewidziane szczyty.
🔬 Głębiej: fair queues, kolejka standard przy dużej liczbie ponowień, szczegóły KMS
Fair queues (2025): w kolejce standard możesz podawać MessageGroupId (np. ID najemcy). SQS ogranicza wtedy wpływ „hałaśliwego sąsiada” (noisy neighbor): gdy jeden najemca zrobi zator, czas oczekiwania pozostałych rośnie mniej. To nie jest FIFO, kolejność dalej nie jest gwarantowana.
W kolejce standard z maxReceiveCount > 3 wiadomość odebrana 3 lub więcej razy bez skasowania jest przesuwana na koniec kolejki. ApproximateAgeOfOldestMessage pokazuje wtedy wiek kolejnej wiadomości.
Kolejka zaszyfrowana kluczem AWS managed (aws/sqs) nie może wywołać Lambdy w innym koncie. SSE nie szyfruje metadanych (ID, znaczniki czasu, atrybuty), tylko treść. Anonimowe SendMessage/ReceiveMessage do zaszyfrowanej kolejki są odrzucane.
Temporary queues (Temporary Queue Client) i wzorzec request-response przez kolejki z ReplyTo pojawiają się rzadko. Wystarczy wiedzieć, że istnieją dla wzorca RPC na SQS.
- Pull + jawne
DeleteMessage. Brak kasowania → wiadomość wraca po visibility timeout (30 s domyślnie, max 12 h). - Standard = at-least-once, bez gwarancji kolejności. FIFO = kolejność per
MessageGroupId, deduplikacja 5 min, 300 wywołań/s (3 000 wiadomości/s z batchem), high throughput mode. - Long polling ≤ 20 s. Retencja 1 min – 14 dni (domyślnie 4 dni). Delay ≤ 15 min. Wiadomość ≤ 1 MiB (dawniej 256 KB), większe przez Extended Client + S3 (do 2 GB).
- DLQ:
maxReceiveCount, ten sam typ, konto i region, dłuższa retencja. Redrive odsyła wiadomości z powrotem. - Batch = 10 wiadomości. SSE-SQS domyślnie, SSE-KMS dla audytu i własnego klucza.
Amazon SNS: jeden komunikat, wielu odbiorców
publish raz, a każdy subskrybent dostaje kopięSQS przypomina szatnię, a SNS megafon na dworcu. Mówisz raz („pociąg do Krakowa opóźniony”) i słyszy to każdy, kto stoi na peronie. Nie wiesz, kto słucha, a nikt nie musi Cię o nic pytać. To pub/sub: wydawca (publisher) wysyła wiadomość do tematu (topic), a SNS wypycha (push) kopię do każdej subskrypcji.
Subskrybentem może być kolejka SQS, funkcja Lambda, endpoint HTTP/S, e-mail, SMS, aplikacja mobilna (push) albo strumień Amazon Data Firehose. SNS nie przechowuje wiadomości do późniejszego odczytu. Jeśli dostarczenie się nie uda, SNS ponawia próby według delivery policy, a potem wiadomość przepada, chyba że subskrypcja ma DLQ.
Najważniejszy wzorzec egzaminacyjny to fan-out SNS → SQS. Zamówienie trafia do tematu, temat do kilku kolejek (fakturowanie, wysyłka, analityka), a każda kolejka ma własnych konsumentów, którzy pracują w swoim tempie i nie gubią wiadomości, gdy są wyłączeni. Filter policy na subskrypcji sprawia, że kolejka dostaje tylko to, co ją interesuje.
4.3.41.1.81.1.3
- Fan-out: SNS topic + kilka subskrypcji SQS. Kolejka potrzebuje access policy pozwalającej
sns.amazonaws.comnasqs:SendMessage(z warunkiemaws:SourceArn= ARN tematu). - Subscription filter policy (skill 4.3.4): JSON przypięty do subskrypcji. Bez polityki subskrybent dostaje wszystko.
FilterPolicyScope=MessageAttributes(domyślnie) alboMessageBody. Filtrowanie po stronie SNS zastępuje filtrowanie w kodzie konsumenta i zmniejsza koszty. - FIFO topic (nazwa
.fifo): kolejność perMessageGroupId, deduplikacja 5 min. Dostarcza tylko do kolejek SQS (FIFO lub standard), nie do e-maila, SMS ani HTTP. - Retries: endpointy AWS (SQS, Lambda) mają do 100 015 prób w 23 dni. HTTP/S ma własną, konfigurowalną delivery policy. Po wyczerpaniu prób: DLQ (kolejka SQS) przypięta do subskrypcji, nie do tematu.
- Rozmiar: domyślnie 256 KiB. Temat może przyjmować do 1 MiB po ustawieniu atrybutu
MaximumMessageSize(tylko gdy ma ≤ 100 subskrypcji SQS, Lambda lub Firehose). Większe ładunki: SNS Extended Client Library + S3. - SNS vs SQS vs EventBridge vs Kinesis: tabela porównawcza jest w rozdziale Kinesis.
Protokoły subskrypcji
| Opcja | Co robi | Kiedy |
|---|---|---|
| SQS | Wrzuca kopię do kolejki (wymaga access policy kolejki) | Fan-out, buforowanie, odporność na niedostępnego konsumenta |
| Lambda | Wywołuje funkcję asynchronicznie (retries i destinations Lambdy, szczegóły) | Lekka reakcja na zdarzenie |
| HTTP/S | POST na endpoint. Wymaga potwierdzenia subskrypcji (SubscribeURL / ConfirmSubscription). Jedyny protokół z własną delivery policy | Webhook do systemu zewnętrznego |
| Email / Email-JSON | Wiadomość e-mail, wymaga potwierdzenia przez odbiorcę | Powiadomienia dla ludzi, alarmy CloudWatch |
| SMS | Wiadomość tekstowa (również bez tematu: Publish z PhoneNumber) | Kody, alerty na telefon |
| Platform application endpoint | Mobile push przez APNs, FCM, ADM, Baidu, WNS, MPNS | Powiadomienia push w aplikacji mobilnej |
| Firehose | Dostarcza do strumienia Amazon Data Firehose (wymaga roli subskrypcji) | Archiwizacja wiadomości w S3, analityka |
Subskrypcje HTTP/S, e-mail i zasobów z innych kont trzeba potwierdzić, zanim zaczną dostawać wiadomości. Subskrypcja SQS lub Lambdy w tym samym koncie działa od razu.
Filter policies (skill 4.3.4)
Polityka to JSON: nazwy właściwości i listy dopuszczalnych wartości. Między różnymi kluczami działa AND, a w obrębie listy wartości OR. SNS ignoruje właściwości wiadomości, których polityka nie wymienia. Jeśli wiadomość nie ma atrybutu, którego wymaga polityka, nie zostanie dostarczona do tej subskrypcji.
// FilterPolicyScope = MessageAttributes (domyślnie) — dopasowanie do atrybutów wiadomości
{ "region": ["eu"], "type": ["order", "preorder"] }
// FilterPolicyScope = MessageBody — dopasowanie do pól w treści JSON (także zagnieżdżonych)
{ "order": { "amount": [ { "numeric": [">=", 1000] } ],
"country": [ { "anything-but": ["US"] } ] } }
- Operatory: dokładne dopasowanie (domyślnie, wielkość liter ma znaczenie),
prefix,suffix,anything-but,numeric(zakresy),exists,equals-ignore-case,cidr(adresy IP), a także$or. - Ograniczenia: max 5 kluczy na politykę, łączna liczba kombinacji wartości ≤ 150, do 200 polityk na temat. Zmiana polityki działa po maksymalnie 15 minutach (eventual consistency).
- Filtrowanie po treści wymaga poprawnego JSON-a w body. Atrybuty mają typy
String,String.Array,Number,Binary. Wiadomość SQS ma do 10 atrybutów. Gdy SNS przekazuje wiadomość do SQS z raw message delivery, atrybuty SNS stają się atrybutami SQS.
aws sns subscribe --topic-arn arn:aws:sns:eu-central-1:111122223333:orders \
--protocol sqs --notification-endpoint arn:aws:sqs:eu-central-1:111122223333:eu-shipping \
--attributes '{"FilterPolicy":"{\"region\":[\"eu\"]}","FilterPolicyScope":"MessageAttributes","RawMessageDelivery":"true"}'
Fan-out SNS → SQS krok po kroku
- Utwórz temat i kolejki (jeśli temat jest FIFO, kolejki mogą być FIFO albo standard).
- W access policy każdej kolejki pozwól
sns.amazonaws.comnasqs:SendMessagez warunkiemaws:SourceArn= ARN tematu (ochrona przed confused deputy). - Zasubskrybuj kolejki do tematu (
Subscribe, protokółsqs), opcjonalnie z filter policy iRawMessageDelivery=true. Bez raw delivery treść w kolejce to koperta JSON SNS (polaType,MessageId,Message…). - Jeśli kolejka używa SSE-KMS, użyj customer managed key i daj SNS w key policy
kms:GenerateDataKeyikms:Decrypt. - Kolejka w innym koncie: działa, ale subskrypcja cross-account wymaga potwierdzenia.
{ "Effect": "Allow",
"Principal": { "Service": "sns.amazonaws.com" },
"Action": "sqs:SendMessage",
"Resource": "arn:aws:sqs:eu-central-1:111122223333:eu-shipping",
"Condition": { "ArnEquals": { "aws:SourceArn": "arn:aws:sns:eu-central-1:111122223333:orders" } } }
Klasyczny przypadek: S3 event notifications nie pozwalają na dwie reguły z nakładającymi się prefiksami lub sufiksami dla tego samego typu zdarzenia. Żeby to samo zdarzenie trafiło do kilku konsumentów, wyślij je do SNS (albo EventBridge) i zrób fan-out.
FIFO topics
- Nazwa kończy się
.fifo.PublishwymagaMessageGroupIdiMessageDeduplicationId(albo content-based deduplication). Duplikat w ciągu 5 minut jest przyjmowany, ale nie dostarczany. - Subskrybenci: tylko kolejki SQS (FIFO dla ścisłej kolejności, standard, gdy wystarczy best-effort i liczy się koszt). Do Lambdy dostarczysz przez kolejkę SQS i jej event source mapping.
- Limity: do 1 000 tematów FIFO na konto i 100 subskrypcji na temat FIFO (standard: 100 000 tematów, 12,5 mln subskrypcji na temat).
Dostarczanie, ponowienia, DLQ
| Typ endpointu | Polityka ponowień | Co dalej |
|---|---|---|
| AWS managed (SQS, Lambda) | 3 natychmiast, 2 co 1 s, 10 z backoffem 1–20 s, 100 000 co 20 s: 100 015 prób w 23 dni | Niezmienna polityka |
| Customer managed (SMTP, SMS, mobile push) | 50 prób w ciągu 6 godzin | Niezmienna polityka |
| HTTP/S | Własna delivery policy (liczba prób, backoff, throttling), łącznie max 3 600 s | Jedyny konfigurowalny protokół |
Błędy client-side (usunięty endpoint, polityka blokuje SNS) nie są ponawiane. Błędy server-side (endpoint niedostępny) są ponawiane według polityki. W obu przypadkach, po porażce, wiadomość trafia do DLQ subskrypcji (atrybut RedrivePolicy subskrypcji, kolejka SQS w tym samym koncie i regionie co subskrypcja; dla subskrypcji tematu FIFO DLQ jest kolejką FIFO), a bez DLQ przepada.
Inne funkcje: Publish z MessageStructure=json wysyła inną treść każdemu protokołowi. PublishBatch to do 10 wiadomości. SSE przez KMS (KmsMasterKeyId). Delivery status logging do CloudWatch Logs pokazuje sukcesy i porażki dostarczeń (np. do Lambdy, SQS, HTTP). Message data protection (data protection policies) audytuje, maskuje, redaguje lub blokuje dane wrażliwe (PII).
Mobile push: tworzysz platform application (dane uwierzytelniające APNs/FCM), dla każdego urządzenia token urządzenia zamieniasz na platform endpoint (CreatePlatformEndpoint → EndpointArn) i publikujesz do endpointu (TargetArn) albo do tematu, który endpointy subskrybują. Logowanie użytkowników aplikacji to rola Cognito, nie SNS.
sqs:SendMessage w swojej polityce.- „Filtruj w kodzie Lambdy/konsumenta” — działa, ale płacisz za każde wywołanie. Pytanie o „najmniejszy koszt” albo „tylko podzbiór wiadomości” wskazuje na subscription filter policy.
- Polityka na treści przy domyślnym scope — domyślnie
FilterPolicyScope=MessageAttributes. Jeśli dane są tylko w body, ustawMessageBody, bo inaczej nic nie przejdzie. - „SNS przechowa wiadomość, aż konsument się podniesie” — nie. Trwałość daje kolejka SQS za tematem albo DLQ subskrypcji.
- DLQ na temacie — DLQ przypinasz do subskrypcji (redrive policy subskrypcji).
- FIFO topic → e-mail/HTTP/Lambda bezpośrednio — FIFO topic dostarcza tylko do kolejek SQS.
- Brak access policy kolejki — subskrypcja istnieje, ale nic nie dociera. Kolejka musi pozwolić SNS na
sqs:SendMessage. - „Jedna kolejka SQS z wieloma konsumentami = fan-out” — nie. Kolejka rozdziela wiadomości (każda trafia do jednego konsumenta). Kopię dla każdego daje SNS (albo EventBridge).
Serwis zamówień publikuje każde zamówienie. Fakturowanie, magazyn i analityka mają przetwarzać je niezależnie, każde we własnym tempie, i nie gubić zamówień, gdy któryś system jest wyłączony. Jaka architektura?
wielu odbiorców, niezależnie, nie gubić
Odpowiedź
SNS topic + osobna kolejka SQS dla każdego systemu (fan-out).
Dlaczego nie: jedna kolejka z trzema konsumentami rozdzieli zamówienia między nich. Sam SNS z Lambdami nie zbuforuje wiadomości przy dłuższej awarii. Kinesis zadziała, ale wymaga zarządzania shardami i jest przesadą.
Kolejka „eu-shipping” ma dostawać tylko zamówienia z regionem „eu”. Region jest atrybutem wiadomości. Jak to zrobić najmniejszym nakładem?
tylko podzbiór, atrybut
Odpowiedź
Filter policy na subskrypcji kolejki: {"region":["eu"]} (scope MessageAttributes, domyślny).
Dlaczego nie: osobny temat dla każdego regionu komplikuje wydawcę. Filtrowanie w konsumencie kosztuje odczyty. Lambda pośrednicząca to dodatkowy kod.
Filter policy {"amount":[{"numeric":[">=",1000]}]} na subskrypcji Lambdy nic nie przepuszcza, choć w treści JSON są duże kwoty. Co jest nie tak?
pole w body, filtr nie działa
Odpowiedź
Ustaw FilterPolicyScope=MessageBody. Domyślny scope MessageAttributes szuka atrybutu amount, którego nie ma.
Dlaczego nie: zmiana typu na String nie pomoże. Raw message delivery dotyczy formatu dostarczania, a nie filtrowania. 15 minut propagacji dotyczy tylko świeżo zmienionej polityki.
Subskrypcja HTTPS partnera bywa niedostępna przez kilka godzin i wiadomości giną. Jak je zachować do ponownego przetworzenia?
giną po ponowieniach
Odpowiedź
Skonfigurować DLQ (kolejkę SQS) na subskrypcji przez jej redrive policy, ewentualnie wydłużyć delivery policy HTTP/S (łącznie max 3 600 s).
Dlaczego nie: DLQ nie ustawia się na temacie. FIFO topic nie dostarcza do HTTPS. SNS nie ma własnej retencji wiadomości.
Zdarzenia zmian cen muszą trafić do kilku kolejek SQS w tej samej kolejności dla danego produktu i bez duplikatów. Co wybrać?
fan-out + kolejność + deduplikacja
Odpowiedź
SNS FIFO topic → kolejki SQS FIFO, MessageGroupId = ID produktu.
Dlaczego nie: standard topic nie gwarantuje kolejności. EventBridge (klasyczna szyna) nie gwarantuje kolejności. Pojedyncza kolejka FIFO nie robi fan-outu.
🔬 Głębiej: limity, raw delivery, duże wiadomości
Raw message delivery (SQS, HTTP/S, Firehose) usuwa kopertę JSON SNS, więc konsument dostaje dokładnie opublikowaną treść. Lambda tej opcji nie ma i zawsze dostaje zdarzenie SNS z polem Records[].Sns.
1 MiB w SNS: atrybut tematu MaximumMessageSize (1 024 – 1 048 576 B, domyślnie 262 144 B). Powyżej 256 KiB temat może mieć max 100 subskrypcji i tylko typy SQS, Lambda, Firehose. Limit obejmuje treść i atrybuty razem. W testach próbnych przyjmuj 256 KB jako limit SNS, a jako rozwiązanie dla większych ładunków: Extended Client Library z S3.
Numeric matching w filtrach działa w zakresie od −109 do 109 z dokładnością do 5 miejsc po przecinku. Polityka może mieć do 256 KB. W polityce body liczą się tylko klucze-liście (leaf keys).
Metryki CloudWatch: NumberOfMessagesPublished, NumberOfNotificationsDelivered, NumberOfNotificationsFailed, NumberOfNotificationsFilteredOut.
- Push pub/sub: jedna wiadomość, kopia dla każdej subskrypcji. Brak przechowywania.
- Fan-out SNS → SQS wymaga access policy kolejki (
sqs:SendMessagedla SNS +aws:SourceArn). - Filter policy na subskrypcji: AND między kluczami, OR w liście. Scope MessageAttributes (domyślny) lub MessageBody. Brak polityki = wszystko.
- FIFO topic: kolejność per grupa, deduplikacja 5 min, tylko subskrybenci SQS.
- Ponowienia: SQS/Lambda 100 015 prób w 23 dni, HTTP/S konfigurowalne. Potem DLQ subskrypcji albo utrata.
Amazon EventBridge: sortownia zdarzeń
reguła patrzy na kopertę i decyduje, gdzie ją wysłaćPomyśl o sortowni poczty. Listy (zdarzenia, events) wpadają na taśmę (event bus). Przy taśmie stoją sortownicy (reguły, rules). Każdy ma kartkę z opisem: „biorę listy z Krakowa powyżej 1 kg” (event pattern). Gdy list pasuje, sortownik wkłada kopię do worka (target). Jeden list może pasować do wielu reguł, a każda reguła może mieć kilka worków.
EventBridge to serwerless router zdarzeń. Zdarzenia przychodzą od usług AWS (np. zmiana stanu EC2, wywołanie API zapisane w CloudTrail), z Twojego kodu (PutEvents) albo od partnerów SaaS. Reguły filtrują je wzorcami i wysyłają do celów: Lambda, SQS, SNS, Step Functions, Kinesis, API Gateway, inna szyna, dowolne API HTTP (API destinations) i wiele innych.
W porównaniu z SNS EventBridge filtruje po dowolnym polu w treści zdarzenia bogatszymi operatorami, potrafi przekształcić zdarzenie przed wysłaniem, archiwizować i odtwarzać zdarzenia, uruchamiać coś według harmonogramu i odbierać zdarzenia z aplikacji SaaS. SNS wygrywa przy bardzo dużej liczbie subskrybentów, w kanałach dla ludzi (SMS, e-mail, push) i przy FIFO.
1.1.121.1.11.1.3
- Szyny: default (zdarzenia usług AWS), custom (Twoje aplikacje), partner (SaaS, np. Zendesk, Datadog). Reguła należy do jednej szyny i ma do 5 targetów.
- Event pattern ma kształt zdarzenia, a wartości podajesz w tablicach. Dopasowanie jest dokładne i rozróżnia wielkość liter. Operatory:
prefix,suffix,anything-but,numeric,exists,wildcard,equals-ignore-case,cidr,$or. - Input transformer (
InputPathsMap+InputTemplate) zmienia zdarzenie przed wysłaniem do celu, bez Lambdy pośredniczącej. - Retry: domyślnie 24 h i 185 prób z backoffem. Potem DLQ (tylko SQS standard) ustawiona per target.
- Archive & replay: odtworzenie przeszłych zdarzeń na tę samą szynę (np. po naprawieniu błędu w konsumencie). Schema registry + schema discovery + code bindings (Java, Python, TypeScript, Go).
- EventBridge Scheduler (zalecany zamiast scheduled rules): cron, rate, one-time, strefy czasowe, miliony harmonogramów. Pipes: point-to-point źródło → filtr → enrichment → cel.
- Cross-account: resource-based policy na docelowej szynie + rola IAM na regule wysyłającej. API destinations: wywołanie zewnętrznego HTTPS z connection (Basic, OAuth, API key; sekret w Secrets Manager) i limitem wywołań na sekundę.
- Rozmiar
PutEvents: do 10 wpisów, łącznie poniżej 1 MB. W starszych pytaniach zobaczysz limit 256 KB na zdarzenie. Większe dane wkładasz do S3 i wysyłasz link.
Zdarzenie na szynie
id, time, region, account, resources). Nazwy, kwoty i reguły są ilustracyjne, a składnia wzorców i semantyka operatorów pochodzą z dokumentacji EventBridge. Mini-silnik w przeglądarce obsługuje tylko pokazane operatory.Zdarzenie i wzorzec
// zdarzenie (envelope + detail)
{ "version": "0", "id": "…", "detail-type": "OrderPlaced", "source": "com.shop.orders",
"account": "111122223333", "time": "2026-10-04T10:00:00Z", "region": "eu-central-1",
"resources": [], "detail": { "amount": 1500, "country": "PL" } }
// wzorzec reguły: wszystkie podane pola muszą pasować (AND), w tablicy wystarczy jedna wartość (OR)
{ "source": ["com.shop.orders"],
"detail-type": ["OrderPlaced"],
"detail": { "amount": [ { "numeric": [">=", 1000] } ],
"country": [ { "anything-but": ["US", "CA"] } ] } }
| Operator | Przykład | Pasuje, gdy |
|---|---|---|
| dokładna wartość | "state": ["running", "stopped"] | wartość równa jednej z listy (z rozróżnieniem wielkości liter) |
prefix / suffix | [{"prefix": "eu-"}], [{"suffix": ".png"}] | tekst zaczyna się / kończy |
anything-but | [{"anything-but": "initializing"}] | każda wartość oprócz podanych (też z prefix, suffix, wildcard) |
numeric | [{"numeric": [">", 0, "<=", 5]}] | liczba w zakresie |
exists | [{"exists": true}] / false | pole jest / go nie ma |
wildcard | [{"wildcard": "dir/*.png"}] | dopasowanie z * |
equals-ignore-case | [{"equals-ignore-case": "alice"}] | równe bez względu na wielkość liter |
cidr | [{"cidr": "10.0.0.0/24"}] | adres IP w podsieci |
$or | "$or": [{"a": [1]}, {"b": [2]}] | alternatywa między różnymi polami |
Pola, których wzorzec nie wymienia, nie mają znaczenia. Wzorzec testujesz w konsoli (Sandbox) albo API TestEventPattern. Reakcja na wywołanie API dowolnej usługi (np. DeleteBucket) to wzorzec z "detail-type": ["AWS API Call via CloudTrail"]. Takie zdarzenia wymagają włączonego CloudTrail.
Targety, uprawnienia, transformacja
- Do Lambdy, SNS i SQS EventBridge może wysyłać na podstawie resource-based policy celu albo roli IAM. Do CloudWatch Logs tylko przez resource-based policy. Do celów takich jak Kinesis, Step Functions, ECS task czy inna szyna potrzebuje roli IAM (
RoleArnw targecie). - Input transformer:
InputPathsMapwyciąga do 100 zmiennych z zdarzenia (np."amt": "$.detail.amount"), aInputTemplateskłada nowy ładunek ("Zamówienie na <amt> zł"). Są też zmienne zarezerwowane, np.<aws.events.rule-name>. Inne tryby: Input (stały JSON) i InputPath (fragment zdarzenia). - Retry policy per target:
MaximumRetryAttempts(0–185) iMaximumEventAgeInSeconds(60 s – 24 h). Błędy typu brak uprawnień lub usunięty cel trafiają do DLQ bez ponowień. Wiadomość w DLQ ma atrybutyERROR_CODE,ERROR_MESSAGE,RULE_ARN,TARGET_ARN. - Klasyczna szyna nie gwarantuje kolejności i nie deduplikuje zdarzeń, więc cel powinien być idempotentny.
- Reguła, której cel publikuje zdarzenia pasujące do tej samej reguły (np. Lambda zapisuje do tego samego zasobu, który generuje zdarzenie), tworzy nieskończoną pętlę i rachunek. Zawęź wzorzec albo zapisuj gdzie indziej.
aws events put-events --entries '[{"Source":"com.shop.orders","DetailType":"OrderPlaced",
"Detail":"{\"amount\":1500,\"country\":\"PL\"}","EventBusName":"orders-bus"}]'
# odpowiedź: FailedEntryCount + Entries[] — sprawdzaj częściowe porażki i ponawiaj tylko nieudane wpisy
Archive, replay, schematy
- Archive zapisuje zdarzenia z jednej szyny (opcjonalnie tylko pasujące do wzorca). Retencja domyślnie bez limitu albo N dni.
- Replay odtwarza wybrany przedział czasu tylko na szynę źródłową (wszystkie reguły albo wybrane). Odtworzone zdarzenie ma pole
replay-name, a zarządzana reguła archiwum nie archiwizuje go ponownie. Do 10 równoległych replayów na konto i region. - Schema registry: schematy zdarzeń usług AWS, Twoje własne oraz wykryte (schema discovery na szynie). Z schematu pobierasz code bindings (Java, Python, TypeScript, Go), czyli gotowe klasy zdarzeń w kodzie. Format OpenAPI 3 lub JSONSchema Draft4.
Harmonogramy: Scheduler kontra scheduled rules
| Opcja | Co robi | Kiedy |
|---|---|---|
| EventBridge Scheduler | Osobna usługa: rate(), cron() i one-time at(), strefy czasowe (z obsługą zmiany czasu), flexible time window, retry i DLQ, ponad 270 usług jako cel (templated i universal targets) | Zalecany wybór: „uruchom raz o 9:00 czasu warszawskiego”, miliony harmonogramów, przypomnienia per użytkownik |
| Scheduled rule | Reguła na szynie default z rate() lub cron() (UTC), cele jak w zwykłej regule | Istniejące rozwiązania, proste zadania cykliczne |
Cron w EventBridge ma 6 pól: cron(minuty godziny dzień-miesiąca miesiąc dzień-tygodnia rok), a w dniu miesiąca lub dniu tygodnia jedno z nich musi być ?. Przykład: cron(0 9 ? * MON-FRI *). Rate: rate(5 minutes).
Pipes, cross-account, API destinations
- EventBridge Pipes łączy jedno źródło z jednym celem: źródła DynamoDB Streams, Kinesis, SQS, Amazon MQ, MSK, Apache Kafka. Opcjonalnie filtr i enrichment (Lambda, Step Functions Express, API Gateway, API destination). Zastępuje kod typu „Lambda czyta strumień, dociąga dane i wrzuca dalej”.
- Cross-account: konto docelowe dodaje do swojej szyny resource-based policy (
events:PutEventsdla konta albo organizacji). Konto źródłowe tworzy regułę z targetem = ARN obcej szyny i rolą IAM (wymagana dla nowych targetów od marca 2023). Cross-region: szyna w innym regionie jako target, tak samo. - API destinations: target HTTPS (dowolna metoda oprócz CONNECT i TRACE) z connection, która trzyma autoryzację (Basic, OAuth client credentials, API key) w Secrets Manager. Ustawiasz limit wywołań na sekundę, nadmiar czeka w kolejce i jest ponawiany do 24 h, a po tym czasie zdarzenie przepada, jeśli nie ma DLQ.
Zespół płatności publikuje zdarzenie PaymentCompleted. Trzy zespoły chcą na nie reagować i nie chcą prosić zespołu płatności o zmiany. Gdzie EventBridge pomaga bardziej niż bezpośrednie wywołania? Każdy zespół dopisuje własną regułę na szynie, a wydawca nic nie wie o odbiorcach. To choreografia (luźne powiązanie, wzorce). Jeśli kolejność kroków i obsługa błędów całego procesu muszą być w jednym miejscu, lepsza jest orkiestracja w Step Functions.
- Wzorzec z wartością bez tablicy (
"state": "running") albo inną wielkością liter — nie zadziała. Wartości są w tablicach, a dopasowanie rozróżnia wielkość liter (chyba że użyjeszequals-ignore-case). - DLQ jako kolejka FIFO — EventBridge obsługuje tylko SQS standard jako DLQ.
- „Lambda, która przekształca zdarzenie przed wysłaniem do SQS” — zwykle wystarczy input transformer (mniej kodu i kosztów).
- Replay do innej szyny — replay idzie tylko do szyny źródłowej archiwum.
- Scheduled rule dla jednorazowego zadania w lokalnej strefie czasowej — scheduled rules liczą w UTC i nie mają harmonogramów jednorazowych. Wybierz EventBridge Scheduler z
at()i strefą czasową. - „EventBridge gwarantuje kolejność” — klasyczna szyna nie gwarantuje. Kolejność: SQS FIFO, SNS FIFO, Kinesis.
- Ponad 5 targetów na regułę — limit to 5 i nie da się go podnieść. Dodaj kolejną regułę z tym samym wzorcem albo target SNS do dalszego fan-outu.
Gdy ktoś zakończy (terminate) instancję EC2 w produkcji, zespół chce dostać powiadomienie na Slacka przez webhook HTTPS. Jak to zrobić bez serwerów i własnego kodu?
reakcja na zmianę stanu usługi, HTTP, bez kodu
Odpowiedź
Reguła EventBridge na szynie default ze wzorcem source: aws.ec2, detail.state: terminated i targetem API destination (connection z kluczem API), ewentualnie z input transformerem formatującym tekst.
Dlaczego nie: CloudWatch Logs nie dostaje zmian stanu EC2 sam z siebie. Lambda z pollingiem DescribeInstances to własny kod. AWS Config to inny cel (zgodność konfiguracji).
Błąd w konsumencie spowodował złe przetworzenie zdarzeń z ostatnich 6 godzin. Po poprawce trzeba je przetworzyć ponownie. Co należało włączyć wcześniej?
ponowne przetworzenie przeszłych zdarzeń
Odpowiedź
EventBridge archive na szynie, a teraz replay z zakresu czasu na tę samą szynę.
Dlaczego nie: DLQ łapie tylko nieudane dostarczenia, a nie błędnie przetworzone zdarzenia. CloudTrail nie odtworzy zdarzeń aplikacyjnych.
Aplikacja ma wysłać każdemu użytkownikowi przypomnienie dokładnie raz, o wybranej przez niego godzinie w jego strefie czasowej. Użytkowników są miliony. Co wybrać?
one-time, strefa czasowa, miliony
Odpowiedź
EventBridge Scheduler z harmonogramami one-time (at()) i strefą czasową, target Lambda albo SNS.
Dlaczego nie: scheduled rules działają w UTC, nie robią one-time i mają limit reguł. SQS delay to max 15 min. Cron na EC2 to serwer do utrzymania.
Deweloperzy chcą mieć w IDE silnie typowane klasy dla zdarzeń, które publikuje inny zespół na custom bus. Jak?
typed classes, events from other team
Odpowiedź
Schema discovery na szynie + schema registry + pobranie code bindings (Java, Python, TypeScript, Go).
Dlaczego nie: AppSync to GraphQL. API Gateway models dotyczą API, nie zdarzeń. Ręczne pisanie klas nie nadąży za zmianami.
Zdarzenia z kolejki SQS mają trafiać do Step Functions, ale najpierw trzeba odfiltrować część i dociągnąć dane klienta z API. Rozwiązanie z najmniejszą ilością kodu?
point-to-point, filter, enrich
Odpowiedź
EventBridge Pipes: źródło SQS → filtr → enrichment (API destination lub Lambda) → target Step Functions.
Dlaczego nie: Lambda ESM + własny kod to więcej kodu. Reguła na szynie nie czyta z SQS.
Konto A ma wysyłać zdarzenia do szyny w koncie B. Co trzeba skonfigurować?
cross-account event bus
Odpowiedź
W koncie B resource-based policy szyny pozwalającą kontu A (lub organizacji) na events:PutEvents. W koncie A regułę z targetem = ARN szyny B i rolą IAM z prawem do PutEvents.
Dlaczego nie: VPC peering nie ma związku z EventBridge. Kluczy dostępu konta B nie powinno się udostępniać.
🔬 Głębiej: nowa „Custom Event Bus”, limity, global endpoints
Uwaga na aktualną dokumentację. Obecne docs rozróżniają Custom Event Bus - Classic (reguły i targety, czyli wszystko, co opisuje ten rozdział i co sprawdza DVA-C02) oraz nowszą Custom Event Bus. Ta druga przechowuje zdarzenia przez wybrany czas, a konsumenci tworzą na niej subscribers (filtr, transformacja, jeden cel), które mogą dostarczać zdarzenia w kolejności, zacząć od punktu w przeszłości i wstrzymywać się bez utraty zdarzeń. Jeśli pytanie mówi o regułach i targetach, myśl o modelu klasycznym.
Limity klasyczne: 100 szyn na region (podnoszalne), 5 targetów na regułę (sztywne), wzorzec do 2 048 znaków. Throttling PutEvents zależy od regionu (np. 10 000/s w us-east-1). Limit wywołań API destination to 300/s na region.
Reguły z wildcardami: do 30 na szynę. Złożone wzorce z wildcardami mogą zostać odrzucone jako zbyt złożone.
Global endpoints dają automatyczny failover publikowania zdarzeń między dwoma regionami (z health check Route 53). Rzadko na DVA, częściej na egzaminach architektonicznych.
- Szyna (default / custom / partner) → reguła z event pattern → do 5 targetów. At-least-once, bez gwarancji kolejności.
- Wzorce: tablice wartości, dokładne dopasowanie z rozróżnieniem wielkości liter, operatory prefix/suffix/anything-but/numeric/exists/wildcard.
- Input transformer zamiast Lambdy-tłumacza. Retry 24 h / 185 prób, potem DLQ SQS standard.
- Archive + replay (tylko do szyny źródłowej). Schema registry + code bindings.
- Scheduler: one-time, cron, rate, strefy czasowe. Pipes: 1 źródło → filtr → enrichment → 1 cel. Cross-account: polityka szyny + rola IAM.
PutEvents: do 10 wpisów, < 1 MB (dawniej 256 KB).
Kinesis: strumień, który pamięta
dane płyną pasami (shardami) i można je czytać ponownieKolejka SQS to stos listów: ktoś bierze list, czyta i wyrzuca. Strumień Kinesis przypomina raczej taśmę rejestratora. Zapisy (records) lądują na taśmie w kolejności, zostają tam przez czas retencji, a każdy czytelnik ma własny „wskaźnik”, od którego czyta. Kilka aplikacji może czytać te same dane niezależnie, a także cofnąć się i przeczytać je jeszcze raz (replay).
Kinesis Data Streams (KDS) dzieli strumień na shardy, czyli równoległe pasy. Każdy rekord ma partition key. Kinesis liczy z niego hash (MD5) i na tej podstawie wybiera shard. Ten sam klucz zawsze trafia do tego samego sharda, więc kolejność jest zachowana w obrębie sharda (czyli dla danego klucza). Każdy rekord dostaje rosnący sequence number.
Rodzina ma trzy usługi. Data Streams to strumień czasu rzeczywistego dla Twoich konsumentów. Amazon Data Firehose (dawniej Kinesis Data Firehose) bez kodu ładuje strumień do S3, Redshift, OpenSearch, Splunk i innych celów w trybie near real time. Amazon Managed Service for Apache Flink (dawniej Kinesis Data Analytics) analizuje strumienie na bieżąco (SQL, Java, Scala, Python).
1.1.101.1.81.1.4
- Shard: zapis do 1 MB/s lub 1 000 rekordów/s, odczyt 2 MB/s (współdzielone przez konsumentów) i 5 wywołań
GetRecords/s. ProvisionedThroughputExceededException: najczęściej gorący shard (zły partition key o małej kardynalności). Naprawy: klucz o wysokiej kardynalności (np. losowy sufiks), retry z exponential backoff, batching (PutRecords), więcej shardów (UpdateShardCount,SplitShard) albo tryb on-demand.- Retencja: domyślnie 24 h, do 365 dni. Dane można czytać wielokrotnie (replay), w przeciwieństwie do SQS i Firehose.
- Enhanced fan-out: każdy zarejestrowany konsument ma własne 2 MB/s na shard, push przez
SubscribeToShard(HTTP/2), opóźnienie ok. 70 ms. Używaj, gdy jest wielu konsumentów. - KCL: tabela lease w DynamoDB (koordynacja i checkpointy). Jeden shard przetwarza naraz jeden worker, więc więcej instancji niż shardów nic nie da.
- Firehose: w pełni zarządzany, auto-scaling, buforuje (rozmiar / czas), opcjonalna transformacja Lambdą, konwersja formatu, kompresja. Nie przechowuje danych do odtworzenia i nie ma własnych konsumentów.
- Rekord: domyślnie do 1 MiB (od października 2025 można podnieść do 10 MiB przez
UpdateMaxRecordSize). W testach próbnych przyjmij limit 1 MB.
ProvisionedThroughputExceededException. Prawdziwy producent ponowiłby je z backoffem.Data Streams: limity i tryby pojemności
| Opcja | Co robi | Kiedy |
|---|---|---|
| Provisioned | Sam ustalasz liczbę shardów i płacisz za shard-godziny. Pojemność = liczba shardów × (1 MB/s zapisu, 2 MB/s odczytu) | Przewidywalny ruch, kontrola kosztów |
| On-demand | Automatyczne skalowanie bez planowania shardów. Nowy strumień: 4 MB/s zapisu i 8 MB/s odczytu, rośnie wraz z ruchem | Nieprzewidywalny ruch, „no capacity planning”, „least operational overhead” |
Między trybami przełączasz strumień maksymalnie dwa razy na 24 h.
PutRecord: jeden rekord (Data+PartitionKey, opcjonalnieExplicitHashKey). Ścisłą kolejność przy kolejnych zapisach tego samego klucza wymuszasz parametremSequenceNumberForOrdering.PutRecords: do 500 rekordów w wywołaniu (łącznie do 10 MiB, dawniej 5 MiB). Odpowiedź może być częściowo udana: sprawdźFailedRecordCounti ponów tylko rekordy zErrorCode.PutRecordsnie gwarantuje kolejności rekordów w obrębie wywołania.- Partition key: do 256 znaków Unicode.
GetRecordszwraca do 10 000 rekordów lub 10 MB, max 5 wywołań/s na shard, z iteratorem zGetShardIterator(TRIM_HORIZONod najstarszego,LATESTod nowych,AT_SEQUENCE_NUMBER,AT_TIMESTAMP…). - KPL (Kinesis Producer Library) agreguje wiele małych rekordów w jeden rekord Kinesis i zbiera je w paczki. Daje wyższą przepustowość za cenę dodatkowego opóźnienia buforowania.
- Szyfrowanie: server-side encryption kluczem AWS KMS (szyfruje dane, zanim trafią na dysk), TLS w tranzycie.
Gorące shardy i resharding
Gdy jeden klucz (np. data, ID dużego klienta, „unknown”) generuje większość ruchu, wszystko trafia do jednego sharda i przekracza jego limit, choć reszta strumienia stoi pusta. Objawy: ProvisionedThroughputExceededException mimo niskiego średniego wykorzystania, metryka WriteProvisionedThroughputExceeded > 0, rosnący GetRecords.IteratorAgeMilliseconds (konsumenci nie nadążają).
- Split (
SplitShard) dzieli jeden shard (rodzic) na dwa (dzieci), dzieląc jego zakres hashy. Pomaga, gdy w gorącym shardzie jest wiele kluczy. Jeden gorący klucz zawsze trafi do jednego sharda. - Merge (
MergeShards) łączy dwa sąsiednie zimne shardy, żeby obniżyć koszt. UpdateShardCountzmienia liczbę shardów strumienia za Ciebie (uniform scaling).- Po reshardingu nowe rekordy trafiają do shardów-dzieci, a rekordy w zamkniętym shardzie-rodzicu pozostają dostępne do końca retencji (stany OPEN → CLOSED → EXPIRED). Żeby zachować kolejność dla klucza, konsument powinien dokończyć rodzica przed dziećmi (KCL robi to sam).
Konsumenci: shared, enhanced fan-out, KCL, Lambda
| Cecha | Shared throughput (GetRecords) | Enhanced fan-out (SubscribeToShard) |
|---|---|---|
| Przepustowość odczytu | 2 MB/s na shard dla wszystkich konsumentów razem | 2 MB/s na shard dla każdego konsumenta |
| Model | pull (polling) | push przez HTTP/2 |
| Opóźnienie | ok. 200 ms przy 1 konsumencie, ok. 1000 ms przy 5 | ok. 70 ms niezależnie od liczby konsumentów |
| Koszt | w cenie strumienia | dodatkowo za consumer-shard-godzinę i pobrane dane |
| Limit | 5 wywołań GetRecords/s na shard | do 20 zarejestrowanych konsumentów na strumień |
- KCL (Kinesis Client Library) ukrywa szczegóły: rozdziela shardy między workery przez lease, a stan i checkpointy trzyma w tabeli DynamoDB (nazwanej jak aplikacja). Jeden shard ma naraz jednego właściciela, a jeden worker może mieć kilka shardów. Throttling tej tabeli spowalnia konsumentów, więc daj jej odpowiednią pojemność (lub on-demand).
- Lambda (event source mapping) czyta rekordy shard po shardzie, w kolejności. Błąd blokuje shard, dopóki rekord nie wygaśnie albo nie skończą się ponowienia. Przyspieszenie:
ParallelizationFactor(1–10 równoległych paczek na shard z zachowaniem kolejności per klucz). Obsługa błędów (bisect, on-failure destination,ReportBatchItemFailures) jest w rozdziale Lambda — zdarzenia.
Amazon Data Firehose
- Źródła: Direct PUT (
PutRecord/PutRecordBatch, do 500 rekordów; bezpośrednio wysyłają też m.in. SDK, Lambda, CloudWatch Logs, SNS, logi WAF i API Gateway), strumień Kinesis Data Streams albo Amazon MSK. - Cele: S3, Redshift (przez S3 i
COPY), OpenSearch, Splunk, Snowflake, Apache Iceberg tables, dowolny HTTP endpoint i partnerzy (Datadog, New Relic…). - Buforowanie: Firehose wysyła paczkę, gdy osiągnie buffer size (MB) albo buffer interval (sekundy). Dlatego jest near real time, a nie real time. Bufor można też ustawić na zero, gdy liczy się opóźnienie.
- Transformacja: Firehose wywołuje Twoją Lambdę synchronicznie z paczką rekordów (np. parsowanie, wzbogacanie, maskowanie). Wbudowana konwersja JSON do Parquet/ORC, kompresja, dynamic partitioning prefiksów S3, kopia zapasowa surowych danych lub nieudanych rekordów do S3.
- Rekord do 1 000 KiB. Gdy cel jest niedostępny, Direct PUT trzyma dane do 24 h. Firehose nie zapewnia replay ani własnych konsumentów. Do tego potrzebujesz KDS.
Managed Service for Apache Flink: zarządzane aplikacje Apache Flink (Java, Scala, Python, SQL; notebooki w Studio) do analizy w czasie rzeczywistym, np. okna czasowe, agregacje, wykrywanie anomalii na strumieniu KDS lub MSK. Słowa kluczowe: „real-time analytics”, „SQL on streaming data”.
SQS vs SNS vs EventBridge vs Kinesis
| Cecha | SQS | SNS | EventBridge | Kinesis Data Streams |
|---|---|---|---|---|
| Model | kolejka, pull | pub/sub, push | router zdarzeń, push (reguły) | strumień, pull (lub push z EFO) |
| Odbiorcy jednej wiadomości | jeden konsument | wszyscy subskrybenci (do 12,5 mln na temat) | każda pasująca reguła, do 5 targetów na regułę | każda aplikacja czytająca strumień |
| Przechowywanie | do 14 dni, kasowana po przetworzeniu | brak | brak (opcjonalne archive) | 24 h – 365 dni, odczyt wielokrotny |
| Kolejność | FIFO queue | FIFO topic | brak (klasyczna szyna) | w obrębie sharda (partition key) |
| Filtrowanie | brak (filtr robi konsument lub ESM Lambdy) | filter policy (atrybuty / body) | bogate event patterns na całym zdarzeniu | brak (konsument, filtr ESM Lambdy) |
| Skalowanie | automatyczne | automatyczne | automatyczne | shardy (provisioned) lub on-demand |
| Typowe słowa w pytaniu | decouple, buffer, worker, retry later | fan-out, notify, SMS/email/push | react to AWS service events, SaaS, schedule, routing rules | real-time, clickstream, IoT, ordering per key, replay, many consumers |
- „Dodaj shardy”, gdy throttluje jeden klucz — przy gorącym kluczu nowe shardy stoją puste. Najpierw zmień partition key na klucz o wysokiej kardynalności.
- „Firehose do analizy w czasie rzeczywistym / replay” — Firehose jest near real time i nie przechowuje danych do ponownego odczytu.
- „Więcej instancji KCL niż shardów” — nie zwiększa równoległości.
- „PutRecords zachowa kolejność” — nie gwarantuje. Kolejność dla klucza:
PutRecordszeregowo zSequenceNumberForOrdering. - „Retencja Kinesis jak SQS: 14 dni maksymalnie” — KDS trzyma do 365 dni (domyślnie 24 h).
- „Ignoruj PTEE, SDK samo ponowi” — SDK ponawia kilka razy. W
PutRecordsbłąd dotyczy pojedynczych rekordów w udanej odpowiedzi, więc musisz sam ponowić nieudane. - „Kinesis Data Analytics” to stara nazwa. Dziś to Managed Service for Apache Flink, a „Kinesis Data Firehose” to Amazon Data Firehose.
Producent IoT dostaje ProvisionedThroughputExceededException, choć CloudWatch pokazuje, że strumień 10-shardowy wykorzystuje średnio 20% pojemności. Partition key to ID modelu urządzenia (3 modele). Co zrobić?
PTEE przy niskim średnim zużyciu, mało różnych kluczy
Odpowiedź
Użyć partition key o wysokiej kardynalności (np. ID urządzenia albo klucz z losowym sufiksem), a w kodzie dodać retry z exponential backoff.
Dlaczego nie: więcej shardów nie pomoże, bo 3 klucze trafiają najwyżej do 3 shardów. On-demand też dzieli ruch po kluczach. Większe paczki nie zmieniają limitu sharda.
Dane clickstream trzeba zapisywać w S3 w formacie Parquet, z jak najmniejszym nakładem operacyjnym. Opóźnienie do kilku minut jest akceptowalne.
S3, Parquet, least operational overhead, minutes OK
Odpowiedź
Amazon Data Firehose z konwersją formatu do Parquet i celem S3.
Dlaczego nie: KDS + Lambda zapisująca do S3 to więcej kodu i zarządzania shardami. SQS nie jest przeznaczony do strumieni analitycznych.
Pięć niezależnych aplikacji czyta ten sam strumień Kinesis. Mają rosnące opóźnienia i błędy ReadProvisionedThroughputExceeded. Co zrobić?
wielu konsumentów, odczyt throttlowany
Odpowiedź
Zarejestrować konsumentów z enhanced fan-out: każdy dostaje własne 2 MB/s na shard i push ok. 70 ms.
Dlaczego nie: więcej workerów KCL nie podniesie 2 MB/s dzielonych przez wszystkich. Dłuższa retencja nie dotyczy przepustowości.
Zdarzenia transakcji tego samego konta muszą być przetwarzane w kolejności, a zespół analityczny chce czasem odtworzyć ostatnie 7 dni danych. Co wybrać?
kolejność per klucz + replay
Odpowiedź
Kinesis Data Streams z partition key = ID konta i retencją ≥ 7 dni.
Dlaczego nie: SQS FIFO daje kolejność, ale skasowanej wiadomości nie odtworzysz. SNS nie przechowuje danych. Firehose nie ma replay.
Ruch strumienia jest nieprzewidywalny: cisza przez większość dnia i nagłe skoki. Zespół nie chce planować liczby shardów.
unpredictable, no capacity planning
Odpowiedź
Kinesis Data Streams w trybie on-demand.
Dlaczego nie: provisioned + własne skalowanie Lambdą to więcej pracy. Firehose nie da konsumentów w czasie rzeczywistym.
🔬 Głębiej: duże rekordy, on-demand, limity kont
Rekordy do 10 MiB (październik 2025): domyślny maksymalny rozmiar rekordu dla nowych i istniejących strumieni to nadal 1 MiB. Podnosisz go przez UpdateMaxRecordSize. Funkcja jest pomyślana dla sporadycznych dużych rekordów obok zwykłego ruchu do 1 MiB, a nie do ciągłego strumienia dużych rekordów. Zapis do sharda dalej ograniczają 1 MB/s i 1 000 rekordów/s (duże rekordy korzystają z burst capacity).
On-demand: domyślnie do 50 strumieni on-demand na konto. W największych regionach strumień skaluje się do 10 GB/s zapisu, w pozostałych do 200 MB/s. Domyślny limit shardów w provisioned: 20 000 na konto w us-east-1, us-west-2, eu-west-1, a w innych regionach 1 000 lub 6 000.
Rejestracja konsumenta EFO: do 20 na strumień (więcej w trybie On-demand Advantage). Metryki warte zapamiętania: IncomingBytes, IncomingRecords, WriteProvisionedThroughputExceeded, ReadProvisionedThroughputExceeded, GetRecords.IteratorAgeMilliseconds.
- Shard: zapis 1 MB/s lub 1 000 rekordów/s, odczyt 2 MB/s. Partition key (MD5) → shard → kolejność per klucz.
- PTEE = gorący shard lub za mało shardów → lepszy klucz, backoff, więcej shardów (split) lub on-demand.
- Retencja 24 h – 365 dni, replay. EFO: 2 MB/s na konsumenta, ~70 ms, push.
- KCL: lease table w DynamoDB, workerów ≤ shardów. Lambda: w kolejności per shard,
ParallelizationFactordo 10. - Firehose = near real time do S3/Redshift/OpenSearch/Splunk/HTTP, bufor, transformacja Lambdą, bez replay. Flink = analiza strumieni w czasie rzeczywistym.
AWS Step Functions: dyrygent procesu
kroki, ponowienia i obsługa błędów w jednym diagramieW orkiestrze każdy muzyk zna swoją partię, ale to dyrygent decyduje, kto gra teraz, co się dzieje po pomyłce i kiedy utwór się kończy. Step Functions jest takim dyrygentem dla usług AWS. Opisujesz proces jako state machine (maszynę stanów) w JSON-ie zwanym Amazon States Language (ASL), a usługa wykonuje kolejne kroki, pamięta stan, ponawia błędy i pokazuje każde wykonanie na diagramie.
Bez Step Functions logikę „najpierw A, potem B, przy błędzie C, ponów 3 razy” piszesz w kodzie Lambdy, która woła inne Lambdy i czeka (płacisz za czekanie i łatwo o limit 15 minut). Ze Step Functions każdy krok jest małą funkcją lub bezpośrednim wywołaniem usługi (DynamoDB, SQS, SNS, ECS, Glue, Bedrock, ponad 200 usług przez SDK integrations), a przepływ i obsługa błędów są w definicji maszyny.
To orkiestracja: jeden centralny koordynator zna cały proces. Przeciwieństwem jest choreografia: usługi reagują na zdarzenia (np. przez EventBridge) i nikt nie widzi całości (więcej w Wzorcach).
1.1.11.1.51.1.13
- Standard: do 1 roku, exactly-once, płatność za przejścia stanów (state transitions), historia wykonania w API i konsoli przez 90 dni. Express: do 5 minut, płatność za liczbę wykonań, czas i pamięć, historia tylko w CloudWatch Logs. Express async = at-least-once, Express sync = at-most-once. Typu nie zmienisz po utworzeniu.
- Retry:
ErrorEquals,IntervalSeconds(domyślnie 1),MaxAttempts(domyślnie 3, 0 = bez ponowień),BackoffRate(domyślnie 2.0), opcjonalnieMaxDelaySecondsiJitterStrategy. Catch:ErrorEquals,Next,ResultPath. Najpierw działają retriery, potem catch. States.ALLłapie wszystkie znane błędy, musi być sam i ostatni.States.Timeout: przekroczonyTimeoutSecondsalbo brak heartbeatu wHeartbeatSeconds.States.TaskFailedłapie wszystko oprócz timeoutu.- Wzorce integracji: Request Response (domyślny), Run a Job (
.sync, czekaj na zakończenie zadania), Wait for Callback (.waitForTaskToken, czekaj naSendTaskSuccess/SendTaskFailurez tokenem). Express obsługuje tylko Request Response. - Map: Inline (do 40 równoległych iteracji, historia w rodzicu) albo Distributed (do 10 000 równoległych wykonań-dzieci, dane z S3, np. miliony obiektów lub wiersze CSV).
- Limit danych między stanami: 256 KiB. Większe dane trzymaj w S3 i przekazuj ARN lub klucz. Historia: max 25 000 zdarzeń na wykonanie.
Payment.GatewayTimeout są wymyślone.Standard kontra Express
| Cecha | Standard | Express |
|---|---|---|
| Maksymalny czas | 1 rok | 5 minut |
| Semantyka | exactly-once (krok nie wykona się dwa razy, chyba że ma Retry) | async: at-least-once · sync: at-most-once |
| Cena | za każde przejście stanu | za liczbę wykonań, czas trwania i pamięć |
| Historia | w API i konsoli przez 90 dni, wizualny debug | tylko przez CloudWatch Logs (trzeba włączyć logowanie) |
| Start | StartExecution (idempotentny dla tej samej nazwy i wejścia) | async: StartExecution · sync: StartSyncExecution (czeka na wynik) |
| Wzorce integracji | Request Response, .sync, .waitForTaskToken | tylko Request Response |
| Kiedy | długie, audytowalne procesy biznesowe, human approval, zadania ETL | duży wolumen, krótkie przetwarzanie: IoT, strumienie, backend API |
Typy stanów
| Stan | Co robi | Kiedy |
|---|---|---|
Task | Wykonuje pracę: Lambda, wywołanie usługi AWS, activity, HTTP endpoint | Każdy krok, który coś robi |
Choice | Rozgałęzienie warunkowe (Choices + Default) | if/else na danych |
Parallel | Uruchamia stałe gałęzie równolegle i czeka na wszystkie | Niezależne kroki naraz |
Map | Te same kroki dla każdego elementu tablicy lub zbioru z S3 | Przetwarzanie listy, plików, wierszy CSV |
Wait | Czeka określoną liczbę sekund albo do znacznika czasu (Seconds, Timestamp, wersje *Path) | Opóźnienie, harmonogram w procesie |
Pass | Przekazuje lub przekształca dane bez pracy | Wstrzyknięcie stałych, debugowanie |
Succeed / Fail | Kończy wykonanie sukcesem lub błędem (Error, Cause) | Jawne zakończenie gałęzi |
Obsługa błędów: Retry i Catch
"ChargeCard": {
"Type": "Task",
"Resource": "arn:aws:states:::lambda:invoke",
"Arguments": { "FunctionName": "charge-card", "Payload": "{% $states.input %}" },
"TimeoutSeconds": 30,
"Retry": [
{ "ErrorEquals": ["Lambda.ServiceException", "Lambda.TooManyRequestsException"],
"IntervalSeconds": 1, "MaxAttempts": 3, "BackoffRate": 2, "JitterStrategy": "FULL" },
{ "ErrorEquals": ["Payment.GatewayTimeout"], "IntervalSeconds": 2, "MaxAttempts": 3, "BackoffRate": 2 }
],
"Catch": [
{ "ErrorEquals": ["States.ALL"], "Next": "NotifyFailure", "Output": { "error": "{% $states.errorOutput %}" } }
],
"Next": "ShipOrder"
}
// JSONPath: zamiast "Output" w Catch użyjesz "ResultPath": "$.error" (zachowa wejście i dopisze błąd)
- Retriery są sprawdzane po kolei, wygrywa pierwszy pasujący
ErrorEquals. Odstęp przed n-tą próbą toIntervalSeconds × BackoffRaten−1(2 s, 4 s, 8 s przy 2 i 2.0).MaxDelaySecondsogranicza odstęp z góry, aJitterStrategy: FULLgo losuje. - Catch jest dostępny w stanach
Task,ParalleliMap. Bez Catch nieobsłużony błąd kończy całe wykonanie jakoFAILED. ResultPathw Catch (JSONPath) decyduje, gdzie trafi obiekt błędu. Domyślnie$nadpisuje całe wejście, a"$.error"zachowuje dane i dopisuje błąd.States.ALLnie łapieStates.Runtime(np. zła ścieżka JSONPath na null) aniStates.DataLimitExceeded(przekroczone 256 KiB).- Błędy Lambdy: obsługuj przejściowe
Lambda.ServiceException,Lambda.AWSLambdaException,Lambda.SdkClientExceptionretry'em (zaleca to dokumentacja). Timeout funkcji pojawia się jakoSandbox.TimedoutlubLambda.Unknown. Wyjątek rzucony w kodzie funkcji ma nazwę klasy błędu, np.InsufficientFundsError, i możesz go wpisać wErrorEquals.
Wzorce integracji z usługami
| Opcja | Co robi | Kiedy |
|---|---|---|
Request Response (np. arn:aws:states:::sns:publish) | Wywołuje API i od razu przechodzi dalej | Wysłanie wiadomości, zapis do DynamoDB |
Run a Job .sync (np. ecs:runTask.sync, glue:startJobRun.sync, states:startExecution.sync) | Uruchamia zadanie i czeka, aż się skończy | Batch, ECS task, Glue job, zagnieżdżona maszyna |
Wait for Callback .waitForTaskToken | Przekazuje $$.Task.Token (JSONata: $states.context.Task.Token) do usługi i pauzuje, aż ktoś wywoła SendTaskSuccess / SendTaskFailure z tym tokenem. Opcjonalnie SendTaskHeartbeat + HeartbeatSeconds | Zatwierdzenie przez człowieka, system zewnętrzny, długa praca poza AWS (do limitu 1 roku) |
| Activity | Worker (EC2, kontener, serwer on-premises) sam polluje GetActivityTask i odsyła wynik | Starsze rozwiązanie dla workerów poza Lambdą |
"WaitForApproval": {
"Type": "Task",
"Resource": "arn:aws:states:::sqs:sendMessage.waitForTaskToken",
"Parameters": { "QueueUrl": "https://sqs…/approvals",
"MessageBody": { "orderId.$": "$.orderId", "taskToken.$": "$$.Task.Token" } },
"HeartbeatSeconds": 3600,
"Next": "Ship"
}
# zatwierdzający system (np. Lambda za API Gateway) kończy krok:
aws stepfunctions send-task-success --task-token "$TOKEN" --task-output '{"approved":true}'
Token musi wysłać principal z tego samego konta. Jeśli krok z tokenem przekroczy timeout, przy ponowieniu powstaje nowy token.
Map, dane i JSONata
- Inline Map (domyślny): wejście to tablica JSON z poprzedniego kroku, do 40 równoległych iteracji (
MaxConcurrency), historia iteracji w historii rodzica, więc liczy się do limitu 25 000 zdarzeń. - Distributed Map: każda iteracja to osobne wykonanie-dziecko, do 10 000 równolegle.
ItemReaderczyta z S3 (lista obiektów, plik JSON, CSV),ItemBatchergrupuje elementy,ResultWriterzapisuje wyniki do S3,ToleratedFailurePercentagepozwala na część porażek. Wybierz go, gdy dane > 256 KiB, historia przekroczyłaby 25 000 zdarzeń albo potrzebujesz > 40 równoległych iteracji. - Dane: w JSONPath (klasycznym) przepływ kształtują
InputPath→Parameters→ResultSelector→ResultPath→OutputPath, a klucze dynamiczne kończą się na.$. W JSONata (od listopada 2024, konsola zaleca go dla nowych maszyn:"QueryLanguage": "JSONata") zostają dwa pola:ArgumentsiOutput, a wyrażenia piszesz w{% … %}. Zmienne (Assign) pozwalają przekazać wartość do dalszych stanów bez przepychania jej przez wszystkie wejścia i wyjścia. Egzaminy próbne zwykle pokazują składnię JSONPath. - Testowanie:
TestStateAPI testuje pojedynczy stan bez wdrażania maszyny. Workflow Studio to graficzny edytor w konsoli. Wersje i aliasy maszyny pozwalają na bezpieczne wdrożenia.
Retrier: IntervalSeconds: 3, MaxAttempts: 4, BackoffRate: 2. Krok cały czas zwraca ten sam błąd. Po ilu sekundach od pierwszej porażki Step Functions przejdzie do Catch (pomijając czas samych prób)?
Odpowiedź
3 + 6 + 12 + 24 = 45 s. Cztery ponowienia, każde odstęp × 2. Gdy czwarte ponowienie (piąta próba w sumie) też się nie uda, retrier się wyczerpuje i błąd trafia do pasującego Catch.
- „Express dla procesu z zatwierdzeniem przez człowieka (dni)” — Express trwa max 5 min i nie obsługuje
.waitForTaskToken. Wybierz Standard. - „Standard dla 100 000 krótkich zdarzeń na sekundę” — drogo (każde przejście stanu kosztuje). Duży wolumen i krótkie wykonania to Express.
States.ALLna początku listy w Catch — musi być sam i ostatni.- Catch bez
ResultPath(JSONPath) — obiekt błędu nadpisze całe wejście i stan awaryjny nie dostanieorderId. Użyj"ResultPath": "$.error". - „Lambda orkiestrująca inne Lambdy” — płacisz za czekanie, ryzykujesz limit 15 min i sam piszesz retry. Pytanie o „least code / visual workflow / error handling” wskazuje na Step Functions.
- Przekazywanie dużych plików między stanami — limit 256 KiB. Zapisz w S3 i przekaż klucz.
- „Express ma historię w konsoli przez 90 dni” — nie, historia Express jest tylko w CloudWatch Logs.
Proces zamówienia wymaga zatwierdzenia przez kierownika, co może potrwać kilka dni. Po zatwierdzeniu w aplikacji webowej proces ma kontynuować. Jak to zbudować?
human approval, days, resume
Odpowiedź
Standard workflow z krokiem .waitForTaskToken (np. SNS lub SQS z tokenem w treści), a aplikacja zatwierdzająca woła SendTaskSuccess lub SendTaskFailure.
Dlaczego nie: Express kończy się po 5 min. Stan Wait z pollingiem to strata przejść i opóźnienie. Lambda czekająca w pętli ma limit 15 min.
Krok wywołujący zewnętrzne API czasem zwraca błąd przejściowy. Trzeba ponowić 3 razy z rosnącym odstępem, a potem wysłać powiadomienie i zakończyć proces porażką, bez dopisywania kodu do funkcji.
retry with backoff, fallback, no code
Odpowiedź
Pole Retry (MaxAttempts 3, BackoffRate 2) i Catch → stan SNS publish → Fail.
Dlaczego nie: pętla retry w Lambdzie to kod do utrzymania. DLQ Lambdy dotyczy wywołań asynchronicznych, a nie kroków maszyny.
Trzeba przetworzyć 5 milionów plików CSV w S3, każdy przez Lambdę, z dużą równoległością i tolerancją na 1% porażek.
miliony obiektów S3, wysoka równoległość
Odpowiedź
Distributed Map z ItemReader na S3, MaxConcurrency do 10 000 i ToleratedFailurePercentage = 1.
Dlaczego nie: Inline Map ma 40 równoległych iteracji, wejście ograniczone do 256 KiB i limit historii 25 000 zdarzeń.
Backend API przetwarza 50 000 krótkich (2 s) żądań na sekundę przez kilkuetapowy workflow i musi zwrócić wynik w odpowiedzi HTTP. Co jest najtańsze?
high volume, short, synchronous result
Odpowiedź
Synchronous Express Workflow (StartSyncExecution, np. z integracji API Gateway).
Dlaczego nie: Standard nalicza opłatę za każde przejście stanu i nie zwraca wyniku synchronicznie. Async Express nie zwraca wyniku w odpowiedzi.
Krok uruchamia zadanie AWS Batch trwające 2 godziny, a następny krok ma ruszyć dopiero po jego zakończeniu. Jak, bez pollingu w kodzie?
wait for job to complete
Odpowiedź
Integracja arn:aws:states:::batch:submitJob.sync (Run a Job) w Standard workflow.
Dlaczego nie: Request Response przejdzie dalej od razu. Pętla Wait + DescribeJobs działa, ale to więcej stanów i kosztów.
🔬 Głębiej: idempotencja startu, Express i Pipes, HTTP Task
StartExecution jest idempotentny dla Standard: ta sama nazwa i to samo wejście co działające wykonanie zwraca to samo wykonanie, a inne wejście daje ExecutionAlreadyExists. Nazwę możesz użyć ponownie 90 dni po zamknięciu. Dla Express StartExecution nie jest idempotentny.
Synchroniczne Express wywołane z konsoli kończy się po 60 s. Pełne 5 minut masz przez SDK lub CLI. EventBridge Pipes jako enrichment obsługuje tylko Express.
HTTP Task wywołuje dowolne API HTTPS (uwierzytelnianie przez connection EventBridge), z timeoutem max 60 s. Zagnieżdżona maszyna, która rzuci States.Timeout, w rodzicu pojawia się jako States.TaskFailed. Retrier liczy próby łącznie dla wszystkich wejść do danego stanu w jednym wykonaniu stanu.
Distributed Map uruchamia dzieci jako wykonania Standard albo Express (ExecutionType w ItemProcessor). Wykonania-dzieci mają własną historię, więc nie zjadają limitu rodzica.
- Orkiestracja w ASL: Task, Choice, Parallel, Map, Wait, Pass, Succeed, Fail.
- Standard: 1 rok, exactly-once, płatność za przejścia, historia 90 dni. Express: 5 min, at-least-once (async) / at-most-once (sync), historia w CloudWatch Logs.
- Retry (1 s / 3 próby / ×2 domyślnie) → Catch (
Next,ResultPath).States.ALLsam i ostatni. .syncczeka na zadanie,.waitForTaskTokenczeka naSendTaskSuccess. Express: tylko Request Response.- Inline Map ≤ 40 równolegle. Distributed Map ≤ 10 000, dane z S3. Payload ≤ 256 KiB.
AppSync i Amplify: GraphQL i frontend bez serwerów
klient pyta dokładnie o to, czego potrzebujeW restauracji z REST-em zamawiasz gotowe zestawy: „zestaw 3” to zawsze burger, frytki i napój, nawet jeśli chcesz tylko frytki. Przy GraphQL zamawiasz à la carte: jedno zapytanie mówi dokładnie, które pola chcesz, także z kilku „kuchni” naraz. Kelner (serwer GraphQL) zbiera to od różnych kucharzy (data sources) i podaje na jednym talerzu.
AWS AppSync to zarządzany serwer GraphQL. Definiujesz schemat (typy, query do odczytu, mutation do zapisu, subscription do powiadomień na żywo), a każde pole łączysz z resolverem, który wie, jak pobrać dane z DynamoDB, Lambdy, RDS, OpenSearch, HTTP albo EventBridge. Aplikacje mobilne i webowe dostają jedno API, mniej zapytań sieciowych (koniec z over-fetchingiem i under-fetchingiem) oraz real-time przez WebSockety.
AWS Amplify to zestaw dla deweloperów frontendu. Amplify Hosting buduje i hostuje aplikacje webowe (React, Next.js, Angular, Vue…) prosto z repozytorium Git, z osobnym środowiskiem dla każdej gałęzi i podglądem dla każdego pull requesta. Biblioteki i backend Amplify (Gen 2) konfigurują pod spodem m.in. Cognito, AppSync i S3.
3.3.31.1.62.1.1
- „GraphQL”, „pobierz dane z wielu źródeł jednym zapytaniem”, „real-time updates / subscriptions”, „offline sync dla aplikacji mobilnej” → AppSync.
- Resolvery: unit (jedno źródło) albo pipeline (kilka funkcji po kolei, z handlerem before i after). Język: APPSYNC_JS (JavaScript) albo VTL (Velocity Template Language, starsze mapping templates).
- Autoryzacja:
API_KEY,AWS_IAM,AMAZON_COGNITO_USER_POOLS,OPENID_CONNECT,AWS_LAMBDA. Jeden tryb domyślny plus dodatkowe. Dyrektywy w schemacie, np.@aws_iam,@aws_cognito_user_pools, określają tryb per typ lub pole. Klucz API ważny do 365 dni, nagłówekx-api-key. - Subscriptions są wyzwalane przez mutacje wykonane przez AppSync (dyrektywa
@aws_subscribe(mutations: [...])), a klienci dostają je przez WebSocket. - Caching po stronie serwera: full request, per-resolver albo operation-level. TTL do 3 600 s.
- Amplify Hosting (skill 3.3.3): środowisko per gałąź Git (np.
main= prod,dev= test), PR previews, gałęzie chronione hasłem, własne domeny, atomic deployments, build specamplify.yml.
Schemat, resolver, data source
type Order @aws_cognito_user_pools @aws_iam { id: ID! status: String items: [Item] }
type Query { getOrder(id: ID!): Order }
type Mutation { updateStatus(id: ID!, status: String!): Order }
type Subscription { onStatusChanged(id: ID): Order
@aws_subscribe(mutations: ["updateStatus"]) }
// resolver APPSYNC_JS (unit, data source DynamoDB) dla Query.getOrder
import * as ddb from '@aws-appsync/utils/dynamodb';
export const request = (ctx) => ddb.get({ key: { id: ctx.args.id } });
export const response = (ctx) => ctx.result;
| Opcja (data source) | Co robi | Kiedy |
|---|---|---|
| DynamoDB | Bezpośrednie Get/Put/Query/Scan/Batch/Transact z resolvera, bez Lambdy | Typowe CRUD, najtańsze i najszybsze |
| Lambda | Dowolna logika w kodzie | Logika biznesowa, źródła bez natywnej integracji |
| RDS (relational database) | Zapytania SQL do bazy relacyjnej (Aurora) | Dane relacyjne |
| OpenSearch | Wyszukiwanie pełnotekstowe | Search, filtrowanie |
| HTTP | Wywołanie dowolnego endpointu HTTP/REST | Istniejące API, mikroserwisy |
| EventBridge | Publikowanie zdarzeń na szynę | Mutacja ma wywołać zdarzenie dla innych systemów |
| None | Brak źródła: resolver tylko przekształca dane | Lokalne operacje, „publish” do subskrybentów bez zapisu |
Pipeline resolver: handler before → funkcje (każda z własnym data source, np. „sprawdź uprawnienia w DynamoDB”, potem „zapisz zamówienie”, potem „wyślij zdarzenie”) → handler after. Dane między funkcjami przekazujesz przez ctx.stash i ctx.prev.result.
Autoryzacja, cache, real-time
| Tryb | Co robi | Kiedy |
|---|---|---|
API_KEY | Klucz w nagłówku x-api-key, ważny do 365 dni (można przedłużać) | Publiczne API, prototypy |
AMAZON_COGNITO_USER_POOLS | Token JWT z user pool, w resolverze ctx.identity (np. sub, grupy) | Zalogowani użytkownicy aplikacji, dostęp per grupa |
AWS_IAM | Podpis SigV4 (rola IAM, także gość z Cognito identity pool) | Backendy, inne usługi AWS, użytkownicy niezalogowani przez identity pool |
OPENID_CONNECT | Token z zewnętrznego dostawcy OIDC | Auth0, Okta, własny IdP |
AWS_LAMBDA | Twoja funkcja decyduje na podstawie tokenu | Własna logika autoryzacji |
- Caching: full request caching (klucz z
ctx.argumentsictx.identity), per-resolver caching (wybrane resolvery, własne klucze), operation-level caching (cała odpowiedź zapytania). TTL max 3 600 s. Nowe cache są zawsze szyfrowane (at rest i in transit). Unieważnianie przez API flush lubextensions.evictFromApiCache. - Subscriptions: klient subskrybuje, a AppSync wysyła dane, gdy wykona się wskazana mutacja przez AppSync. Zmiana zapisana bezpośrednio w DynamoDB z pominięciem API nie wywoła subskrypcji (np. trzeba ją przepuścić przez mutację, choćby z data source None). Do czystego pub/sub przez WebSocket służy też nowsze AppSync Events (od marca 2025).
- Offline i konflikty: AppSync ma conflict detection z trzema strategiami: Optimistic Concurrency (odrzuć konflikt), Automerge, Lambda. Korzysta z tego Amplify DataStore w aplikacjach offline-first.
- Inne: Merged APIs (jedno API złożone z API wielu zespołów), Private APIs i integracja z AWS WAF, logi w CloudWatch, śledzenie w X-Ray.
Amplify Hosting i środowiska
| Opcja | Co robi | Kiedy |
|---|---|---|
| Feature branch deployments | Każda podłączona gałąź Git to osobne wdrożenie z własnym URL (https://dev.appid.amplifyapp.com), opcjonalnie z własnym backendem. Można podłączać gałęzie automatycznie według wzorca | Środowiska dev / test / prod, testy integracyjne na zatwierdzonej wersji |
| Web previews (PR previews) | Każdy pull request dostaje tymczasowy URL (i tymczasowy backend dla prywatnych repo), usuwany po zamknięciu PR | Code review, QA przed merge |
| Password-protected branches | Nazwa użytkownika i hasło na gałęzi (lub wszystkich gałęziach) | Ukrycie środowiska testowego przed światem |
| Custom domains | Własna domena (Route 53 lub zewnętrzny DNS) z certyfikatem, subdomeny per gałąź | Produkcja, dev.example.com |
amplify.yml + environment variables | Fazy build (preBuild, build), artifacts.baseDirectory, cache; zmienne środowiskowe per gałąź | Dostosowanie builda, różne endpointy dla gałęzi |
| Atomic deployments, redirects/rewrites, monitoring | Nowa wersja pojawia się w całości albo wcale; reguły przekierowań (np. SPA); metryki i logi dostępu | Bez okien serwisowych, routing SPA |
Amplify Gen 2 definiuje backend w TypeScript (code-first), np. defineAuth (Cognito) i defineData (AppSync + DynamoDB), a wdrożenie tworzy stos CloudFormation. Każdy deweloper może uruchomić własny, odizolowany cloud sandbox poleceniem npx ampx sandbox. W Gen 1 backend zmieniałeś Amplify CLI (amplify add api, amplify push). Wdrożenia i środowiska dla zespołu przez gałęzie: CI/CD i CDK opisują resztę.
Hasło „AWS Amplify” w pytaniu prawie zawsze znaczy jedno z trzech: hosting frontendu z CI/CD z Gita (Amplify Hosting), szybkie dodanie logowania i API do aplikacji mobilnej lub webowej (biblioteki i backend Amplify) albo środowiska per gałąź do testów. Jeśli pytanie dotyczy GraphQL i subskrypcji, odpowiedzią jest AppSync, nawet jeśli konfiguruje go Amplify.
- „API Gateway do GraphQL z subskrypcjami” — API Gateway nie jest serwerem GraphQL. Real-time GraphQL to AppSync (WebSocket API Gateway to inny, niskopoziomowy model).
- Subskrypcja po zapisie bezpośrednio do DynamoDB — nie zadziała. Subskrypcje wyzwalają mutacje AppSync.
API_KEYdla danych per użytkownik — klucz nie identyfikuje użytkownika. Użyj Cognito User Pools (lub OIDC) ictx.identity.- Lambda jako resolver do prostego CRUD na DynamoDB — działa, ale bezpośredni resolver DynamoDB jest tańszy i szybszy.
- „Amplify do hostowania backendu na EC2” — Amplify Hosting służy aplikacjom webowym (statycznym i SSR). Serwer aplikacyjny to Beanstalk, ECS lub Lambda.
- Ręczne kopiowanie aplikacji do środowiska testowego — Amplify tworzy środowisko z gałęzi automatycznie.
Aplikacja mobilna musi pobierać dane profilu z DynamoDB, zamówienia z Aurora i rekomendacje z Lambdy jednym zapytaniem, a ekran zamówienia ma się odświeżać na żywo przy zmianie statusu. Co wybrać?
wiele źródeł, jedno zapytanie, real-time
Odpowiedź
AWS AppSync: schemat GraphQL z resolverami do DynamoDB, RDS i Lambdy oraz subscription na mutację zmiany statusu.
Dlaczego nie: REST API Gateway wymaga wielu wywołań i nie ma subskrypcji GraphQL. Polling przez SQS nie nadaje się do aplikacji mobilnej.
API AppSync ma być dostępne dla zalogowanych użytkowników Cognito, a jedno pole adminNotes tylko dla backendu działającego z rolą IAM. Jak to skonfigurować?
dwa typy klientów, różne pola
Odpowiedź
Domyślny tryb AMAZON_COGNITO_USER_POOLS, dodatkowy AWS_IAM, a pole oznaczone dyrektywą @aws_iam.
Dlaczego nie: dwa osobne API to duplikacja. API_KEY nie rozróżnia klientów.
Zespół frontendu chce, by każdy pull request automatycznie dostawał tymczasowe środowisko do review, a gałąź staging była osobnym środowiskiem chronionym hasłem. Co wymaga najmniej pracy?
preview per PR, środowisko per gałąź
Odpowiedź
Amplify Hosting z włączonymi web previews i podłączoną gałęzią staging z password protection.
Dlaczego nie: S3 + CloudFront + CodePipeline per gałąź to dużo ręcznej konfiguracji. Elastic Beanstalk nie tworzy środowisk z PR.
Odczyty listy produktów przez AppSync są częste i rzadko się zmieniają, a baza jest przeciążona. Jak zmniejszyć obciążenie najmniejszym nakładem?
powtarzalne odczyty, mniej zapytań do źródła
Odpowiedź
Włączyć server-side caching AppSync (per-resolver dla zapytania o produkty, TTL np. 300 s).
Dlaczego nie: DAX wymaga zmian w kodzie dostępu do danych. CloudFront przed AppSync komplikuje sprawę przy zapytaniach POST z autoryzacją.
🔬 Głębiej: Merged APIs, VTL, AppSync Events
Merged APIs: zespoły utrzymują własne źródłowe API (source APIs), a AppSync scala je w jedno API dla klientów. Każdy zespół wdraża zmiany niezależnie.
VTL (mapping templates $util, $ctx) nadal działa i pojawia się w starszych pytaniach. Nowe resolvery pisze się w APPSYNC_JS, które obsługuje tylko podzbiór JavaScript (np. bez try/catch, pętli while i wyrażeń regularnych), z narzędziami z @aws-appsync/utils.
AppSync Events to osobny typ API: kanały pub/sub przez WebSocket bez schematu GraphQL, np. czat lub tablica wyników na żywo.
- AppSync = zarządzany GraphQL: query, mutation, subscription (WebSocket, wyzwalane mutacjami).
- Resolvery unit/pipeline w APPSYNC_JS lub VTL. Data sources: DynamoDB, Lambda, RDS, OpenSearch, HTTP, EventBridge, None.
- Auth: API key (≤ 365 dni), Cognito User Pools, IAM, OIDC, Lambda. Wiele trybów naraz, dyrektywy w schemacie.
- Cache: full request / per-resolver / operation-level, TTL ≤ 1 h.
- Amplify Hosting: środowisko per gałąź, PR previews, hasło na gałęzi, własne domeny,
amplify.yml. Gen 2: backend w TypeScript, cloud sandbox per deweloper.
API i krawędź sieci
Jak wystawić backend światu: API Gateway (budowa, stage'e, bezpieczeństwo, wydajność) i CloudFront (cache na brzegu sieci, prywatne treści, funkcje na krawędzi). Po tej części rozpoznasz w pytaniu, czy chodzi o transformację żądania, o routing między środowiskami, czy o klucz cache.
API Gateway: budowa API
REST vs HTTP vs WebSocket, proxy vs non-proxy, VTL, walidacja, CORSAmazon API Gateway to „recepcja” przed Twoim backendem. Klient rozmawia tylko z recepcją, a ona sprawdza przepustkę, poprawia formularz, przekazuje sprawę do właściwego działu (Lambda, HTTP, usługa AWS) i oddaje odpowiedź. Każda decyzja na egzaminie sprowadza się do pytania: ile pracy wykonuje recepcja, a ile backend.
W REST API żądanie przechodzi przez cztery okienka: Method Request (autoryzacja, walidacja, klucz API), Integration Request (mapowanie na format backendu), backend, Integration Response (mapowanie odpowiedzi, wybór kodu statusu) i Method Response (co klient może dostać). W integracji proxy dwa środkowe okienka są zamknięte: żądanie leci do backendu w całości, a backend sam składa odpowiedź HTTP.
1.1.63.2.2
- REST API ma najwięcej funkcji: API keys i usage plans, cache, walidację żądań, transformację body (VTL), mock, canary, custom gateway responses, WAF, resource policies, X-Ray, execution logs, endpointy edge-optimized i private. HTTP API jest prostsze i tańsze: JWT authorizer, automatyczne deploymenty, integracja z Cloud Map. WebSocket API służy do komunikacji dwukierunkowej (czat, powiadomienia na żywo).
- Lambda proxy (
AWS_PROXY): Lambda dostaje całe żądanie jako event i musi zwrócić{statusCode, headers, body, isBase64Encoded}. Zły format kończy się błędem 502 Bad Gateway. - Non-proxy (custom) integration: transformujesz żądanie i odpowiedź mapping templates (VTL:
$input,$context,$stageVariables,$util) i mapujesz błędy backendu na kody HTTP (regex na integration response,$context.responseOverride.status). - Mock integration zwraca odpowiedź bez backendu. Przydaje się do testów, do prototypu kontraktu API i do metody
OPTIONSdla CORS. - Request validation (validator + model JSON Schema draft 4) odrzuca złe żądania kodem 400, zanim backend cokolwiek zobaczy, więc nie płacisz za wywołanie Lambdy.
- CORS: przy integracji non-proxy API Gateway zwraca nagłówki (
OPTIONS+ mock). Przy proxy to Twoja Lambda musi zwrócićAccess-Control-Allow-Origin(i pozostałe nagłówki). „Enable CORS” w konsoli tego nie załatwi. - Endpoint edge-optimized (domyślny dla REST, idzie przez CloudFront POP), Regional (klienci w tym samym Regionie albo własna dystrybucja CloudFront), private (tylko z VPC przez interface VPC endpoint).
REST API vs HTTP API vs WebSocket API
Na egzaminie wybór typu API zwykle rozstrzyga jedna funkcja wymieniona w pytaniu. Szukaj słów „cache”, „API key”, „usage plan”, „request validation”, „transform body”, „WAF”, „canary”, „private endpoint” albo „X-Ray” (wszystkie oznaczają REST). Słowa „najtańsze”, „najniższe opóźnienie”, „JWT/OIDC authorizer” wskazują HTTP API.
| Funkcja | REST API | HTTP API |
|---|---|---|
| Endpoint edge-optimized / Regional / private | ✔ / ✔ / ✔ | ✖ / ✔ / ✖ |
| Autoryzacja IAM (SigV4), Lambda authorizer, Cognito | ✔ (Cognito jako COGNITO_USER_POOLS) | ✔ (Cognito przez JWT authorizer) |
| JWT authorizer (natywny OIDC/OAuth 2.0) | ✖ (zrób to Lambda authorizerem) | ✔ |
| Resource policy, AWS WAF, certyfikat do backendu | ✔ | ✖ |
| Mutual TLS na custom domain | ✔ | ✔ |
| API keys, usage plans, throttling per klient | ✔ | ✖ |
| Cache odpowiedzi | ✔ | ✖ |
| Request validation, transformacja body (VTL), mock | ✔ | ✖ (transformacja tylko parametrów) |
| Canary release, custom gateway responses, test invoke w konsoli | ✔ | ✖ |
| Automatyczne deploymenty (auto-deploy stage'a) | ✖ | ✔ |
| Execution logs, X-Ray, access logs do Firehose | ✔ | ✖ (tylko access logs do CloudWatch) |
| Prywatna integracja z AWS Cloud Map | ✖ | ✔ |
| Response streaming | ✔ | ✖ |
| Cena | wyższa | niższa („minimal features … lower price”) |
WebSocket API utrzymuje stałe połączenie. Trasy wybiera route selection expression, np. $request.body.action. Trasy specjalne: $connect (tu jedyne miejsce na autoryzację, przy porażce klient dostaje 401/403), $disconnect (best-effort, bo połączenie już jest zamknięte) i $default (gdy nic nie pasuje). Backend odpisuje klientowi przez @connections API: POST (wyślij wiadomość), GET (status połączenia) i DELETE (rozłącz) na https://{api-id}.execute-api.{region}.amazonaws.com/{stage}/@connections/{connection_id}. Potrzebne uprawnienie to execute-api:ManageConnections. GoneException oznacza, że klient już się rozłączył. Limity: ramka 32 KB, wiadomość 128 KB, połączenie maks. 2 h, rozłączenie po 10 min bezczynności.
Typy endpointów
| Opcja | Co robi | Kiedy |
|---|---|---|
| Edge-optimized (domyślny dla REST) | ruch wchodzi przez najbliższy POP CloudFront (dystrybucja zarządzana przez AWS); nagłówki dostają wielkie litery (Cookie) | klienci rozproszeni po świecie; certyfikat custom domain musi być w us-east-1 |
| Regional | endpoint w jednym Regionie, nagłówki bez zmian | klienci w tym samym Regionie (EC2, inne usługi), własny CloudFront przed API, multi-Region z Route 53 |
| Private | dostęp tylko z VPC przez interface VPC endpoint (execute-api) + resource policy | wewnętrzne mikroserwisy, API niewidoczne z internetu |
Proxy vs non-proxy: kto składa odpowiedź
| Typ integracji | Co robi | Kiedy |
|---|---|---|
AWS_PROXY (Lambda proxy) | cały request (path, query, headers, body, requestContext, stageVariables) trafia do Lambdy jako event; brak mapping templates | domyślny wybór, najmniej konfiguracji, logika HTTP w kodzie |
AWS (non-proxy, custom) | mapping templates w obie strony, mapowanie błędów na kody | wywołanie usługi AWS bez Lambdy (np. PutItem w DynamoDB, SendMessage do SQS), zmiana formatu dla starego klienta |
HTTP_PROXY | przekazuje żądanie do endpointu HTTP bez zmian | fasada przed istniejącym serwisem HTTP |
HTTP | endpoint HTTP + mapping templates | stary backend wymaga innego formatu |
MOCK | API Gateway sam generuje odpowiedź (request template zwykle {"statusCode": 200}) | testy i rozwój front-endu bez backendu, preflight CORS |
// Odpowiedź Lambdy w integracji proxy (inny kształt = 502)
return {
statusCode: 201,
headers: { "Content-Type": "application/json",
"Access-Control-Allow-Origin": "https://app.example.com" },
body: JSON.stringify({ id: "42" }), // body MUSI być stringiem
isBase64Encoded: false
};
Błędy Lambdy przy integracji z API Gateway: gdy Lambda API odrzuci wywołanie (np. brak uprawnień, throttling), API Gateway zwraca 500. Gdy funkcja rzuci wyjątek albo zwróci zły format, zwraca 502. W obu przypadkach klient widzi {"message": "Internal server error"}. Przekroczony czas integracji daje 504 (INTEGRATION_TIMEOUT).
Mapping templates (VTL) i nadpisywanie kodów statusu
Mapping template to szablon w Velocity Template Language przypisany do Content-Type. Najważniejsze zmienne:
| Zmienna | Co daje |
|---|---|
$input.body, $input.json('$.pets'), $input.path('$.pets') | surowe body, fragment JSON jako string, fragment jako obiekt (JSONPath) |
$input.params('name') | parametr z path, query albo nagłówka |
$context.requestId, $context.identity.sourceIp, $context.authorizer.claims, $context.authorizer.principalId | metadane żądania i wynik autoryzacji |
$stageVariables.env | zmienna stage'a (patrz rozdział 26) |
$util.escapeJavaScript(), $util.base64Encode(), $util.parseJson() | funkcje pomocnicze |
$context.responseOverride.status, $context.responseOverride.header.X | nadpisanie kodu statusu i nagłówków odpowiedzi |
## Integration response template: backend zawsze zwraca 200,
## ale gdy body zawiera "error", klient ma dostać 400
#set($inputRoot = $input.path('$'))
$input.json("$")
#if($inputRoot.toString().contains("error"))
#set($context.responseOverride.status = 400)
#end
Druga metoda to integration responses z regex (selectionPattern). Regex jest dopasowywany do kodu HTTP backendu, a przy Lambdzie do errorMessage. Pusta reguła działa jako odpowiedź domyślna. Przykład: .*NotFound.* → method response 404.
Passthrough behavior decyduje, co zrobić z body, gdy żaden szablon nie pasuje do Content-Type. WHEN_NO_MATCH przepuszcza je bez zmian. WHEN_NO_TEMPLATES przepuszcza tylko wtedy, gdy nie zdefiniowano żadnego szablonu, a w przeciwnym razie odrzuca żądanie kodem 415 Unsupported Media Type. NEVER zawsze odrzuca je kodem 415. Limity: szablon do 300 KB, pętla #foreach do 1000 iteracji.
Walidacja żądań, modele i gateway responses
Request validator ma trzy warianty: tylko parametry, tylko body, albo parametry i body. Walidacja parametrów sprawdza wyłącznie, czy wymagane parametry (path, query, nagłówki) są obecne i niepuste. Typu ani formatu nie sprawdza. Walidacja body porównuje payload z modelem, czyli JSON Schema draft 4 przypisanym do Content-Type. Porażka daje 400 (BAD_REQUEST_BODY albo BAD_REQUEST_PARAMETERS), a backend nie zostaje wywołany. Modele służą też do generowania typowanych SDK.
Gateway responses to odpowiedzi, które API Gateway generuje sam, bez udziału backendu. Możesz zmienić ich kod, nagłówki (np. dodać CORS do błędów 4xx) i body. Najważniejsze typy:
| Typ | Kod | Kiedy |
|---|---|---|
DEFAULT_4XX / DEFAULT_5XX | – | wszystkie nieobsłużone 4xx / 5xx |
MISSING_AUTHENTICATION_TOKEN | 403 | brak tokenu albo nieistniejąca ścieżka/metoda (częsta zagadka „403 przy literówce w URL”) |
UNAUTHORIZED / ACCESS_DENIED / EXPIRED_TOKEN | 401 / 403 / 403 | authorizer odmówił, token wygasł |
INVALID_API_KEY / INVALID_SIGNATURE / WAF_FILTERED | 403 | zły klucz API, zły podpis SigV4, blokada WAF |
BAD_REQUEST_BODY / BAD_REQUEST_PARAMETERS | 400 | walidacja nie przeszła |
THROTTLED / QUOTA_EXCEEDED | 429 | throttling albo wyczerpany limit usage planu |
REQUEST_TOO_LARGE / UNSUPPORTED_MEDIA_TYPE | 413 / 415 | payload > 10 MB, brak pasującego szablonu |
INTEGRATION_FAILURE / INTEGRATION_TIMEOUT | 504 / 504 | backend nieosiągalny, przekroczony timeout |
AUTHORIZER_FAILURE / AUTHORIZER_CONFIGURATION_ERROR / API_CONFIGURATION_ERROR | 500 | authorizer się wywrócił, błędna konfiguracja |
CORS i binary media types
Analogia: przeglądarka to ochroniarz, który przed wpuszczeniem gościa z innej domeny (origin) dzwoni do serwera z pytaniem „czy ten gość może wejść i z czym?”. Telefon to preflight OPTIONS, a odpowiedź to nagłówki Access-Control-Allow-Origin, -Methods i -Headers. Prosty GET/POST nie wymaga preflightu, ale odpowiedź nadal musi mieć Access-Control-Allow-Origin.
- Non-proxy: „Enable CORS” tworzy metodę
OPTIONSz integracją mock i dodaje nagłówki do method/integration responses. Po zmianie trzeba zrobić redeploy. - Proxy (Lambda/HTTP): integration response nie istnieje, więc to backend zwraca nagłówki CORS, także w odpowiedziach na błędy.
- Błędy generowane przez samo API Gateway (4xx/5xx, np. 403 z authorizera) nie mają nagłówków CORS, dopóki nie dodasz ich do gateway responses
DEFAULT_4XX/DEFAULT_5XX. Inaczej przeglądarka pokaże błąd CORS zamiast prawdziwego błędu. - HTTP API ma CORS jako prostą konfigurację na poziomie API.
Binary media types (obrazy, PDF): dodaj typy MIME do listy binaryMediaTypes API (np. image/png albo */*). Przy Lambda proxy funkcja musi zwrócić body zakodowane w base64 i isBase64Encoded: true. API Gateway sprawdza pierwszy nagłówek Accept klienta. Przy non-proxy konwersją steruje contentHandling: CONVERT_TO_BINARY albo CONVERT_TO_TEXT. Limit payloadu to 10 MB, więc większe pliki wysyłaj do S3 przez presigned URL (patrz S3).
- „Włączyłem CORS w konsoli, a przeglądarka dalej blokuje”: przy Lambda proxy nagłówki musi zwrócić funkcja. Konsola konfiguruje tylko
OPTIONSi odpowiedzi non-proxy. - 502 przy Lambda proxy to prawie zawsze zły kształt odpowiedzi (brak
statusCode,bodyjako obiekt zamiast stringa) albo wyjątek w funkcji. To nie jest timeout, bo timeout daje 504. - „Użyj HTTP API, bo jest tańsze”, gdy pytanie wymaga cache, API keys, walidacji, WAF albo private endpointu. Te funkcje ma tylko REST API.
- Walidacja w Lambdzie jako odpowiedź na „odrzuć złe żądania najmniejszym kosztem”: request validator odrzuca je przed wywołaniem backendu i za darmo.
- Mapping templates przy proxy: integracja proxy ich nie używa. Jeśli trzeba zmienić format body, potrzebujesz non-proxy.
- 403 „Missing Authentication Token” przy publicznym API często oznacza błędną ścieżkę albo metodę (albo API bez deploymentu), a nie problem z tokenem.
AWS bez Lambdy to dobry pomysł?SendMessage do SQS). Mapping template + rola IAM dla API Gateway robią to samo bez kodu, cold startów i kosztu Lambdy.Lambda za REST API z integracją proxy działa w teście konsoli Lambdy, ale klient dostaje 502 Bad Gateway. Funkcja zwraca {"message": "ok"}. Co poprawić?
proxy · 502 · format odpowiedzi
Odpowiedź
Zwracać obiekt z statusCode, headers i body jako stringiem. Przy proxy API Gateway wymaga tego formatu, a każdy inny kształt kończy się 502.
Dlaczego nie: zwiększenie timeoutu (timeout to 504), włączenie CORS (to inny objaw w przeglądarce), dodanie mapping template (proxy go nie używa).
Stary klient wysyła XML, a nowa Lambda oczekuje JSON. Zespół nie chce zmieniać ani klienta, ani funkcji. Co zrobić?
transformacja · bez zmian w kodzie
Odpowiedź
Integracja non-proxy z mapping template (VTL) na integration request, która przekłada XML na JSON, i odwrotny szablon na integration response.
Dlaczego nie: Lambda proxy (brak transformacji), HTTP API (nie transformuje body), Lambda@Edge (inna warstwa, zbędna złożoność).
API musi odrzucać żądania POST /orders bez pola quantity albo z ujemną wartością, zanim zostanie wywołana Lambda. Rozwiązanie ma wymagać najmniej wysiłku.
przed backendem · najmniej wysiłku
Odpowiedź
Model JSON Schema (required, minimum) + request validator „Validate body” na metodzie. Złe żądania dostają 400 bez wywołania Lambdy.
Dlaczego nie: walidacja w kodzie (Lambda i tak jest wywoływana), WAF (nie zna schematu biznesowego), Lambda authorizer (służy do autoryzacji, nie do walidacji).
SPA na https://app.example.com woła API (Lambda proxy). Preflight przechodzi, ale fetch kończy się błędem CORS przy każdej odpowiedzi 200.
proxy · nagłówki w odpowiedzi
Odpowiedź
Lambda musi dodawać Access-Control-Allow-Origin (i ewentualnie -Credentials) do każdej odpowiedzi. Przy proxy API Gateway nie dokleja nagłówków do odpowiedzi backendu.
Dlaczego nie: ponowne „Enable CORS” (dotyczy tylko OPTIONS), zmiana na edge-optimized (bez związku), binary media types (bez związku).
Aplikacja potrzebuje czatu, w którym serwer wysyła wiadomości do konkretnych podłączonych klientów. Jak backend (Lambda) wyśle wiadomość do klienta?
dwukierunkowo · push do klienta
Odpowiedź
WebSocket API + zapis connectionId w $connect (np. w DynamoDB), a potem POST na @connections/{connectionId} (PostToConnection) z uprawnieniem execute-api:ManageConnections.
Dlaczego nie: REST API z long pollingiem (nieefektywne), SNS (nie dociera do przeglądarki), HTTP API (nie ma stałego połączenia).
🔬 Głębiej: rzadkie szczegóły budowy API
- W evencie Lambda proxy (format 1.0 dla REST) są pola
headersimultiValueHeadersorazqueryStringParametersimultiValueQueryStringParameters. HTTP API używa formatu payloadu 2.0 (rawPath,cookies; w konsoli domyślnie, a w CLI/CloudFormation/SDK trzeba podaćpayloadFormatVersion) i pozwala Lambdzie zwrócić sam JSON (API Gateway sam ułoży odpowiedź 200). - Endpoint edge-optimized zamienia nazwy nagłówków na wielkie litery. Regional i private przekazują je bez zmian.
- Konsola nie ustawi
contentHandlingdla integracji MOCK i prywatnych. Trzeba to zrobić przez CLI, CloudFormation albo SDK. - Import i eksport: REST API możesz zaimportować z OpenAPI 2.0/3.0 i wyeksportować (
aws apigateway get-export --export-type oas30|swagger --parameters extensions='apigateway', z rozszerzeniamix-amazon-apigateway-*), także z rozszerzeniami Postman (extensions=postman). - Limity REST: nagłówki łącznie 20 480 B (private API: 8000 B), payload 10 MB. HTTP API: request line + nagłówki 10 240 B.
- REST = pełny zestaw funkcji (cache, API keys, walidacja, VTL, WAF, private). HTTP = tańsze, JWT authorizer. WebSocket =
$connect/$disconnect/$default+@connections. - Proxy: backend zwraca
statusCode/headers/body, zły format = 502. Non-proxy: mapping templates (VTL) i regex na kody. - Mock = odpowiedź bez backendu. Validator + model = 400 przed backendem. Gateway responses = błędy generowane przez samo API Gateway.
- CORS przy proxy zwraca backend. Binary:
binaryMediaTypes+ base64. Limit payloadu 10 MB.
API Gateway: stage'e, bezpieczeństwo i wydajność
deploy, stage variables → alias, canary, authorizery, throttling, cache, 5xxZmiana w API Gateway to jak poprawka w menu restauracji. Dopóki szef kuchni nie wydrukuje nowej karty (deployment) i nie położy jej na konkretnych stolikach (stage: dev, test, prod), goście widzą starą wersję. Deployment to migawka (snapshot) konfiguracji API, a stage to nazwany wskaźnik na migawkę z własnymi ustawieniami: throttlingiem, cache, logami i stage variables.
Stage variables działają jak karteczka przypięta do stolika: „ten stolik obsługuje kuchnia DEV”. Ten sam zasób API wywołuje funkcję orders:${stageVariables.alias}, więc stage dev trafia w alias DEV, a stage prod w alias PROD. Jedno API obsługuje w ten sposób wiele środowisk.
3.2.33.3.23.3.53.4.23.4.102.1.2
- Każda zmiana w REST API wymaga redeployu do stage'a (wyjątek: ustawienia samego stage'a, np. stage variables). „Zmieniłem metodę, a klienci nie widzą zmiany” → brak deploymentu. HTTP API ma opcję auto-deploy.
- Stage variables w ARN integracji:
arn:aws:lambda:…:function:orders:${stageVariables.lambdaAlias}. Każdy alias musi mieć uprawnienie resource-based (aws lambda add-permission --principal apigateway.amazonaws.com), bo konsola nie doda go za Ciebie. Brak uprawnienia oznacza, że Lambda odrzuca wywołanie, a API Gateway zwraca 500. - Canary release na stage'u:
percentTraffic(0–100%) trafia do nowego deploymentu,stageVariableOverridespozwala skierować canary na inny alias, potem robisz promote. - Custom domain: certyfikat z ACM, dla edge-optimized w us-east-1, dla Regional w Regionie API. Base path mappings (API mappings) łączą
api.example.com/v1z API i stage'em. - Authorizery: IAM (
AWS_IAM+ SigV4,execute-api:Invoke), Cognito user pool (COGNITO_USER_POOLS, token w nagłówku), Lambda authorizer TOKEN (jeden nagłówek z bearer tokenem) lub REQUEST (nagłówki, query, stage variables,$context). Wynik jest cache'owany: domyślnie 300 s, maks. 3600 s, 0 = wyłączony. - Throttling: domyślnie 10 000 RPS i burst 5000 na konto i Region (wspólne dla wszystkich API). Nadwyżka → 429 Too Many Requests. Limity per stage/metoda i per klient (usage plan + API key, nagłówek
x-api-key). - Cache (tylko REST, per stage): TTL domyślnie 300 s, maks. 3600 s, 0 = wyłączony. Klucz cache tworzą wybrane parametry. Klient unieważnia wpis nagłówkiem
Cache-Control: max-age=0, o ile maexecute-api:InvalidateCache. - Kody: 429 = throttling/quota, 502 = zła odpowiedź backendu, 504 = timeout integracji (domyślnie maks. 29 s). Metryki:
Latency(całość) vsIntegrationLatency(sam backend).
lambdaAlias = DEVlambdaAlias = PRODcanary: wył.function:orders:${stageVariables.lambdaAlias}$LATESTDeploymenty, stage'e i środowiska
Typowy wzorzec dla dev/test/prod: jedno API, kilka stage'y, stage variables wskazujące na różne aliasy Lambdy albo różne hosty HTTP (http://${stageVariables.host}/orders). Alternatywa to osobne API (lub osobne konta) na środowisko, wdrażane z IaC (SAM/CDK, CloudFormation). Ustawienia per stage:
| Ustawienie stage'a | Co robi | Kiedy |
|---|---|---|
| Stage variables | pary klucz–wartość (maks. 100 na stage, klucz 64 znaki, wartość 512) dostępne w ARN integracji, URL HTTP, mapping templates ($stageVariables.x) i evencie Lambda (event.stageVariables) | różne aliasy, hosty, nazwy tabel per środowisko. Nie na sekrety. |
| Default method throttling + nadpisania per metoda | rate i burst dla stage'a i konkretnych metod | ochrona backendu, np. 100 RPS na POST /orders |
| Cache | klaster cache 0,5–237 GB, TTL, szyfrowanie | powtarzalne odczyty, mniejsze obciążenie backendu |
| Logs/tracing | execution logs (ERROR/INFO, pełne request/response), access logs, detailed metrics, X-Ray | debugowanie, audyt |
| Canary settings | procent ruchu, overrides stage variables, użycie cache stage'a | bezpieczne wdrożenie nowej wersji API |
| Client certificate / WAF | certyfikat, którym API Gateway uwierzytelnia się do backendu HTTP / web ACL na stage'u | backend weryfikuje, że ruch idzie z API Gateway / ochrona L7 |
# Jedno API, dwa aliasy, dwa uprawnienia (po jednym na alias!)
aws lambda add-permission --function-name "arn:aws:lambda:eu-west-1:123456789012:function:orders:PROD" \
--source-arn "arn:aws:execute-api:eu-west-1:123456789012:a1b2c3/*/GET/orders" \
--principal apigateway.amazonaws.com --statement-id apigw-prod --action lambda:InvokeFunction
aws apigateway create-deployment --rest-api-id a1b2c3 --stage-name prod \
--variables lambdaAlias=PROD
Stage variables wskazują tylko funkcje z tego samego konta. Lambda dostaje stage variables w evencie proxy, więc kod może np. czytać tabelę orders-${stage}. O aliasach i wersjach przeczytasz w rozdziale Lambda: konfiguracja, a o wdrożeniach z przesuwaniem ruchu na aliasie Lambdy w rozdziale CodeDeploy.
Canary release
Canary w API Gateway dzieli ruch na poziomie stage'a: część żądań idzie do nowego deploymentu, reszta do obecnego. Ustawiasz percentTraffic (0.0–100.0), opcjonalnie stageVariableOverrides (canary może wołać inny alias Lambdy) i useStageCache. Canary ma własne logi wykonania w grupie API-Gateway-Execution-Logs_{api-id}/{stage}/Canary i własne metryki. Gdy wszystko jest w porządku, robisz promote: deployment canary staje się produkcyjnym, a canary zostaje wyłączony. Rollback to usunięcie ustawień canary.
Custom domains
- Certyfikat TLS musi być w ACM. Dla edge-optimized custom domain certyfikat musi być w us-east-1, bo obsługuje go CloudFront. Dla Regional certyfikat musi być w tym samym Regionie co API.
- W DNS (Route 53) tworzysz rekord alias (lub CNAME) na domenę docelową, którą wygenerował API Gateway.
- API mappings (base path mappings) łączą ścieżkę z API i stage'em:
api.example.com/orders→ API A/prod,api.example.com/users→ API B/prod. Mapowania wielopoziomowe (/v1/orders) wymagają Regional custom domain i polityki TLS 1.2. - Jedna custom domain może obsłużyć REST i HTTP API (Regional). Domyślny endpoint
execute-apimożesz wyłączyć, żeby wymusić ruch przez custom domain (np. przy mTLS). - Mutual TLS: na custom domain wgrywasz truststore (certyfikaty CA w S3), a klient musi przedstawić certyfikat. Dostępne w REST i HTTP API.
Kontrola dostępu: cztery mechanizmy
| Opcja | Co robi | Kiedy |
|---|---|---|
IAM (AWS_IAM) | klient podpisuje żądanie SigV4, polityka IAM musi zezwalać na execute-api:Invoke na ARN arn:aws:execute-api:region:acct:api-id/stage/METHOD/resource | wywołania z usług AWS, mikroserwisy, użytkownicy z poświadczeniami AWS (np. przez Cognito identity pool) |
| Cognito user pool authorizer | API Gateway sam weryfikuje JWT z nagłówka (zwykle Authorization). ID token = autoryzacja po claims, access token = po scopes (OAuth) ustawionych na metodzie | użytkownicy aplikacji zalogowani w Cognito, zero kodu autoryzacji |
| Lambda authorizer TOKEN | dostaje bearer token z jednego nagłówka (opcjonalnie wstępnie filtrowany regexem), zwraca politykę IAM; cache po wartości tokenu | JWT/OAuth z zewnętrznego IdP (Auth0, Okta), własne tokeny |
| Lambda authorizer REQUEST | dostaje nagłówki, query string, stage variables, $context; cache po wszystkich wskazanych identity sources (brak któregoś = 401 bez wywołania) | autoryzacja po kilku parametrach, np. nagłówek + IP + stage |
| Resource policy | polityka na API: zezwala/blokuje konta, IP (aws:SourceIp), VPC/VPC endpointy (aws:SourceVpc, aws:SourceVpce) | dostęp cross-account, private API, blokada IP |
Lambda authorizer zwraca principalId, policyDocument (Allow/Deny na execute-api:Invoke), opcjonalnie context (dostępny jako $context.authorizer.klucz, a przy proxy w event.requestContext.authorizer) i usageIdentifierKey (klucz API dla usage planu, gdy źródłem klucza jest AUTHORIZER). Odmowa daje 403, a brak lub zły token 401. Przy cache'owaniu zwracaj politykę obejmującą wszystkie metody, z których korzysta użytkownik, bo inaczej cache z jednej metody zablokuje drugą. Dostęp cross-account z IAM wymaga zgody w obu miejscach: w polityce IAM wywołującego i w resource policy API.
Throttling, usage plans i API keys
Analogia: wiadro z żetonami (token bucket). Co sekundę wpada rate żetonów, a wiadro mieści maksymalnie burst. Każde żądanie zabiera żeton, a gdy wiadro jest puste, klient dostaje 429.
- Limit konta: 10 000 RPS, burst 5000 na Region, wspólny dla wszystkich API (REST, HTTP, WebSocket). W kilku nowszych Regionach domyślnie 2500/1250. Limit RPS można podnieść, burstu nie.
- Kolejność stosowania: limity per klient/per metoda w usage planie → limity per metoda na stage'u → limity konta. Żaden niższy limit nie może przekroczyć wyższego.
- Usage plan = throttling (rate, burst) + quota (liczba żądań na
DAY/WEEK/MONTH) dla API keys, przypięty do API i stage'y. Metoda musi miećapiKeyRequired=true. Klucz przychodzi w nagłówkuX-API-Keyalbo z Lambda authorizera (usageIdentifierKey). Brak lub zły klucz → 403, przekroczona quota → 429. - API keys nie są mechanizmem uwierzytelniania: identyfikują klienta do celów rozliczeń i limitów. Do autoryzacji użyj IAM, Cognito albo Lambda authorizera. Limity usage planu działają „best effort” i nie chronią przed kosztami (do tego służą AWS Budgets i WAF).
- Klient po 429 powinien ponawiać z exponential backoff i jitterem (patrz wzorce).
Cache API Gateway
- Włączasz na stage'u, wybierasz rozmiar (0,5–237 GB, płatne za godzinę, bez free tier). Domyślnie cache'owane są tylko metody GET. Inne metody włączasz nadpisaniem per metoda.
- TTL: domyślnie 300 s, maks. 3600 s, 0 = cache wyłączony. Maks. rozmiar odpowiedzi w cache to 1 MB.
- Klucz cache: wybrane parametry metody (nagłówki, query string, path). Jeśli
?type=adminnie jest w kluczu, admin i zwykły użytkownik dostaną tę samą odpowiedź. - Unieważnianie: Flush stage cache (konsola,
aws apigateway flush-stage-cache) dla całości. Pojedynczy wpis unieważnia klient nagłówkiemCache-Control: max-age=0. Bez wymogu autoryzacji (execute-api:InvalidateCache, „Require authorization”) każdy klient może czyścić cache. Zachowanie przy braku uprawnień:FAIL_WITH_403,SUCCEED_WITH_RESPONSE_HEADERalboSUCCEED_WITHOUT_RESPONSE_HEADER. - Szyfrowanie danych w cache to opcja („Encrypt cache data”). Zmiana rozmiaru cache usuwa jego zawartość.
- Metryki
CacheHitCountiCacheMissCountpokazują skuteczność cache.
Timeouty, kody błędów i monitoring
| Kod | Co znaczy | Typowa przyczyna |
|---|---|---|
| 400 / 415 | zły request / brak pasującego szablonu | request validator, passthrough NEVER/WHEN_NO_TEMPLATES |
| 401 / 403 | brak lub zły token / odmowa | authorizer, zły klucz API, zły podpis SigV4, resource policy, WAF, nieistniejąca ścieżka (Missing Authentication Token) |
| 429 | Too Many Requests | throttling konta/stage'a/metody albo quota usage planu |
| 500 | błąd wewnętrzny | Lambda API odrzuciła wywołanie (np. brak lambda:InvokeFunction dla aliasu), błąd konfiguracji authorizera |
| 502 | Bad Gateway | Lambda rzuciła wyjątek albo zwróciła zły format przy proxy |
| 503 | Service Unavailable | ogólny kod HTTP „usługa chwilowo niedostępna”, zwykle przekazany z przeciążonego backendu HTTP; na egzaminie rzadki |
| 504 | Gateway Timeout | integracja przekroczyła timeout (INTEGRATION_TIMEOUT) albo jest nieosiągalna (INTEGRATION_FAILURE) |
Timeout integracji REST API: od 50 ms do 29 s (domyślnie 29 s). Dla API Regional i private możesz poprosić o podniesienie powyżej 29 s, co może wymagać obniżenia limitu throttlingu konta. Dla edge-optimized limit jest stały. HTTP API ma maks. 30 s. W starszych pytaniach „29 s to twardy limit, którego nie da się zmienić”. Dla edge-optimized to nadal prawda, a w każdym przypadku dłuższą pracę lepiej przenieść na wzorzec asynchroniczny (zwróć 202, przetwórz w tle przez SQS/Step Functions, klient sprawdza status). Lambda za API Gateway może mieć timeout 15 min, ale klient i tak dostanie 504 po upływie timeoutu integracji.
- Execution logs (tylko REST): co API Gateway zrobiło z żądaniem, poziom ERROR lub INFO, opcjonalnie pełne request/response. Wymaga roli IAM z zaufaniem do
apigateway.amazonaws.comustawionej raz na konto (cloudWatchRoleArn). Grupa:API-Gateway-Execution-Logs_{api-id}/{stage}. - Access logs: kto wołał i z jakim wynikiem, w Twoim formacie ze zmiennych
$context(CLF, JSON, XML, CSV), do CloudWatch Logs albo Firehose. - Metryki:
Count,4XXError,5XXError,Latency(od odebrania żądania do odpowiedzi, z narzutem API Gateway),IntegrationLatency(sam backend),CacheHitCount,CacheMissCount. WysokiLatencyprzy niskimIntegrationLatencyoznacza, że czas tracisz w API Gateway (authorizer, mapping), a nie w backendzie. Metryki per metoda wymagają detailed CloudWatch metrics. - X-Ray włączasz przełącznikiem „active tracing” na stage'u (patrz X-Ray).
- „Zaktualizowałem integrację, ale stary kod dalej działa”: brakuje redeployu, a nie restartu Lambdy czy czyszczenia cache.
- Stage variable z aliasem bez uprawnienia: uprawnienia Lambdy trzeba nadać ręcznie (
add-permission) — dla ARN każdego aliasu (orders:DEV,orders:PROD,--qualifier) albo na poziomie całej funkcji. - API key jako zabezpieczenie: klucz identyfikuje klienta na potrzeby usage planu, nie jest uwierzytelnianiem. Poprawne odpowiedzi to IAM, Cognito albo Lambda authorizer.
- 429 vs 5xx: 429 to throttling, rozwiązywany backoffem, usage planem albo podniesieniem limitu. Podnoszenie pamięci Lambdy tu nie pomoże.
- Certyfikat dla edge-optimized custom domain w Regionie API: musi być w us-east-1. Dla Regional odwrotnie, w Regionie API.
- Cache dla POST: domyślnie cache'owane są tylko GET. „Cache nie działa dla mojego POST” → nadpisanie per metoda (i zastanów się, czy na pewno chcesz).
- Każdy może czyścić cache: bez „Require authorization” nagłówek
Cache-Control: max-age=0od dowolnego klienta omija cache i obciąża backend. - Lambda authorizer w HTTP API dla JWT: HTTP API ma natywny JWT authorizer (mniej kodu i kosztu). W REST API JWT z zewnętrznego IdP sprawdzasz Lambda authorizerem.
execute-api:Invoke i nic więcej nie trzeba.Jedno REST API ma obsługiwać dev i prod. Funkcja Lambda ma aliasy DEV i PROD. Jak skonfigurować API z najmniejszym wysiłkiem, żeby każdy stage wołał właściwy alias?
jedno API · stage · alias
Odpowiedź
Stage variable (np. lambdaAlias) w ARN integracji function:orders:${stageVariables.lambdaAlias} + add-permission dla każdego aliasu.
Dlaczego nie: osobne API na środowisko (więcej pracy), zmienna środowiskowa Lambdy (nie zmienia, który alias jest wołany), canary (służy do dzielenia ruchu, a nie do środowisk).
Firma sprzedaje dostęp do API trzem planom cenowym z różnymi limitami żądań miesięcznie. Co skonfigurować?
per klient · quota · miesięcznie
Odpowiedź
Usage plans (quota MONTH + throttling) i API keys przypisane do klientów, metody z apiKeyRequired.
Dlaczego nie: throttling stage'a (wspólny dla wszystkich klientów), WAF rate-based rule (liczy po IP, a nie po kliencie i planie), Lambda reserved concurrency (chroni funkcję, nie rozlicza klientów).
Metryka Latency wynosi 2,5 s, a IntegrationLatency 0,2 s. Gdzie szukać przyczyny?
Latency vs IntegrationLatency
Odpowiedź
W API Gateway, a nie w backendzie, np. wolny Lambda authorizer bez cache. Różnica to narzut przed i po integracji.
Dlaczego nie: zwiększanie pamięci funkcji backendu (backend odpowiada szybko), DAX (bez związku), cache API (nie skróci czasu autoryzacji przy chybieniu).
Endpoint zwraca katalog produktów zmieniający się raz na godzinę. Lambda jest wołana tysiące razy na minutę z identycznym zapytaniem. Jak obniżyć koszt i opóźnienie bez zmiany kodu?
powtarzalne GET · bez zmian kodu
Odpowiedź
Włączyć cache API Gateway na stage'u z TTL 3600 s (maksimum) i odpowiednimi parametrami w kluczu cache.
Dlaczego nie: ElastiCache (wymaga zmian w kodzie), provisioned concurrency (dalej płacisz za wywołania), HTTP API (nie ma cache).
Nowa wersja API ma najpierw dostać 10% ruchu produkcyjnego z osobnymi metrykami, a po weryfikacji 100%. Funkcje Lambda wołane są przez stage variables.
procent ruchu · stage · promote
Odpowiedź
Canary release na stage'u prod: percentTraffic=10, stageVariableOverrides wskazujący nowy alias, a po weryfikacji promote.
Dlaczego nie: nowy stage prod2 (klienci musieliby zmienić URL), Route 53 weighted (działa na poziomie DNS i wymaga dwóch endpointów), Lambda alias routing (możliwy, ale nie obejmuje zmian w samym API).
Raport generuje się 45 s. Klienci dostają 504 po 29 s, choć Lambda kończy pracę poprawnie. Jak to naprawić zgodnie z dobrymi praktykami?
504 · długie zadanie
Odpowiedź
Wzorzec asynchroniczny: API przyjmuje zlecenie (202 + id), praca idzie w tle (SQS/Step Functions), wynik trafia do S3/DynamoDB, a klient odpytuje status albo dostaje powiadomienie (WebSocket). Dla Regional/private REST API można też poprosić o timeout powyżej 29 s.
Dlaczego nie: zwiększenie timeoutu Lambdy (to nie ona jest wąskim gardłem), zwiększenie pamięci (nie zmieni limitu API Gateway), cache (pierwsze żądanie i tak trwa 45 s).
🔬 Głębiej: rzadziej pytane szczegóły
- Kwoty: 300 usage planów na konto i Region, 10 usage planów na klucz API, 10 000 kluczy API na konto, 10 authorizerów na API, 20 ustawień throttlingu per metoda w usage planie.
- Throttling i quota usage planu sumują się dla klucza ze wszystkich stage'y w planie. Klucz z planu z kilkoma API daje dostęp do wszystkich API w tym planie.
- Authorizer
TOKENmoże mieć regex „token validation”: tokeny niepasujące do wzorca dostają 401 bez wywołania Lambdy. Zmiana części klucza cache authorizera i redeploy unieważnia cache polityk. - Private API: w resource policy typowo
aws:SourceVpce. Endpoint VPC dlaexecute-apiprzepisuje adres źródłowy, więcaws:SourceIpdla private API nie zadziała tak jak dla publicznego. Używasz wtedyaws:VpcSourceIp. - Unieważnianie cache między kontami (cross-account) nie jest obsługiwane.
- Eksport API do OpenAPI z rozszerzeniami API Gateway (
--parameters extensions='apigateway') przenosi m.in. walidatory i integracje, więc API można odtworzyć w innym Regionie lub koncie.
- Zmiana API = redeploy. Stage = migawka + ustawienia. Stage variables → alias Lambdy (+
add-permissionper alias). - Canary: % ruchu + overrides + promote. Custom domain: ACM (edge = us-east-1) + API mappings.
- IAM (SigV4) dla maszyn, Cognito authorizer dla użytkowników bez kodu, Lambda authorizer TOKEN/REQUEST dla wszystkiego innego. Cache autoryzacji: 300 s domyślnie, maks. 3600 s.
- Throttling 10 000/5000 → 429. Usage plan + API key = limity per klient (nie autoryzacja). Cache: tylko GET, TTL 300 s domyślnie, maks. 3600 s,
Cache-Control: max-age=0. - 502 = zła odpowiedź backendu, 504 = timeout 29 s.
Latency−IntegrationLatency= narzut API Gateway.
CloudFront: cache na krawędzi sieci
klucz cache, TTL, invalidation, OAC, signed URL/cookies, funkcje na krawędziCloudFront to sieć „lodówek” (edge locations) postawionych blisko klientów. Gdy ktoś prosi o plik, lodówka sprawdza, czy ma go na półce z dokładnie taką etykietą. To jest cache hit, a plik wydaje od ręki. Jeśli nie ma, idzie do magazynu (origin: S3, ALB, EC2, API Gateway, dowolny serwer HTTP) i odkłada kopię na półkę na czas TTL.
Etykieta to cache key. Domyślnie jest nią domena dystrybucji i ścieżka URL. Każdy dodatkowy element w kluczu (nagłówek, cookie, parametr query) tworzy osobną półkę. Gdy dodasz do klucza nagłówek User-Agent, który ma setki wariantów, ten sam plik ląduje na setkach półek, a cache hit ratio spada prawie do zera. Najważniejsza zasada rozdziału: w kluczu cache trzymaj tylko to, od czego naprawdę zależy odpowiedź.
4.3.5
- Cache policy decyduje, które nagłówki, cookies i query strings trafiają do klucza cache (i automatycznie do originu), oraz ustala TTL min/default/max. Origin request policy przekazuje dodatkowe wartości do originu bez dodawania ich do klucza, więc nie psuje hit ratio.
- Niski cache hit ratio → usuń zbędne nagłówki, cookies i query strings z klucza (np. zamiast całego
User-AgentużyjCloudFront-Is-Mobile-Viewer), a resztę przekaż origin request policy. - TTL: origin steruje nagłówkami
Cache-Control: max-age/s-maxage/Expiresw granicach min/max TTL polityki. Bez nagłówków obowiązuje default TTL (bez cache policy: 24 h). - Invalidation usuwa obiekty z cache przed TTL (ścieżki,
/*). Pierwsze 1000 ścieżek miesięcznie jest darmowe, potem płacisz za ścieżkę, a/*liczy się jako jedna ścieżka. Do częstych wdrożeń lepsze są wersjonowane nazwy plików (app.v42.js). - Prywatny bucket S3 jako origin: OAC (Origin Access Control, zalecany, obsługuje SSE-KMS i PUT/DELETE) zamiast starszego OAI. Bucket policy zezwala principalowi
cloudfront.amazonaws.comz warunkiemAWS:SourceArn= ARN dystrybucji. - Signed URL = dostęp do pojedynczego pliku. Signed cookies = wiele plików (cały kurs wideo, strefa abonenta) bez zmiany URL-i. Podpisujący to trusted key group (zalecane) zamiast kluczy CloudFront konta root.
- CloudFront Functions (JS, tylko viewer request/response, submilisekundowe, miliony RPS, bez sieci i body) vs Lambda@Edge (Node.js/Python, 4 zdarzenia w tym origin request/response, dostęp do sieci i body, do 30 s, tworzona w us-east-1).
- Certyfikat ACM dla CloudFront musi być w us-east-1. HTTPS dla widzów wymusza viewer protocol policy „Redirect HTTP to HTTPS” albo „HTTPS only”.
host + /products.json?utm= o 6 wartościach. Origin zwraca to samo niezależnie od utm. Liczba wariantów jest uproszczona.Cache policy vs origin request policy
| Opcja | Co robi | Kiedy |
|---|---|---|
| Cache policy | wartości w kluczu cache (headers / cookies / query strings: none, whitelist, all-except, all) + TTL min/default/max + obsługa kompresji Gzip/Brotli | odpowiedź naprawdę zależy od wartości, np. Accept-Language dla wersji językowych |
| Origin request policy | wartości przekazywane do originu bez wpływu na klucz, plus nagłówki dodawane przez CloudFront (np. CloudFront-Viewer-Country) | origin potrzebuje danych do logów lub analityki, ale odpowiedź się nie zmienia |
| Response headers policy | dodaje nagłówki do odpowiedzi dla widza (CORS, nagłówki bezpieczeństwa jak HSTS) | CORS na S3/originie bez zmian w originie |
Managed policies (np. CachingOptimized, CachingDisabled) | gotowe polityki od AWS | typowe przypadki: statyczne pliki / dynamiczne API |
Ważna zależność: wszystko, co jest w kluczu cache, CloudFront automatycznie przekazuje do originu. Odwrotnie to nie działa. Domyślnie (bez polityk) query strings, nagłówki i cookies z żądania widza nie trafiają do originu. „Origin nie widzi parametru ?lang” oznacza, że dodajesz go do cache policy (gdy odpowiedź od niego zależy) albo do origin request policy (gdy nie zależy). Nagłówki urządzeń i lokalizacji (CloudFront-Is-Mobile-Viewer, CloudFront-Is-Desktop-Viewer, CloudFront-Viewer-Country) CloudFront wylicza sam z User-Agent i IP. Dają kilka wariantów zamiast setek, więc nadają się do klucza cache.
TTL i nagłówki Cache-Control
- Origin wysyła
Cache-Control: max-age=3600(cache w przeglądarce i w CloudFront) albos-maxage(tylko cache współdzielone, np. CloudFront).Expiresto starsza alternatywa. Gdy są oba, wygrywamax-age. - CloudFront przycina wartość z nagłówków do zakresu Minimum TTL ↔ Maximum TTL. Gdy origin nie wysyła nagłówków, obowiązuje Default TTL (bez cache policy domyślnie 24 h).
- Gdy Minimum TTL > 0, CloudFront cache'uje nawet przy
no-cache,no-storeiprivate. Gdy min, default i max = 0, cache jest wyłączony (typowe dla dynamicznego API).
Invalidation vs wersjonowanie plików
Invalidation to wysłanie do wszystkich lodówek polecenia „wyrzuć to z półki”. Działa, ale kosztuje (powyżej 1000 ścieżek miesięcznie na konto), trwa chwilę i nie czyści cache przeglądarek. Wersjonowane nazwy (logo_2.png, /v42/app.js) zmieniają klucz cache, więc nowa wersja jest od razu chybieniem i pobiera się świeża. Stara wygasa sama. AWS zaleca wersjonowanie do regularnych wdrożeń, a invalidation do sytuacji awaryjnych.
aws cloudfront create-invalidation --distribution-id E2ABC123 \
--paths "/index.html" "/images/*" # "/*" = cała dystrybucja, liczona jako 1 ścieżka
Aktualne limity invalidation: 150 ścieżek (lub tagów) na sekundę i 1 invalidation z wildcardem na sekundę. W starszych testach możesz spotkać „3000 ścieżek w toku i 15 wildcardów naraz”. Dokumentacja podaje dziś limit na sekundę.
Originy i zabezpieczenie dostępu do nich
| Origin | Jak zablokować obejście CloudFront | Uwagi |
|---|---|---|
| S3 bucket (REST endpoint) | OAC + bucket policy z cloudfront.amazonaws.com i AWS:SourceArn; Block Public Access zostaje włączone | OAI to starsza metoda: nie obsługuje SSE-KMS, PUT/DELETE ani nowych Regionów opt-in |
| S3 static website endpoint | to custom origin, OAC/OAI nie zadziała; bucket musi być dostępny publicznie (website endpoint nie obsługuje uwierzytelnionych żądań) | potrzebny, gdy chcesz przekierowań i stron indeksu S3 website |
| ALB / EC2 / serwer HTTP (custom origin) | sekretny nagłówek dodawany przez CloudFront (origin custom header) + reguła ALB, która przepuszcza tylko z nim; security group z AWS-managed prefix list CloudFront; wewnętrzny ALB przez VPC origin | HTTPS do originu: origin protocol policy |
| API Gateway | Regional endpoint + własna dystrybucja | edge-optimized API ma już zarządzaną dystrybucję |
Origin failover: origin group z originem primary i secondary oraz listą kodów (np. 500, 502, 503, 504, 404, 403). Gdy primary zwróci kod z listy, CloudFront ponawia żądanie do secondary. Błąd połączenia uruchamia failover, gdy na liście jest 503, a timeout, gdy jest 504. Działa tylko dla GET, HEAD i OPTIONS. Typowe użycie: dwa buckety S3 w różnych Regionach (z replikacją).
Treści prywatne, HTTPS, geo i field-level encryption
| Opcja | Co robi | Kiedy |
|---|---|---|
| Signed URL | URL z polityką (canned: tylko czas wygaśnięcia; custom: także data startu, zakres IP, wildcard ścieżki) i podpisem | pojedynczy plik (instalator, raport); klient nie obsługuje cookies |
| Signed cookies | te same polityki w cookies CloudFront-Policy/-Signature/-Key-Pair-Id | wiele plików (segmenty HLS, cała strefa premium), URL-e mają się nie zmieniać |
| Trusted key group | klucze publiczne wgrane do CloudFront, zarządzane przez IAM/API | zalecany signer (stara metoda wymaga konta root) |
| Viewer protocol policy | HTTP and HTTPS / Redirect HTTP to HTTPS (GET/HEAD dostają 301) / HTTPS only (HTTP odrzucany) | wymuszenie szyfrowania w tranzycie między widzem a CloudFront |
| Origin protocol policy | HTTP only / HTTPS only / match viewer między CloudFront a originem | szyfrowanie end-to-end |
| Geo restriction | allow list albo block list krajów dla całej dystrybucji, zablokowani dostają 403 | licencje na treści; finezyjniej: usługa geolokalizacji, WAF geo match |
| Field-level encryption | CloudFront szyfruje do 10 pól formularza POST kluczem publicznym (RSA); odszyfruje dopiero aplikacja z kluczem prywatnym | numer karty i PII nie mogą być widoczne w warstwach pośrednich, logach i serwerach WWW |
| AWS WAF | web ACL na dystrybucji (tworzony w us-east-1) | SQL injection, XSS, rate limiting, boty (patrz rozdział 31) |
CloudFront Functions vs Lambda@Edge
Analogia: CloudFront Functions to bramkarz przy drzwiach, który w mgnieniu oka sprawdza bilet i poprawia adres na kopercie. Lambda@Edge to recepcjonista, który może zadzwonić do innego działu, przeczytać treść listu i zredagować odpowiedź, ale pracuje wolniej i drożej.
| CloudFront Functions | Lambda@Edge | |
|---|---|---|
| Język | JavaScript (ECMAScript 5.1 + runtime 2.0) | Node.js, Python |
| Zdarzenia | viewer request, viewer response | viewer request, viewer response, origin request, origin response |
| Skala / czas | miliony RPS, submilisekundowo | do 10 000 RPS na Region, do 30 s |
| Pamięć / rozmiar kodu | 2 MB / 10 KB | 128 MB (viewer) / do 10 240 MB (origin) · 50 MB kodu |
| Sieć, system plików, body żądania | ✖ | ✔ |
| Dane geolokalizacji i urządzenia | ✔ | tylko w zdarzeniach origin |
| KeyValueStore | ✔ | ✖ |
| Typowe zadania | przepisanie URL, przekierowania, normalizacja klucza cache, nagłówki, weryfikacja prostego tokenu (JWT podpisem w kodzie) | uwierzytelnianie z wywołaniem zewnętrznym, wybór originu dynamicznie, generowanie odpowiedzi, modyfikacja body, A/B z danymi z DynamoDB |
Ograniczenia Lambda@Edge: funkcję tworzysz w us-east-1, podpinasz numerowaną wersję (nie $LATEST ani alias), bez VPC, zmiennych środowiskowych, warstw i architektury arm64. Wygenerowana odpowiedź może mieć do 40 KB w zdarzeniach viewer i do 1 MB w zdarzeniach origin. W starszych materiałach przeczytasz, że viewer-triggery Lambda@Edge mają limit 5 s i 128 MB. Aktualna dokumentacja podaje do 30 s dla wszystkich czterech zdarzeń (pamięć: 128 MB dla viewer, do 10 240 MB dla origin), ale zasada wyboru pozostaje: proste, masowe manipulacje nagłówkami i URL → CloudFront Functions.
- „Forward all headers”, żeby origin widział wszystko: każdy nagłówek w kluczu mnoży warianty i obniża hit ratio. Do originu przekazuj przez origin request policy.
- Invalidation po każdym deployu jako „najtańsze” rozwiązanie: przy częstych wdrożeniach taniej i pewniej działają wersjonowane nazwy plików.
- OAI dla bucketu z SSE-KMS: OAI nie obsługuje SSE-KMS, potrzebujesz OAC (i uprawnienia
kms:Decryptdla CloudFront w polityce klucza). - OAC na S3 website endpoint: website endpoint to custom origin, OAC nie zadziała.
- Signed URL dla całej biblioteki wideo: przy wielu plikach i stałych URL-ach lepsze są signed cookies.
- Lambda@Edge do dopisania nagłówka: CloudFront Functions zrobi to taniej i szybciej. Lambda@Edge wybieraj przy origin request/response, wywołaniach sieciowych albo dostępie do body.
- Certyfikat ACM w Regionie bucketu: dla CloudFront certyfikat musi być w us-east-1.
- Geo restriction na pojedynczy katalog: wbudowana blokada obejmuje całą dystrybucję. Do części treści użyj usługi geolokalizacji, funkcji na krawędzi albo reguły WAF.
Sklep pokazuje ceny w walucie kraju klienta. Co dodasz do klucza cache: CloudFront-Viewer-Country czy pełny adres IP klienta? Dlaczego?
Odpowiedź
CloudFront-Viewer-Country: kilkadziesiąt wariantów, a odpowiedź naprawdę od niego zależy. Adres IP dałby osobny wpis cache dla każdego klienta, czyli praktycznie zero trafień.
Dystrybucja CloudFront ma cache hit ratio 4%. Cache policy przekazuje wszystkie nagłówki, wszystkie cookies i wszystkie query strings. Odpowiedź originu zależy tylko od języka. Co zrobić?
niski hit ratio · tylko język
Odpowiedź
Cache policy tylko z Accept-Language (lub parametrem lang), a pozostałe wartości potrzebne originowi przekazywać origin request policy.
Dlaczego nie: wydłużenie TTL (nie pomoże, gdy każdy wariant jest inny), Origin Shield (zmniejsza ruch do originu, ale nie poprawia trafień na brzegu), invalidation (odwrotny efekt).
Strona SPA jest wdrażana kilka razy dziennie na S3 za CloudFront. Użytkownicy widzą stare pliki JS przez godzinę. Jakie rozwiązanie jest najbardziej opłacalne?
częste wdrożenia · koszt
Odpowiedź
Wersjonowane nazwy plików (hash w nazwie, np. app.3f9a.js) + krótki TTL tylko dla index.html (lub jego invalidation).
Dlaczego nie: invalidation /* przy każdym deployu (działa, ale wolniej, a przy wielu ścieżkach rośnie koszt), TTL=0 dla wszystkiego (traci sens cache), włączenie wersjonowania obiektów S3 (nie zmienia URL-a).
Bucket S3 z SSE-KMS ma być dostępny tylko przez CloudFront. Użytkownicy nie mogą pobierać obiektów bezpośrednio z S3.
tylko przez CloudFront · SSE-KMS
Odpowiedź
OAC + bucket policy dla cloudfront.amazonaws.com z AWS:SourceArn dystrybucji + w polityce klucza KMS zgoda na kms:Decrypt dla CloudFront.
Dlaczego nie: OAI (brak wsparcia SSE-KMS), signed URLs (kontrolują widzów, a nie dostęp do bucketu), publiczny bucket z ograniczeniem IP (adresy CloudFront się zmieniają, a bucket byłby publiczny).
Serwis e-learningowy udostępnia subskrybentom setki plików wideo (HLS). URL-e w odtwarzaczu nie powinny się zmieniać.
wiele plików · bez zmiany URL
Odpowiedź
Signed cookies z custom policy (wildcard na ścieżkę kursu) i trusted key group.
Dlaczego nie: signed URLs (jeden URL na plik, zmienia adresy), presigned URL S3 (omija CloudFront), geo restriction (nie identyfikuje subskrybenta).
Trzeba przekierowywać użytkowników mobilnych na /m/ i normalizować nagłówki przy milionach żądań na sekundę, przy najniższym koszcie i opóźnieniu.
proste przepisanie · skala · najtaniej
Odpowiedź
CloudFront Functions na viewer request (z nagłówkiem CloudFront-Is-Mobile-Viewer).
Dlaczego nie: Lambda@Edge (droższa i wolniejsza, potrzebna dopiero przy sieci, body albo zdarzeniach origin), ALB rules (za originem, po chybieniu cache), API Gateway (zła warstwa).
Formularz płatności przechodzi przez CloudFront, ALB i kilka mikroserwisów. Tylko serwis płatności może widzieć numer karty, nawet w logach pośrednich warstw.
konkretne pole · tylko jeden serwis
Odpowiedź
Field-level encryption: CloudFront szyfruje pole kluczem publicznym, a klucz prywatny ma tylko serwis płatności.
Dlaczego nie: HTTPS (kończy się na CloudFront/ALB, potem dane są jawne), KMS w każdej usłudze (więcej pracy, dane i tak widoczne po drodze), WAF (nie szyfruje).
🔬 Głębiej: drobiazgi CloudFront
- Origin Shield to dodatkowa warstwa cache przed originem, która zmniejsza liczbę żądań do originu przy wielu edge locations.
- Darmowe 1000 ścieżek invalidation miesięcznie liczy się dla całego konta (wszystkie dystrybucje). Invalidation po tagach wlicza się do tej samej puli.
- Obsługę kompresji (Gzip/Brotli) włączasz w ustawieniach klucza cache w cache policy. CloudFront może wtedy pobierać i cache'ować wersje skompresowane, gdy widz deklaruje ich obsługę w
Accept-Encoding. - „Redirect HTTP to HTTPS” odpowiada 301 dla GET/HEAD. Dla POST/PUT/DELETE/OPTIONS/PATCH po HTTP z protokołem poniżej HTTP/1.1 CloudFront zwraca 403.
- Kwoty: 20 własnych cache policies na konto, 100 CloudFront Functions na konto, 100 Lambda@Edge na dystrybucję.
- Klucz cache = minimum, od którego zależy odpowiedź (cache policy). Reszta do originu przez origin request policy.
- TTL:
max-age/s-maxage/Expiresw granicach min/max, default 24 h bez polityki. Invalidation: 1000 ścieżek/mies. gratis,/*= 1 ścieżka. Lepiej wersjonować nazwy. - S3 prywatny: OAC (nie OAI). Signed URL = 1 plik, signed cookies = wiele plików. Key groups zamiast root.
- CloudFront Functions = viewer, lekkie i masowe. Lambda@Edge = 4 zdarzenia, sieć i body, us-east-1, numerowana wersja.
- ACM dla CloudFront w us-east-1. Field-level encryption = do 10 pól POST. Geo restriction = cała dystrybucja, 403.
Bezpieczeństwo aplikacji
Tożsamość użytkowników (Cognito), szyfrowanie (KMS), sekrety i konfiguracja (Secrets Manager, Parameter Store, AppConfig) oraz ochrona danych: certyfikaty, WAF, maskowanie PII i izolacja tenantów. To jedna czwarta egzaminu (domena 2: 26%).
Amazon Cognito: kto Ty jesteś i co Ci wolno
user pools vs identity pools, tokeny JWT, federacja, triggery, guestCognito ma dwie części, które na egzaminie łatwo pomylić. User pool to katalog użytkowników i bramka logowania: rejestracja, hasło, MFA, logowanie przez Google/SAML. Po zalogowaniu wydaje tokeny JWT. Identity pool (federated identities) to kantor wymiany: przyjmuje dowód tożsamości (token z user poola, Google, SAML, a nawet „nic” dla gościa) i wydaje tymczasowe poświadczenia AWS (STS) z rolą IAM.
Analogia z hotelem: user pool to recepcja, która sprawdza dowód i wydaje kartę gościa z Twoim nazwiskiem (ID token) oraz listą uprawnień (access token: basen, siłownia). Identity pool to automat, który za tę kartę wydaje klucz do konkretnych drzwi w budynku AWS (S3, DynamoDB). Pytanie „użytkownik ma się zalogować” wskazuje user pool. Pytanie „aplikacja mobilna ma pisać prosto do S3/DynamoDB” wskazuje identity pool.
2.1.12.1.22.1.7
- User pool = uwierzytelnianie (sign-up, sign-in, MFA, federacja SAML/OIDC/social, managed login) → JWT: ID token (kim jest:
email,name,cognito:groups), access token (co może: scopes, grupy; do autoryzacji API), refresh token (nowe ID/access bez ponownego logowania). - Identity pool = autoryzacja do usług AWS: wymienia token na tymczasowe poświadczenia STS z rolą IAM (authenticated / unauthenticated = guest). Izolacja danych per użytkownik: zmienna
${cognito-identity.amazonaws.com:sub}w polityce IAM. - Ważność tokenów: ID i access od 5 min do 1 dnia (domyślnie 1 h), refresh od 60 min do 10 lat (domyślnie 30 dni).
- Weryfikacja JWT w backendzie: podpis kluczem z JWKS (
https://cognito-idp.{region}.amazonaws.com/{userPoolId}/.well-known/jwks.json, dopasowanie pokid),exp,iss,aud/client_id,token_use. Gotowa biblioteka:aws-jwt-verify. - Integracje bez kodu: API Gateway Cognito authorizer (REST) / JWT authorizer (HTTP API), ALB akcja
authenticate-cognito(tylko listener HTTPS), AppSync z trybem autoryzacji Cognito user pools. - Lambda triggers user poola (synchroniczne, odpowiedź w 5 s; wyjątek: custom sender triggers): Pre sign-up, Post confirmation, Pre/Post authentication, Pre token generation, User migration, Custom message, Define/Create/Verify auth challenge.
- Grupy user poola mogą mieć rolę IAM. Gdy użytkownik należy do kilku grup, wygrywa grupa o najniższym
Precedence. Identity pool może brać rolę z tokenu (cognito:preferred_role) albo z reguł mapujących claims (pierwsza pasująca).
${sub}/User pool vs identity pool
| User pool | Identity pool | |
|---|---|---|
| Pytanie | „Kim jesteś?” (authentication) | „Jakie uprawnienia AWS dostajesz?” (authorization do AWS) |
| Wynik | JWT: ID, access, refresh token | tymczasowe poświadczenia AWS (access key, secret, session token) z roli IAM |
| Źródła tożsamości | własny katalog + federacja SAML 2.0, OIDC, social (Google, Facebook, Apple, Amazon) | user pool, SAML, OIDC, social, developer-authenticated identities, goście |
| Do czego dalej | Twoje API (API Gateway authorizer, ALB, AppSync, własny backend) | bezpośrednie wywołania SDK: S3, DynamoDB, IoT, Lambda |
| Typowe pytanie | rejestracja, logowanie, MFA, reset hasła, „login with Google” | aplikacja mobilna wrzuca zdjęcia do S3 bez backendu, dostęp gościa |
Najczęstszy wzorzec łączy oba: logowanie w user poolu, a potem wymiana ID tokena w identity poolu na poświadczenia AWS. Federacja „Login with Google” może więc być skonfigurowana w user poolu (Google → user pool → JWT) albo bezpośrednio w identity poolu (Google → poświadczenia AWS). Wybierz user pool, jeśli chcesz jednolitych tokenów, grup i triggerów dla wszystkich dostawców.
Tokeny: który do czego
| Token | Co zawiera | Do czego | Ważność |
|---|---|---|---|
| ID token | claims tożsamości: sub, email, name, cognito:groups, cognito:preferred_role, atrybuty własne | informacje o użytkowniku w aplikacji, wymiana w identity poolu, API Gateway authorizer (autoryzacja po claims) | 5 min – 1 dzień, domyślnie 1 h |
| Access token | sub, grupy, scopes (np. orders/read), client_id | autoryzacja wywołań API (resource server, scopes na metodzie API Gateway), operacje self-service na user poolu (zmiana atrybutów) | 5 min – 1 dzień, domyślnie 1 h |
| Refresh token | nieprzezroczysty, zaszyfrowany | pobranie nowych ID/access tokenów (REFRESH_TOKEN_AUTH / endpoint /oauth2/token); można go unieważnić (revoke) | 60 min – 10 lat, domyślnie 30 dni |
Bearer token to „okaziciel”: kto ma token, ten jest wpuszczany. Dlatego tokeny wysyła się tylko po HTTPS w nagłówku Authorization, w przeglądarce trzyma się je w bezpiecznym miejscu, a backend zawsze weryfikuje podpis i czas. Treść JWT jest tylko zakodowana base64, a nie zaszyfrowana, więc nie umieszczaj w atrybutach sekretów. Pre token generation trigger pozwala dodać lub zmienić claims (np. tenant_id) i scopes w tokenach.
// Node.js: weryfikacja access tokenu w backendzie / Lambda authorizerze
import { CognitoJwtVerifier } from "aws-jwt-verify";
const verifier = CognitoJwtVerifier.create({
userPoolId: "eu-west-1_AbC123", tokenUse: "access", clientId: "6n8qexample" });
const payload = await verifier.verify(token); // podpis (JWKS + kid), exp, iss, client_id, token_use
if (!payload.scope.includes("orders/write")) throw new Error("Forbidden");
Managed login, OAuth 2.0 i federacja
- Po dodaniu domeny user pool dostaje managed login (gotowe strony logowania, rejestracji, MFA i resetu hasła z brandingiem) albo starszy classic hosted UI. Starsze materiały mówią po prostu „Hosted UI”. Do tego dochodzi serwer autoryzacji OAuth 2.0 (
/oauth2/authorize,/oauth2/token,/oauth2/userInfo). - Authorization code grant (z PKCE dla aplikacji publicznych): najbezpieczniejszy, bo tokeny nie przechodzą przez URL. Implicit grant: przestarzały, tokeny w URL. Client credentials: machine-to-machine (M2M), bez użytkownika, z resource serverem i custom scopes (wymaga app clienta z sekretem).
- Federacja w user poolu: SAML 2.0 (Active Directory/ADFS, Okta), OIDC, social (Google, Facebook, Apple, Login with Amazon). Użytkownik federacyjny dostaje profil w user poolu i te same tokeny Cognito co inni.
- Przepływy logowania przez API (SDK) z app clienta:
USER_SRP_AUTH(hasło nie opuszcza urządzenia, protokół SRP),USER_PASSWORD_AUTH(hasło po TLS, np. przy migracji),ADMIN_USER_PASSWORD_AUTH(serwer z poświadczeniami IAM),CUSTOM_AUTH(wyzwania z triggerów Lambda),USER_AUTH(choice-based: hasło, OTP e-mail/SMS, passkeys),REFRESH_TOKEN_AUTH. - MFA: SMS, e-mail, TOTP (aplikacja authenticator); tryb off / optional / required. Threat protection (dawniej „advanced security features”, plan Plus): compromised credentials (wykrywanie wyciekniętych haseł) i adaptive authentication (ocena ryzyka logowania i wymaganie MFA albo blokada przy wysokim ryzyku).
Lambda triggers user poola
| Trigger | Co robi | Kiedy |
|---|---|---|
| Pre sign-up | akceptuje/odrzuca rejestrację, może auto-potwierdzić i auto-zweryfikować e-mail | tylko domeny firmowe, blokada kont jednorazowych |
| Post confirmation | po potwierdzeniu konta | zapis profilu do DynamoDB, e-mail powitalny, dodanie do grupy |
| Pre authentication / Post authentication | przed logowaniem (może odrzucić) / po logowaniu | blokada w określonych warunkach / audyt, statystyki |
| Pre token generation | dodaje, zmienia lub usuwa claims, grupy i scopes w tokenach | tenant_id w tokenie, role z zewnętrznej bazy |
| User migration | przy logowaniu lub resecie hasła nieznanego użytkownika pyta stary system i tworzy konto | migracja z istniejącej bazy bez wymuszania resetu haseł |
| Custom message / Custom sender | własna treść e-mail/SMS / własny dostawca wysyłki | branding, lokalizacja, zewnętrzny dostawca SMS |
| Define / Create / Verify auth challenge | własny przepływ uwierzytelniania (CUSTOM_AUTH) | CAPTCHA, kod jednorazowy, pytanie bezpieczeństwa |
Identity pool: role, reguły i goście
- Identity pool ma rolę authenticated i (opcjonalnie) unauthenticated. Dostęp gościa (guest access) włączasz jawnie i dajesz mu minimalne uprawnienia (np. odczyt publicznego katalogu).
- Wybór roli: default role, choose role from token (claim
cognito:preferred_rolez grupy o najniższymPrecedence) albo rules (np.custom:dept = "finance"→ rola Finance; pierwsza pasująca reguła wygrywa). Gdy nic nie pasuje, możesz użyć roli domyślnej albo odmówić. - Przepływ enhanced (zalecany):
GetId→GetCredentialsForIdentity. Przepływ basic (classic):GetId→GetOpenIdToken→sts:AssumeRoleWithWebIdentity. - Trust policy roli: principal
cognito-identity.amazonaws.com, warunek naaud(ID identity poola) iamr(authenticated/unauthenticated).
{ "Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject"],
"Resource": "arn:aws:s3:::photos-bucket/${cognito-identity.amazonaws.com:sub}/*" }
// każdy użytkownik widzi tylko swój „folder”, bez backendu i bez kodu autoryzacji
Tak samo w DynamoDB: dynamodb:LeadingKeys = ${cognito-identity.amazonaws.com:sub} ogranicza użytkownika do elementów z jego kluczem partycji (szerzej w rozdziale 31). Ogólne zasady polityk i zmiennych znajdziesz w rozdziale IAM.
Integracje: API Gateway, ALB, AppSync
| Opcja | Co robi | Kiedy |
|---|---|---|
API Gateway REST + COGNITO_USER_POOLS | sprawdza ID token (claims) albo access token (scopes ustawione na metodzie); claims dostępne w $context.authorizer.claims | API dla zalogowanych użytkowników bez kodu autoryzacji |
| HTTP API + JWT authorizer | issuer = user pool, audience = app client id, scopes per trasa | tańsze API z Cognito lub innym IdP OIDC |
ALB authenticate-cognito / authenticate-oidc | ALB przekierowuje na logowanie, trzyma sesję w cookie, a do targetu przekazuje nagłówki x-amzn-oidc-accesstoken, x-amzn-oidc-identity, x-amzn-oidc-data (claims, JWT podpisany przez ALB) | aplikacja webowa na EC2/ECS bez kodu logowania; wymaga listenera HTTPS |
AppSync (tryb AMAZON_COGNITO_USER_POOLS) | autoryzacja GraphQL po tokenie i grupach (@aws_cognito_user_pools) | patrz AppSync |
| Identity pool + IAM auth w API Gateway | klient podpisuje żądanie SigV4 poświadczeniami z identity poola | API dostępne także dla gości, autoryzacja politykami IAM |
- Identity pool do logowania użytkowników: identity pool nie ma katalogu użytkowników ani stron logowania. Rejestracja, hasła i MFA to user pool.
- User pool do bezpośredniego zapisu w S3: JWT z user poola nie jest poświadczeniem AWS. Do podpisanych wywołań SDK potrzebujesz identity poola (lub backendu).
- Access token zamiast ID tokena (i odwrotnie): scopes OAuth są w access tokenie, a atrybuty profilu (e-mail, imię) w ID tokenie. Wymiana na poświadczenia AWS w identity poolu używa ID tokena.
- Dekodowanie JWT bez weryfikacji podpisu: każdy może wygenerować token z dowolnymi claims. Backend musi sprawdzić podpis (JWKS),
exp,issiaud/client_id. - Implicit grant jako „najprostszy dla SPA”: to przepływ przestarzały. Wybierz authorization code + PKCE.
- Wspólny „folder” w S3 z filtrowaniem w aplikacji: najmniej kodu i najbezpieczniej daje zmienna
${cognito-identity.amazonaws.com:sub}w polityce roli. - Trigger dłuższy niż 5 s: Cognito wywołuje triggery synchronicznie i czeka maksymalnie 5 s. Ciężką pracę przenieś do kolejki.
sub z user poola od identity ID?sub w JWT to identyfikator użytkownika w user poolu. Identity ID (np. eu-west-1:1234…) to identyfikator w identity poolu i to on trafia do zmiennej ${cognito-identity.amazonaws.com:sub} w politykach IAM.Aplikacja mobilna ma pozwolić użytkownikom logować się kontem Google i zapisywać zdjęcia w S3, przy czym każdy widzi tylko swoje pliki. Bez własnego backendu.
mobilna · S3 bezpośrednio · tylko swoje
Odpowiedź
Cognito user pool (federacja Google) + identity pool z rolą authenticated, której polityka ogranicza S3 do prefiksu ${cognito-identity.amazonaws.com:sub}/.
Dlaczego nie: klucze IAM użytkownika w aplikacji (wyciek kluczy), presigned URL (wymaga backendu), sam user pool (JWT nie jest poświadczeniem AWS).
Sklep pozwala przeglądać katalog bez logowania (odczyt z DynamoDB przez SDK), a zakupy tylko po zalogowaniu.
bez logowania · goście
Odpowiedź
Identity pool z włączonym guest access (unauthenticated role) tylko z odczytem katalogu, a rola authenticated z dodatkowymi uprawnieniami.
Dlaczego nie: publiczny dostęp do tabeli (DynamoDB wymaga podpisanych żądań IAM), wspólny użytkownik IAM (klucze w aplikacji), API key (brak poświadczeń AWS).
Po rejestracji każdy nowy użytkownik ma trafić do tabeli Customers w DynamoDB, ale tylko po potwierdzeniu adresu e-mail.
po potwierdzeniu · zapis profilu
Odpowiedź
Trigger Post confirmation.
Dlaczego nie: Pre sign-up (przed potwierdzeniem, konto może nigdy nie zostać potwierdzone), Post authentication (przy każdym logowaniu), Pre token generation (do modyfikacji tokenów).
Aplikacja na EC2 za ALB ma wymagać logowania przez firmowego dostawcę OIDC bez zmian w kodzie aplikacji.
ALB · bez kodu · OIDC
Odpowiedź
Akcja authenticate-oidc (albo authenticate-cognito z federacją) na listenerze HTTPS ALB. Aplikacja dostaje claims w nagłówkach x-amzn-oidc-*.
Dlaczego nie: Lambda authorizer (to funkcja API Gateway, nie ALB), identity pool (nie chroni aplikacji webowej), CloudFront signed cookies (nie ma integracji z IdP).
Usługa backendowa bez użytkownika ma wywoływać API chronione przez Cognito i uzyskać zakres reports/read.
machine-to-machine · scopes
Odpowiedź
Client credentials grant: app client z sekretem, resource server z custom scope reports/read, access token z /oauth2/token.
Dlaczego nie: konto „techniczne” z hasłem w user poolu (gorsza praktyka), identity pool guest (to poświadczenia AWS, a nie token API), API key (nie jest autoryzacją).
🔬 Głębiej: rzadziej pytane szczegóły Cognito
- Feature plans user poola: Lite, Essentials, Plus. Threat protection wymaga planu Plus. Pre token generation z modyfikacją access tokena wymaga Essentials lub Plus.
- Refresh token rotation (opcjonalna) wydaje nowy refresh token w tym samym oknie ważności, bez jego przedłużania.
- Sesja managed login (cookie) jest ważna 1 h, więc użytkownik może się zalogować ponownie bez wpisywania hasła, nawet gdy ważność tokenów ustawiono na krócej niż godzinę.
- Identity pool trust policy powinna mieć warunek
cognito-identity.amazonaws.com:aud(ID twojej puli), żeby rolę mogli przyjąć tylko użytkownicy tej puli.
- User pool = logowanie i JWT (ID = kim jest, access = scopes i API, refresh = nowe tokeny). Identity pool = token → poświadczenia AWS (także dla gości).
- Tokeny 1 h (5 min–1 dzień), refresh 30 dni (60 min–10 lat). Backend weryfikuje podpis przez JWKS (
kid),exp,iss,aud. - Managed login / hosted UI + OAuth: code + PKCE (najlepszy), implicit (przestarzały), client credentials (M2M). Federacja SAML/OIDC/social.
- Triggery: Pre sign-up, Post confirmation, Pre token generation, User migration… (5 s). Grupy → rola IAM (najniższy Precedence).
${cognito-identity.amazonaws.com:sub}= izolacja danych per użytkownik. Integracje: API GW authorizer, ALB (HTTPS), AppSync.
AWS KMS: klucze, koperty i polityki
envelope encryption, 4 KB, key policy, grants, rotacja, cross-accountAWS KMS (Key Management Service) to sejf z kluczami, z którego klucz nigdy nie wychodzi. Nie dostaniesz od KMS klucza głównego. Możesz za to podać mu dane do zaszyfrowania (do 4 KB) albo poprosić o data key, czyli klucz roboczy, którym sam zaszyfrujesz duże dane. Każde użycie klucza sprawdza polityka i rejestruje CloudTrail.
Analogia z kopertą (envelope encryption): masz walizkę dokumentów (1 GB danych). Zamykasz ją zwykłą kłódką (data key, AES-256), a kluczyk do kłódki wkładasz do koperty zapieczętowanej pieczęcią, którą ma tylko bank (KMS key). Kopertę przyklejasz do walizki. Żeby otworzyć walizkę, zanosisz kopertę do banku (Decrypt), dostajesz kluczyk, otwierasz i od razu zapominasz kluczyk. Po sieci do KMS idzie tylko mała koperta, a nie gigabajty danych.
2.2.12.2.32.2.42.2.62.2.7
Encryptprzyjmuje maks. 4 KB (4096 bajtów). Większe dane szyfrujesz envelope encryption:GenerateDataKey→ klucz w postaci jawnej + zaszyfrowanej, szyfrujesz lokalnie, wyrzucasz jawny z pamięci, zapisujesz zaszyfrowany obok danych. Odczyt:Decryptzaszyfrowanego data key → odszyfrowanie lokalne. Najprościej robi to AWS Encryption SDK.GenerateDataKeyWithoutPlaintextzwraca tylko zaszyfrowany klucz (gdy użyjesz go później albo w innym systemie).ReEncryptzmienia klucz KMS szyfrogramu bez ujawniania jawnego tekstu poza KMS.- Typy kluczy: customer managed (Twoje: polityka, rotacja, usuwanie, cross-account, opłata miesięczna), AWS managed (
alias/aws/s3,aws/lambda…, polityki nie zmienisz, rotacja co rok automatycznie), AWS owned (niewidoczne, bez opłat). - Key policy jest obowiązkowa (dokładnie jedna na klucz). Domyślna polityka daje dostęp kontu (
arn:aws:iam::111122223333:root) i dopiero to włącza polityki IAM dla klucza. Bez tego wpisu IAM Allow nie działa. - Grants: programowe, tymczasowe delegowanie uprawnień (np. usługa AWS na czas operacji):
CreateGrant,RetireGrant,RevokeGrant. - Rotacja automatyczna (tylko symetryczne customer managed z materiałem z KMS): domyślnie co 365 dni, konfigurowalnie 90–2560 dni, plus on-demand (maks. 25 razy na klucz). Key ID się nie zmienia, a stary materiał zostaje do odszyfrowania. Klucze asymetryczne, HMAC i z importowanym materiałem rotujesz ręcznie: nowy klucz + przestawienie aliasu.
- Cross-account: polityka klucza musi zezwalać drugiemu kontu, a w drugim koncie polityka IAM musi delegować to uprawnienie użytkownikom lub rolom. Klucza AWS managed nie udostępnisz innemu kontu.
ThrottlingException→ exponential backoff, data key caching (Encryption SDK), S3 Bucket Keys (do 99% mniej żądań do KMS), ewentualnie podniesienie limitu.
alias/appmateriał: v1GenerateDataKey/Decrypt z dokumentacji. Rozmiar pliku i numery wersji materiału są ilustracyjne. Limit 4096 bajtów dla Encrypt jest rzeczywisty.Typy kluczy KMS
| Typ | Widzisz / zarządzasz | Rotacja | Koszt | Kiedy |
|---|---|---|---|---|
| Customer managed key | ✔ / ✔ (polityka, grants, aliasy, tagi, wyłączenie, usunięcie) | opcjonalna automatyczna (90–2560 dni, domyślnie 365) i on-demand | opłata miesięczna + za użycie | kontrola dostępu, audyt, cross-account, własny harmonogram rotacji, wymogi zgodności |
AWS managed key (alias/aws/<usługa>) | ✔ / ✖ | obowiązkowa, co rok | bez opłaty miesięcznej, za użycie | „włącz szyfrowanie i nie zarządzaj kluczem” w jednym koncie; typ wycofywany (od 2021 nowe usługi używają AWS owned) |
| AWS owned key | ✖ / ✖ | zarządza usługa | bez opłat | domyślne szyfrowanie wielu usług (np. DynamoDB, SQS SSE-SQS) |
W starszych materiałach przeczytasz, że klucze AWS managed rotują się co 3 lata. Według aktualnej dokumentacji rotują się co rok. Nazwa „CMK” (customer master key) to dawne określenie klucza KMS. Dziś mówi się „KMS key”, a „customer managed key” oznacza klucz zarządzany przez Ciebie.
| Specyfikacja | Co robi | Kiedy |
|---|---|---|
Symmetric (SYMMETRIC_DEFAULT, AES-256-GCM) | szyfrowanie/deszyfrowanie i data keys; klucz nigdy nie opuszcza KMS | prawie zawsze; integracje z usługami AWS wymagają symetrycznego |
| Asymmetric RSA | para kluczy: albo encrypt/decrypt, albo sign/verify; klucz publiczny można pobrać (GetPublicKey) | szyfrowanie po stronie klienta poza AWS bez dostępu do KMS, podpisy |
| Asymmetric ECC (i ML-DSA) | podpisy cyfrowe (sign/verify), uzgadnianie kluczy | podpisywanie tokenów, dokumentów, kodu |
| HMAC | symetryczny klucz do GenerateMac/VerifyMac | integralność i autentyczność wiadomości, tokeny |
Identyfikatory klucza: key ID (UUID), key ARN, alias (alias/orders, zawsze z prefiksem alias/) i alias ARN. Alias to wymienna etykieta, więc kod używający aliasu nie zmienia się przy ręcznej rotacji. Do Decrypt szyfrogramu symetrycznego nie musisz podawać klucza, bo KMS odczyta go z metadanych szyfrogramu. Dobrą praktyką jest jednak podanie KeyId.
Envelope encryption i API
| Operacja | Co robi | Kiedy |
|---|---|---|
Encrypt / Decrypt | szyfruje do 4096 B bezpośrednio kluczem KMS / odszyfrowuje | małe sekrety: hasło, token, data key |
GenerateDataKey | zwraca Plaintext + CiphertextBlob data key (KeySpec=AES_256 albo NumberOfBytes) | szyfrujesz teraz duże dane lokalnie |
GenerateDataKeyWithoutPlaintext | zwraca tylko zaszyfrowany data key | klucz będzie potrzebny później lub w innym komponencie (np. system ma zaszyfrować dopiero przy zapisie) |
ReEncrypt | odszyfrowuje i szyfruje ponownie innym kluczem wewnątrz KMS | zmiana klucza (ręczna rotacja, inny Region/konto) bez ujawniania danych |
GenerateRandom, Sign/Verify, GenerateMac/VerifyMac | losowe bajty, podpisy asymetryczne, HMAC | kryptografia aplikacyjna |
# Python (boto3) – envelope encryption ręcznie
import boto3, os
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
kms = boto3.client("kms")
dk = kms.generate_data_key(KeyId="alias/app", KeySpec="AES_256",
EncryptionContext={"tenant": "acme"})
nonce = os.urandom(12)
blob = AESGCM(dk["Plaintext"]).encrypt(nonce, big_data, None)
store(blob, nonce, dk["CiphertextBlob"]) # zaszyfrowany data key leży obok danych
del dk["Plaintext"] # jawny klucz usuń z pamięci jak najszybciej
# odczyt: kms.decrypt(CiphertextBlob=..., EncryptionContext={"tenant": "acme"})
Szyfrowanie po stronie klienta vs po stronie serwera: przy SSE (np. S3 SSE-KMS) usługa AWS szyfruje dane po ich otrzymaniu i sama woła KMS. Przy client-side encryption szyfrujesz przed wysłaniem (Encryption SDK, S3 Encryption Client), więc AWS nigdy nie widzi danych jawnych. Szczegóły opcji S3 znajdziesz w rozdziale S3: bezpieczeństwo. Szyfrowanie at rest (KMS, SSE) i in transit (TLS) to dwie osobne warstwy, potrzebujesz obu (więcej w rozdziale 31).
Encryption context to pary klucz–wartość (np. {"tenant":"acme"}) dołączane do Encrypt/GenerateDataKey jako AAD (additional authenticated data). Nie są tajne, za to są kryptograficznie związane z szyfrogramem: Decrypt z innym kontekstem się nie powiedzie. Kontekst trafia do CloudTrail (wiesz, czego dotyczyło użycie klucza) i może być warunkiem w polityce (kms:EncryptionContext:tenant).
Key policy, IAM i grants
{ "Sid": "Enable IAM policies", // domyślna polityka: konto jako właściciel
"Effect": "Allow",
"Principal": { "AWS": "arn:aws:iam::111122223333:root" },
"Action": "kms:*", "Resource": "*" },
{ "Sid": "Allow use via S3 only",
"Effect": "Allow",
"Principal": { "AWS": "arn:aws:iam::111122223333:role/app" },
"Action": ["kms:Decrypt", "kms:GenerateDataKey"], "Resource": "*",
"Condition": { "StringEquals": { "kms:ViaService": "s3.eu-west-1.amazonaws.com" } } }
- Bez key policy nikt nie ma dostępu, nawet root, bo KMS nie ufa automatycznie IAM. Wpis z
:rootnie daje dostępu „wszystkim w koncie”. Oznacza, że konto deleguje uprawnienia do polityk IAM. Usunięcie go grozi kluczem, którym nikt nie zarządza (wtedy pomaga tylko AWS Support). kms:ViaServiceogranicza użycie klucza do żądań przychodzących przez wskazaną usługę (np. tylko przez S3 albo EBS).kms:CallerAccount,kms:EncryptionContext:*ikms:GrantIsForAWSResourceto inne częste warunki.- Grants to programowe, wąskie i odwoływalne uprawnienia. Usługi AWS (EBS, RDS) tworzą grant na czas użycia klucza. Grant daje tylko operacje kryptograficzne i
CreateGrant/DescribeKey, nie zarządzanie kluczem. Nowy grant może potrzebować chwili na propagację, a grant token pozwala go użyć od razu. Limit: 50 000 grantów na klucz. - Wyłączenie klucza (
DisableKey) blokuje użycie natychmiast i odwracalnie. Usunięcie (ScheduleKeyDeletion) wymaga okresu oczekiwania 7–30 dni (domyślnie 30), w którym możesz anulować. Dane zaszyfrowane usuniętym kluczem są nie do odzyskania. W tym czasie klucz ma stan Pending deletion i nie da się go użyć w operacjach kryptograficznych, więc próby użycia w CloudTrail ujawnią, czy ktoś go jeszcze potrzebuje.
Rotacja kluczy
| Opcja | Co robi | Kiedy |
|---|---|---|
Automatyczna (EnableKeyRotation, RotationPeriodInDays) | nowy materiał co 90–2560 dni (domyślnie 365); ten sam key ID i ARN; stare wersje zostają do odszyfrowania, więc nie musisz ponownie szyfrować danych | symetryczny customer managed z materiałem z KMS |
On-demand (RotateKeyOnDemand) | natychmiastowa rotacja, maks. 25 razy na klucz; nie zmienia harmonogramu automatycznej | incydent, audyt, test procedury; działa też dla importowanego materiału |
Ręczna (nowy klucz + UpdateAlias) | nowy key ID; stary klucz trzymasz do odczytu starych danych albo robisz ReEncrypt | klucze asymetryczne, HMAC, w custom key store; dowolny harmonogram |
W starszych testach rotacja automatyczna ma stały okres 1 roku („co 365 dni, bez możliwości zmiany”). Dziś okres ustawisz od 90 do 2560 dni, a do tego masz rotację on-demand.
Między kontami i Regionami
- Cross-account to dwa kroki. (1) Key policy w koncie A zezwala kontu B (lub jego roli) na np.
kms:Decrypt,kms:GenerateDataKey,kms:DescribeKey. (2) Polityka IAM w koncie B nadaje to uprawnienie konkretnej roli. W wywołaniu podajesz ARN klucza lub ARN aliasu (sama nazwa aliasu bez ARN działa tylko w obrębie konta). Typowy przypadek: snapshot EBS/RDS lub obiekty S3 zaszyfrowane kluczem customer managed udostępnione innemu kontu. Z kluczem AWS managed się nie da, wtedy najpierw kopiujesz z ponownym szyfrowaniem kluczem customer managed. - Multi-Region keys (
mrk-…): klucze w różnych Regionach z tym samym key ID i materiałem. Zaszyfrujesz w jednym Regionie, odszyfrujesz w drugim bez wywołania między Regionami i bezReEncrypt(np. DynamoDB global tables, aplikacje aktywne w wielu Regionach, DR). Każdą replikę zarządzasz osobno (polityka, aliasy, grants). Zwykły klucz KMS działa tylko w swoim Regionie. - Importowany materiał (BYOK, origin
EXTERNAL): sam odpowiadasz za kopię i trwałość materiału. Możesz ustawić datę wygaśnięcia i usunąć materiał natychmiast (DeleteImportedKeyMaterial). Rotacja automatyczna nie działa, on-demand działa. - Custom key store: klucze w Twoim klastrze AWS CloudHSM (pojedynczy najemca, FIPS, pełna kontrola nad HSM) albo w zewnętrznym menedżerze kluczy (XKS). Gdy pytanie wymaga „dedykowanego HSM pod Twoją kontrolą”, odpowiedzią jest CloudHSM.
Limity żądań i throttling
Operacje kryptograficzne na kluczach symetrycznych (Encrypt, Decrypt, GenerateDataKey*, ReEncrypt, GenerateMac…) dzielą wspólny limit na konto i Region: 10 000, 20 000 albo 100 000 żądań/s zależnie od Regionu. Klucze RSA mają osobne, niższe limity (np. 1000/s). Po przekroczeniu KMS zwraca ThrottlingException. W starszych testach możesz spotkać niższe wartości tego limitu. Zasada pozostaje ta sama: przekroczenie = throttling. Rozwiązania w kolejności typowej dla egzaminu:
- retry z exponential backoff (SDK robi to automatycznie),
- data key caching w AWS Encryption SDK: jeden data key dla wielu wiadomości, z limitem czasu, liczby wiadomości lub bajtów,
- S3 Bucket Keys dla SSE-KMS: klucz na poziomie bucketu zamiast wywołania KMS na każdy obiekt (do 99% mniej żądań i kosztów),
- prośba o podniesienie limitu w Service Quotas.
- „Zaszyfruj plik 50 MB przez
kms:Encrypt”: limit to 4 KB. Poprawna odpowiedź:GenerateDataKey+ szyfrowanie lokalne (envelope). - „Wyślij dane do KMS w celu odszyfrowania”: przy envelope encryption do KMS idzie tylko zaszyfrowany data key, a dane odszyfrowujesz lokalnie.
- Polityka IAM z
kms:Decrypt, a dalej AccessDenied: key policy nie deleguje uprawnień do IAM (brak wpisu z:root) albo przy cross-account brakuje jednej z dwóch zgód. - Rotacja automatyczna dla klucza asymetrycznego lub importowanego: nie jest obsługiwana. Robisz ręczną rotację przez alias (dla importowanego działa też on-demand).
- „Po rotacji trzeba ponownie zaszyfrować wszystkie dane”: nie trzeba. KMS trzyma stare wersje materiału i sam wybiera właściwą przy
Decrypt. - Udostępnienie snapshotu zaszyfrowanego kluczem AWS managed innemu kontu: polityki takiego klucza nie zmienisz. Najpierw skopiuj snapshot z kluczem customer managed.
- Throttling KMS przy S3 SSE-KMS: zamiast podnoszenia limitu najpierw włącz S3 Bucket Keys.
- Natychmiastowe usunięcie klucza: nie istnieje. Minimum to 7 dni oczekiwania. Natychmiast możesz go tylko wyłączyć.
Aplikacja szyfruje 2 000 000 małych rekordów dziennie, każdy własnym GenerateDataKey, i dostaje ThrottlingException. Wymień dwie zmiany w kodzie, które usuną problem bez zmiany limitów.
Odpowiedź
(1) Data key caching w AWS Encryption SDK, czyli jeden data key na wiele rekordów (z limitem wieku i liczby użyć). (2) Retry z exponential backoff i jitterem. Opcjonalnie paczkowanie rekordów i szyfrowanie paczki jednym kluczem.
Aplikacja musi zaszyfrować pliki o rozmiarze 100 MB przed zapisem do S3, a klucz ma być zarządzany przez KMS. Jakich wywołań API użyć?
> 4 KB · szyfrowanie po stronie klienta
Odpowiedź
GenerateDataKey → szyfrowanie pliku jawnym data key → zapis zaszyfrowanego klucza razem z plikiem. Do odczytu Decrypt zaszyfrowanego klucza. Najprościej przez AWS Encryption SDK.
Dlaczego nie: Encrypt (limit 4 KB), GenerateDataKeyWithoutPlaintext (nie da jawnego klucza do szyfrowania teraz), GenerateRandom (klucz bez ochrony KMS).
Zespół bezpieczeństwa wymaga rotacji klucza szyfrującego co 6 miesięcy, z historią rotacji i bez zmian w aplikacji.
okres rotacji · bez zmian w kodzie
Odpowiedź
Customer managed key z automatyczną rotacją i RotationPeriodInDays=180.
Dlaczego nie: AWS managed key (rotacja co rok, bez konfiguracji), ręczna rotacja przez alias (więcej pracy, choć też możliwa), importowany materiał (brak rotacji automatycznej).
Funkcja Lambda w koncie B ma odszyfrowywać dane zaszyfrowane kluczem customer managed z konta A. Co trzeba skonfigurować?
cross-account · dwie zgody
Odpowiedź
Key policy w koncie A zezwalająca roli (lub kontu) B na kms:Decrypt + polityka IAM roli wykonawczej Lambdy w koncie B z kms:Decrypt na ARN klucza.
Dlaczego nie: sama polityka IAM w B (klucz jej nie widzi), sama nazwa aliasu w wywołaniu (między kontami trzeba podać ARN klucza lub ARN aliasu), grant bez polityki IAM (możliwy, ale nie „najprostszy standard”).
Dane w tabeli DynamoDB global table (eu-west-1 i us-east-1) są szyfrowane po stronie klienta. Aplikacja w każdym Regionie ma odszyfrowywać lokalnie, bez wywołań między Regionami.
wiele Regionów · ten sam klucz
Odpowiedź
Multi-Region key (primary + replica) z tym samym key ID i materiałem.
Dlaczego nie: dwa niezależne klucze (szyfrogram z jednego Regionu nie odszyfruje się w drugim), ReEncrypt przy każdym odczycie (koszt i opóźnienie), CloudHSM (nie rozwiązuje replikacji).
Rola ma móc używać klucza KMS wyłącznie wtedy, gdy żądanie przychodzi przez Amazon S3, a nie przez bezpośrednie wywołania API.
tylko przez usługę
Odpowiedź
Warunek kms:ViaService = s3.<region>.amazonaws.com w key policy (lub IAM).
Dlaczego nie: aws:SourceIp (S3 nie woła z Twojego IP), encryption context (nie ogranicza ścieżki wywołania), grant (służy do delegowania, a nie do takiego warunku).
🔬 Głębiej: drobne fakty o KMS
- Okres oczekiwania na usunięcie może być w praktyce do 24 h dłuższy niż ustawiony.
- Klucze multi-Region z importowanym materiałem wymagają importu tego samego materiału do każdej repliki.
- Operacje na kluczach w custom key store liczą się do limitu konta i dodatkowo do limitu key store'u (np. 1800/s dla CloudHSM key store).
- W kluczach symetrycznych KMS używa AES-256-GCM. Szyfrogram zawiera metadane (m.in. identyfikator klucza i wersji materiału), dlatego
Decryptnie wymagaKeyId. - Kopia S3 przy replikacji między Regionami (CRR) odszyfrowuje i szyfruje dane ponownie kluczem w Regionie docelowym, nawet gdy to powiązany klucz multi-Region.
Encrypt≤ 4 KB. Duże dane:GenerateDataKey(jawny + zaszyfrowany), szyfrowanie lokalne,Decryptdata key przy odczycie.ReEncrypt= zmiana klucza w KMS.- Customer managed (pełna kontrola, płatny) / AWS managed (
aws/…, rotacja co rok, brak cross-account) / AWS owned (niewidoczny). - Key policy obowiązkowa. Wpis
:rootwłącza IAM. Cross-account = key policy + IAM w drugim koncie. Grants = programowe delegowanie. - Rotacja automatyczna 90–2560 dni (domyślnie 365), on-demand ≤ 25, ręczna przez alias dla asymetrycznych/HMAC/importowanych. Usunięcie: 7–30 dni.
- Encryption context = AAD w CloudTrail.
kms:ViaService= tylko przez usługę. Throttling → backoff, data key caching, S3 Bucket Keys.
Sekrety i konfiguracja: gdzie trzymać hasła, a gdzie flagi
Secrets Manager vs Parameter Store vs env vars vs AppConfigHasła do bazy, klucze API partnerów i flagi funkcji nie powinny mieszkać w kodzie. Pytanie egzaminacyjne brzmi zwykle: który magazyn wybrać. Analogia: Secrets Manager to sejf z automatem, który sam co miesiąc zmienia szyfr i informuje o tym bazę danych (rotacja). Parameter Store to segregator w szafie biurowej z przegródkami (/prod/db/host), w którym część kartek ma kłódkę (SecureString). AppConfig to pilot do aplikacji: zmieniasz ustawienie, a ono stopniowo trafia do działającej floty, z alarmem i automatycznym cofnięciem, jeśli coś pójdzie źle.
Zmienne środowiskowe Lambdy są wygodne, ale zmieniają się tylko przy aktualizacji konfiguracji funkcji i są widoczne dla każdego, kto może czytać konfigurację funkcji (o ile nie zaszyfrujesz ich dodatkowo). Na sekrety AWS zaleca Secrets Manager.
2.3.22.3.33.1.5
- Secrets Manager: sekrety z automatyczną rotacją (Lambda rotacyjna albo managed rotation dla RDS, Aurora, Redshift, DocumentDB), replikacja do innych Regionów, resource policy (cross-account), do 64 KB, płatny za sekret i za wywołania API. „Rotacja co 30 dni” → Secrets Manager.
- Parameter Store:
String,StringList,SecureString(KMS, domyślnie kluczaws/ssm). Tier standard: 10 000 parametrów, 4 KB, bez opłat. Advanced: 100 000 parametrów, 8 KB, parameter policies (expiration), udostępnianie między kontami, płatny. Hierarchia/app/prod/db+GetParametersByPath. Brak natywnej rotacji. „Najtańsza konfiguracja/sekret bez rotacji” → Parameter Store. - Wersje w Secrets Manager: etykiety
AWSCURRENT,AWSPENDING(w trakcie rotacji),AWSPREVIOUS. Lambda rotacyjna wykonuje krokicreateSecret→setSecret→testSecret→finishSecret. - Zmienne środowiskowe Lambdy są zawsze szyfrowane at rest kluczem KMS (domyślnie AWS managed, opcjonalnie customer managed). Encryption helpers w konsoli szyfrują wartość po stronie klienta („in transit”), a funkcja musi ją odszyfrować przez
kms:Decrypt. Łącznie maks. 4 KB. - AWS Parameters and Secrets Lambda Extension (warstwa) cache'uje parametry i sekrety lokalnie: żądanie HTTP na
localhost:2773z nagłówkiemX-Aws-Parameters-Secrets-Token(=AWS_SESSION_TOKEN). Mniej wywołań API, niższy koszt i opóźnienie. - CloudFormation dynamic references:
{{resolve:ssm:/path}},{{resolve:ssm-secure:/path}},{{resolve:secretsmanager:id:SecretString:password}}. Wartość nie trafia do szablonu. - AppConfig: konfiguracja i feature flags z walidatorami (JSON Schema albo Lambda), strategiami wdrożenia (linear/exponential, bake time) i automatycznym rollbackiem po alarmie CloudWatch. W Lambdzie: AppConfig Agent Lambda extension (
localhost:2772).
Porównanie
| Cecha | Secrets Manager | Parameter Store | AppConfig | Lambda env vars |
|---|---|---|---|---|
| Przeznaczenie | sekrety (hasła DB, klucze API) | konfiguracja i proste sekrety | konfiguracja dynamiczna, feature flags | konfiguracja jednej funkcji |
| Rotacja | ✔ automatyczna (Lambda lub managed) | ✖ (możesz zbudować sam) | – | ✖ |
| Szyfrowanie | zawsze KMS | tylko SecureString (KMS) | opcjonalnie KMS | zawsze KMS at rest + opcjonalne helpers |
| Rozmiar | 64 KB | 4 KB (standard) / 8 KB (advanced) | zależnie od źródła (hosted store do 2 MB) | 4 KB łącznie |
| Wersje | etykiety AWSCURRENT/AWSPENDING/AWSPREVIOUS + własne | do 100 wersji, labels (name:label) | wersje konfiguracji, wdrożenia | wersje funkcji |
| Wiele Regionów / kont | replikacja, resource policy | sharing (advanced, przez AWS RAM) | – | – |
| Koszt | za sekret/miesiąc + za wywołania | standard bez opłat, advanced płatny | za pobrania i konfiguracje | bez opłat |
| Zmiana bez redeployu | ✔ | ✔ | ✔ (z kontrolą wdrożenia) | ✖ (wymaga aktualizacji konfiguracji funkcji) |
Secrets Manager: rotacja i wersje
Rotacja to wymiana hasła w dwóch miejscach naraz: w sekrecie i w bazie. Robi to funkcja Lambda (gotowe szablony dla baz) w czterech krokach:
createSecret: generuje nowe hasło i zapisuje je jako wersjęAWSPENDING.setSecret: zmienia hasło w bazie lub usłudze na wartość zAWSPENDING.testSecret: loguje się nowym hasłem.finishSecret: przenosiAWSCURRENTna nową wersję. Stara dostajeAWSPREVIOUS.
- Harmonogram:
rate()albocron()z oknem rotacji. Najczęściej co 4 godziny, przy oknie co najmniej 1 h. - Strategie: single user (zmiana hasła jednego użytkownika; krótka chwila, gdy stare połączenia mogą dostać błąd) i alternating users (dwóch użytkowników na zmianę, rotacja bez przerwy; wymaga sekretu z uprawnieniami administratora do klonowania).
- Managed rotation: RDS, Aurora, Redshift i DocumentDB rotują hasło głównego użytkownika same, bez Lambdy (np. RDS „Manage master credentials in Secrets Manager”).
- Lambda rotacyjna w VPC potrzebuje dostępu do bazy i do endpointu Secrets Manager (VPC endpoint albo NAT).
- Replikacja sekretu do innych Regionów (DR, aplikacje wieloregionowe). Replikę można wypromować do samodzielnego sekretu.
- Resource policy na sekrecie daje dostęp innemu kontu. Sekret musi być wtedy szyfrowany kluczem customer managed, bo klucza
aws/secretsmanagernie da się użyć cross-account. - Caching: biblioteki klienckie (Java, Python, .NET, Go) i Lambda extension przechowują sekret lokalnie, co zmniejsza koszt i opóźnienie. Limit
GetSecretValueto 10 000 żądań/s.
# Python: odczyt sekretu i cache po stronie klienta
import boto3, json
from aws_secretsmanager_caching import SecretCache
cache = SecretCache(client=boto3.client("secretsmanager"))
db = json.loads(cache.get_secret_string("prod/orders/db")) # {"username":..., "password":...}
# CLI
aws secretsmanager get-secret-value --secret-id prod/orders/db --version-stage AWSPREVIOUS
Parameter Store: hierarchie, typy i tiery
| Opcja | Co robi | Kiedy |
|---|---|---|
String | zwykły tekst | URL, nazwa tabeli, ID AMI |
StringList | lista rozdzielona przecinkami | lista Regionów, adresów |
SecureString | wartość szyfrowana KMS (aws/ssm lub customer managed); odczyt z --with-decryption / WithDecryption=True i uprawnieniem kms:Decrypt | hasła, tokeny, gdy nie potrzebujesz rotacji |
| Standard tier | 10 000 parametrów, 4 KB, bez polityk, bez opłat | domyślnie |
| Advanced tier | 100 000 parametrów, 8 KB, parameter policies, sharing; płatny; nie da się cofnąć do standard | duże wartości, wygasanie, wiele kont |
| Parameter policies (advanced) | Expiration (usuwa parametr), ExpirationNotification i NoChangeNotification (zdarzenia w EventBridge) | tymczasowe hasła, przypomnienie o zmianie |
| Hierarchie | ścieżki /app/prod/db/url (do 15 poziomów); GetParametersByPath --recursive; uprawnienia IAM na ścieżkę | konfiguracja per środowisko: /app/dev/… vs /app/prod/… |
| Wersje i labels | do 100 wersji; label (np. prod) wskazuje wersję: /app/db:prod albo /app/db:3 | przypięcie konfiguracji, rollback |
| Public parameters | parametry publikowane przez AWS w /aws/service/… (np. najnowsze AMI) | „zawsze najnowszy Amazon Linux AMI” w szablonie |
| Odwołanie do Secrets Manager | /aws/reference/secretsmanager/<nazwa> przez API Parameter Store | jeden interfejs dla konfiguracji i sekretów |
Parameter Store ma domyślny limit przepustowości. Przy bardzo częstych odczytach (np. Lambda czytająca parametr przy każdym wywołaniu) możesz dostać throttling. Rozwiązania: cache (Lambda extension, odczyt w fazie init), higher throughput (płatne) albo GetParameters/GetParametersByPath zamiast wielu pojedynczych wywołań.
Lambda: zmienne środowiskowe, extension i dynamic references
- Lambda zawsze szyfruje zmienne środowiskowe at rest. Domyślnie kluczem AWS managed (bez dodatkowych uprawnień), opcjonalnie customer managed key (wtedy rola wdrażająca potrzebuje uprawnień do klucza).
- Encryption helpers („Enable helpers for encryption in transit”) szyfrują wartość w konsoli po stronie klienta. W konsoli widać szyfrogram, a funkcja musi wywołać
kms:Decryptw kodzie (najlepiej raz, poza handlerem). Chroni to wartość przed osobami, które widzą konfigurację funkcji. - Lepiej trzymać sekret w Secrets Manager / Parameter Store, a w zmiennej środowiskowej tylko jego nazwę lub ARN.
# Lambda + AWS Parameters and Secrets Lambda Extension (warstwa)
import os, json, urllib.request
def handler(event, context):
req = urllib.request.Request(
"http://localhost:2773/secretsmanager/get?secretId=prod%2Forders%2Fdb",
headers={"X-Aws-Parameters-Secrets-Token": os.environ["AWS_SESSION_TOKEN"]})
secret = json.loads(urllib.request.urlopen(req).read())["SecretString"]
# parametry: /systemsmanager/parameters/get?name=%2Fapp%2Fprod%2Furl&withDecryption=true
# TTL cache: SECRETS_MANAGER_TTL, SSM_PARAMETER_STORE_TTL; rozmiar: PARAMETERS_SECRETS_EXTENSION_CACHE_SIZE
# CloudFormation: dynamic references (maks. 60 w szablonie)
MasterUsername: '{{resolve:secretsmanager:prod/orders/db:SecretString:username}}'
MasterUserPassword: '{{resolve:secretsmanager:prod/orders/db:SecretString:password}}'
ImageId: '{{resolve:ssm:/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-6.1-x86_64}}'
# {{resolve:ssm-secure:/app/prod/token}} – SecureString, tylko w wybranych właściwościach zasobów
Parametry szablonu typu AWS::SSM::Parameter::Value<String> to druga, starsza metoda pobierania wartości z Parameter Store w CloudFormation (więcej w rozdziale CloudFormation).
AWS AppConfig: konfiguracja na żywo
AppConfig rozwiązuje problem: „chcę zmienić zachowanie działającej aplikacji bez deployu kodu, ale bezpiecznie”. Elementy:
| Opcja | Co robi | Kiedy |
|---|---|---|
| Application / Environment | logiczna aplikacja i jej środowiska (dev, prod), do środowiska przypinasz alarmy CloudWatch | zawsze |
| Configuration profile | typ feature flags albo freeform; źródło: AppConfig hosted store, S3, Parameter Store, Secrets Manager, SSM documents, CodePipeline | flagi on/off z atrybutami, dowolny JSON/YAML/tekst |
| Validators | JSON Schema albo funkcja Lambda (do 15 s); błąd walidacji zatrzymuje wdrożenie; flagi są walidowane automatycznie | chronią przed literówką, która położy produkcję |
| Deployment strategy | typ linear albo exponential, step percentage (growth factor), czas wdrożenia, bake time (monitoring po 100%) | stopniowe udostępnianie zmiany |
| Predefiniowane strategie | AppConfig.AllAtOnce (od razu, bake 10 min), AppConfig.Linear50PercentEvery30Seconds (testy), AppConfig.Linear20PercentEvery6Minutes i AppConfig.Canary10Percent20Minutes (zalecane przez AWS) | szybki start |
| Rollback | alarm CloudWatch w trakcie wdrożenia lub bake time → AppConfig sam przywraca poprzednią wersję | „automatycznie wycofaj zmianę konfiguracji, gdy rośnie liczba błędów” |
| AppConfig Agent (Lambda extension, ECS, EKS, EC2) | sam odpytuje AppConfig w tle i cache'uje; aplikacja czyta z http://localhost:2772/applications/…/environments/…/configurations/… | zamiast ręcznych StartConfigurationSession/GetLatestConfiguration |
- Parameter Store SecureString, gdy pytanie wymaga automatycznej rotacji: Parameter Store nie rotuje. Odpowiedzią jest Secrets Manager.
- Secrets Manager, gdy pytanie mówi „najtańszy” i nie wspomina o rotacji: standardowe parametry (także
SecureString) są bez opłat. - Hasło w zmiennej środowiskowej „bo Lambda szyfruje at rest”: każdy z
lambda:GetFunctionConfigurationzobaczy wartość jawnie. Do sekretów służą Secrets Manager, Parameter Store albo przynajmniej encryption helpers +kms:Decryptw kodzie. - Odczyt sekretu przy każdym wywołaniu Lambdy: koszt, opóźnienie i ryzyko throttlingu. Pobierz go w fazie init albo użyj extension lub biblioteki cache.
- Cross-account sekret zaszyfrowany
aws/secretsmanager: nie zadziała. Potrzebny jest customer managed key z polityką dla drugiego konta. - Feature flag w zmiennej środowiskowej: zmiana wymaga aktualizacji funkcji i nie ma stopniowego wdrożenia ani rollbacku. Do flag służy AppConfig.
- Advanced → standard: tier advanced nie da się cofnąć.
- Sekret w parametrze szablonu CloudFormation z
NoEcho: lepsza odpowiedź to dynamic reference do Secrets Manager/SSM.
Secrets Manager potrafi wygenerować hasło (GetRandomPassword) z wymaganiami co do znaków. Szablony Lambd rotacyjnych z niego korzystają, więc nowe hasło nigdy nie przechodzi przez ręce człowieka.
Hasło do bazy Amazon RDS musi być zmieniane automatycznie co 30 dni, a aplikacja ma zawsze pobierać aktualne hasło. Najmniej pracy operacyjnej.
rotacja · RDS · najmniej pracy
Odpowiedź
Secrets Manager z managed rotation (lub rotacją z szablonu Lambdy) co 30 dni. Aplikacja pobiera AWSCURRENT, najlepiej z cache.
Dlaczego nie: Parameter Store SecureString (brak rotacji), zmienne środowiskowe (brak rotacji, wymaga redeployu), KMS (szyfruje, ale nie przechowuje ani nie rotuje hasła bazy).
Aplikacja potrzebuje kilkudziesięciu ustawień (URL-e, nazwy kolejek) różnych dla dev, test i prod, przy minimalnym koszcie. Ustawienia mają być pobierane jednym wywołaniem per środowisko.
konfiguracja · per środowisko · tanio
Odpowiedź
Parameter Store (standard) z hierarchią /app/<env>/… i GetParametersByPath.
Dlaczego nie: Secrets Manager (płatny za każdy sekret, przeznaczony do sekretów), AppConfig (możliwe, ale bardziej rozbudowane, niż potrzeba), DynamoDB (więcej pracy).
Zespół chce włączać nową funkcję dla rosnącego odsetka użytkowników i automatycznie ją wyłączyć, gdy alarm błędów 5xx przejdzie w stan ALARM. Bez wdrażania kodu.
feature flag · stopniowo · rollback
Odpowiedź
AWS AppConfig: profil feature flags, strategia linear/exponential, alarm CloudWatch na środowisku (automatyczny rollback), w Lambdzie AppConfig Agent extension.
Dlaczego nie: Parameter Store (brak stopniowego wdrożenia i rollbacku), zmienne środowiskowe (wymagają update funkcji), CodeDeploy (wdraża kod, a nie konfigurację).
Lambda wywoływana 500 razy na sekundę czyta przy każdym wywołaniu parametr z Parameter Store i dostaje ThrottlingException. Najprostsza poprawka?
częste odczyty · throttling · cache
Odpowiedź
Cache: AWS Parameters and Secrets Lambda Extension (TTL) albo odczyt w kodzie init poza handlerem. Ewentualnie higher throughput.
Dlaczego nie: advanced tier (dotyczy rozmiaru i polityk, a nie przepustowości), reserved concurrency (ogranicza funkcję, nie rozwiązuje przyczyny), zmiana na Secrets Manager (też płaci się za wywołania, problem zostaje).
Szablon CloudFormation tworzy bazę RDS. Hasło administratora nie może pojawić się w szablonie ani w parametrach stosu.
CloudFormation · bez hasła w szablonie
Odpowiedź
Dynamic reference {{resolve:secretsmanager:…:SecretString:password}} (albo ManageMasterUserPassword w RDS z Secrets Manager).
Dlaczego nie: parametr NoEcho (hasło nadal przekazywane przy tworzeniu stosu), hasło w zmiennej środowiskowej (bez związku), ssm zwykły String (niezaszyfrowany).
🔬 Głębiej: limity i drobiazgi
- Secrets Manager: maks. 100 wersji na sekret, 20 etykiet łącznie, 500 000 sekretów na Region, resource policy do 20 480 znaków.
DescribeSecret40 000/s,CreateSecret/PutSecretValue50/s. - Usunięcie sekretu: z okresem odzyskiwania (domyślnie 30 dni, można 7–30) albo natychmiast z
--force-delete-without-recovery. - Parameter Store ma też tier
Intelligent-Tiering, który sam wybiera standard lub advanced zależnie od potrzeb parametru. - Po 100 wersjach parametru najstarsza jest usuwana przy tworzeniu nowej, chyba że ma label (wtedy operacja się nie powiedzie).
- Klucz pary EC2 utworzony przez CloudFormation trafia (klucz prywatny) do Parameter Store pod
/ec2/keypair/<key-pair-id>.
- Rotacja / replikacja / sekrety DB → Secrets Manager (
AWSCURRENT/AWSPENDING/AWSPREVIOUS, 4 kroki Lambdy, managed rotation dla RDS). - Tania konfiguracja i proste sekrety → Parameter Store (SecureString, hierarchie,
GetParametersByPath, standard 4 KB / advanced 8 KB + policies). - Feature flags, walidacja, stopniowe wdrożenie, rollback na alarm → AppConfig (+ Agent extension
:2772). - Env vars Lambdy: KMS at rest zawsze, helpers do szyfrowania w tranzycie, 4 KB. Extension
:2773= cache sekretów i parametrów. - CloudFormation:
{{resolve:ssm|ssm-secure|secretsmanager:…}}.
Ochrona danych: certyfikaty, WAF, PII i izolacja tenantów
TLS/ACM/Private CA, klucze SSH, WAF, maskowanie logów, LeadingKeys, M2MWyobraź sobie przychodnię. Drzwi wejściowe mają ochroniarza, który nie wpuszcza podejrzanych (to WAF). Korytarze między gabinetami są zamknięte, a każdy lekarz nosi identyfikator wydany przez przychodnię (to certyfikaty TLS i uwierzytelnianie między usługami). Karty pacjentów leżą w szafie, w której każdy lekarz otwiera tylko szuflady swoich pacjentów (to izolacja tenantów). W rejestrze wizyt PESEL jest zamazany gwiazdkami (to maskowanie PII).
Ten rozdział zbiera tematy z domeny „Security”, które nie zmieściły się w rozdziałach o Cognito, KMS i sekretach. Pytania są tu zwykle krótkie i decyduje jedno słowo: „us-east-1”, „rate limit”, „mask”, „tenant”, „machine-to-machine”.
2.1.82.2.12.2.22.2.52.3.12.3.42.3.52.3.6
- ACM: publiczne certyfikaty dla usług zintegrowanych (ELB, CloudFront, API Gateway) są bez dodatkowej opłaty i odnawiają się same, jeśli walidacja domeny jest przez DNS. Certyfikaty importowane nie mają managed renewal, więc ich wygasanie śledzisz sam (EventBridge).
- Certyfikat ACM dla CloudFront i dla edge-optimized custom domain w API Gateway musi być w us-east-1. Dla ALB i Regional API: w tym samym Regionie co zasób. Certyfikaty ACM są zasobami regionalnymi.
- AWS Private CA = własna hierarchia CA (root + subordinate) dla certyfikatów wewnętrznych (mTLS, usługi w VPC, urządzenia). Płacisz miesięcznie za każde CA.
- Klucze SSH do EC2:
aws ec2 create-key-pair(AWS trzyma klucz publiczny, prywatny pobierasz tylko raz) albossh-keygen+aws ec2 import-key-pair. RSA 2048 lub ED25519 (ED25519 tylko Linux). - AWS WAF (web ACL) podpinasz do CloudFront, ALB, API Gateway REST API, AppSync, Cognito user pool (i kilku innych). Nie do NLB, HTTP API ani bezpośrednio do EC2. Rate-based rule = limit żądań z jednego IP w oknie czasu.
- CloudWatch Logs data protection policy wykrywa i maskuje PII w logach przy ingestii. Odmaskowane dane widzi tylko ktoś z uprawnieniem
logs:Unmask. - Multi-tenant w puli (pool): klucz partycji =
tenantId, a polityka IAM z warunkiemdynamodb:LeadingKeys=${aws:PrincipalTag/tenant}(session tag zsts:TagSession). Dla S3: prefiksbucket/${aws:PrincipalTag/tenant}/*. - Usługa → usługa: rola IAM + SigV4 (np. API Gateway z
AWS_IAM), Cognito client credentials (M2M, OAuth 2.0 scopes) albo mTLS na custom domain API Gateway.
dynamodb:LeadingKeys pilnują, kto czyta które wierszecustom:tenant = ?tenant = ?Orders (PK = tenantId)ForAllValues przy braku klucza w żądaniu (zwraca true) zgadza się z dokumentacją IAM.Szyfrowanie w spoczynku i w tranzycie
W spoczynku (at rest) chronisz dane leżące na dysku: S3, EBS, RDS, DynamoDB, logi. Prawie zawsze robi to KMS po stronie serwera. W tranzycie (in transit) chronisz dane płynące siecią, czyli TLS (HTTPS). Do TLS potrzebujesz certyfikatu, a tu wchodzą ACM i Private CA. Szczegóły SSE-S3/SSE-KMS/client-side i wymuszanie HTTPS w bucket policy (aws:SecureTransport) znajdziesz w rozdziale S3: bezpieczeństwo.
| Opcja | Co robi | Kiedy |
|---|---|---|
| SSE z KMS (at rest) | usługa szyfruje dane kluczem z KMS | domyślny wybór dla danych w usługach AWS |
| Client-side encryption | szyfrujesz przed wysłaniem (np. AWS Encryption SDK) | „AWS nie może widzieć danych jawnych” |
| TLS z certyfikatem ACM | HTTPS na ALB, CloudFront, API Gateway | ruch od klientów z internetu |
| TLS end-to-end | szyfrowanie także między load balancerem a targetem | wymóg „encryption in transit end to end” |
| CloudFront field-level encryption | szyfruje wybrane pola POST kluczem publicznym na krawędzi (do 10 pól) | numer karty widzi tylko jeden mikroserwis z kluczem prywatnym |
Certyfikaty: ACM, import i AWS Private CA
Certyfikat TLS to „dowód osobisty” serwera. Publiczny wydaje urząd, któremu ufają przeglądarki. Prywatny wydaje Twoja własna „firmowa przepustkownia”, której ufają tylko Twoje systemy.
| Opcja | Co robi | Kiedy |
|---|---|---|
| ACM public | publiczny certyfikat (walidacja DNS lub e-mail), managed renewal; bez opłaty dla usług zintegrowanych | HTTPS na ALB, CloudFront, API Gateway |
| ACM exportable public | publiczny certyfikat z dostępem do klucza prywatnego (ExportCertificate); płatny, odnawiany przez ACM | serwer na EC2, w kontenerze albo on-premises |
| Import do ACM | wgrywasz certyfikat od zewnętrznego CA (PEM, nieszyfrowany klucz prywatny ≤ 5 KB) | certyfikat już kupiony u innego wystawcy; brak automatycznego odnowienia |
| AWS Private CA | hierarchia root + subordinate CA, wydaje prywatne certyfikaty X.509; regionalna | mTLS, usługi wewnętrzne, IoT, Kubernetes |
| ACM private certificate | certyfikat z Twojego Private CA zarządzany przez ACM (odnawianie, eksport) | wewnętrzny ALB / API z prywatną domeną |
- Walidacja: DNS (rekord CNAME, zalecana, odnawianie w pełni automatyczne) albo e-mail (odnowienie wymaga kliknięcia w maila). Certyfikat utworzony przez CloudFormation z walidacją e-mail trzyma stos w
CREATE_IN_PROGRESS, dopóki ktoś nie zatwierdzi maila. - Ważność: publiczny certyfikat ACM jest ważny 198 dni. ACM próbuje go odnowić 45 dni przed wygaśnięciem. ARN po odnowieniu się nie zmienia. W starszych materiałach spotkasz inne (dłuższe) okresy ważności — liczy się aktualna dokumentacja.
- Region: CloudFront i edge-optimized custom domain →
us-east-1. ALB, Regional API → ten sam Region. Ten sam FQDN na ALB w dwóch Regionach = dwa certyfikaty (po jednym w każdym Regionie). - Wildcard
*.example.comchroni jeden poziom subdomen (api.example.comtak,a.b.example.comnie). - Private CA: tryb general-purpose (dowolna ważność) albo short-lived certificate (certyfikaty ważne maks. 7 dni). CA jest regionalne i nie da się go skopiować do innego Regionu.
Certyfikaty i klucze SSH do developmentu
Do testów lokalnych nie potrzebujesz publicznego CA. Wystarczy certyfikat self-signed z OpenSSL. Można go nawet zaimportować do ACM (import przyjmuje certyfikaty self-signed), ale przeglądarki nie będą mu ufać.
# self-signed certyfikat dla localhost (dev)
openssl req -x509 -newkey rsa:2048 -nodes -keyout key.pem -out cert.pem -days 30 -subj "/CN=localhost"
aws acm import-certificate --certificate fileb://cert.pem --private-key fileb://key.pem
# klucz SSH: wygenerowany przez AWS (prywatny pobierasz raz)
aws ec2 create-key-pair --key-name dev --key-type ed25519 --query KeyMaterial --output text > dev.pem
chmod 400 dev.pem
# albo własny klucz i import samej części publicznej
ssh-keygen -t ed25519 -f ~/.ssh/dev
aws ec2 import-key-pair --key-name dev2 --public-key-material fileb://~/.ssh/dev.pub
- EC2 przyjmuje RSA 2048-bit (Linux i Windows) oraz ED25519 (tylko Linux). Klucz publiczny trafia przy starcie do
~/.ssh/authorized_keys. - AWS nie przechowuje kopii klucza prywatnego, więc zgubionego klucza nie odzyskasz. Para kluczy utworzona przez CloudFormation zapisuje klucz prywatny w Parameter Store pod
/ec2/keypair/<key_pair_id>. - Import akceptuje m.in. format OpenSSH. Klucz prywatny do połączenia ma być w formacie PEM lub PPK (
ssh-keygen -m PEM).
AWS WAF: ochroniarz przed aplikacją
WAF ogląda każde żądanie HTTP(S), zanim dotrze do aplikacji. Web ACL (w nowej konsoli: protection pack (web ACL)) to lista reguł sprawdzanych po kolei według priorytetu, plus domyślna akcja (Allow albo Block) dla żądań, do których nie pasuje żadna reguła. Zablokowane żądanie dostaje domyślnie 403 Forbidden.
| Opcja | Co robi | Kiedy |
|---|---|---|
| Regular rule | dopasowanie: IP set, kraj (geo match), nagłówek, SQLi, XSS, rozmiar, regex | blokada znanych wzorców ataków lub krajów |
| Rate-based rule | liczy żądania na agregat (domyślnie IP) w oknie 60/120/300/600 s (domyślnie 300); limit od 10 | „jeden IP zalewa login/API”, brute force, prosty DDoS warstwy 7 |
| AWS Managed Rules | gotowe grupy: AWSManagedRulesCommonRuleSet, …SQLiRuleSet, …KnownBadInputsRuleSet, …AmazonIpReputationList, Bot Control (dodatkowo płatna) | „najmniej pracy”, ochrona przed OWASP Top 10 |
| Akcje | Allow, Block, Count, CAPTCHA, Challenge | Count = testuj regułę bez blokowania ruchu |
- Podpinasz do: CloudFront, API Gateway REST API, ALB, AppSync, Cognito user pool, App Runner, Verified Access, Amplify. Web ACL dla CloudFront (zasięg globalny) tworzysz w us-east-1.
- Brak na liście: NLB, HTTP API API Gateway, EC2 bezpośrednio. Chcesz WAF przed EC2? Postaw przed nim ALB albo CloudFront.
- Pojemność web ACL liczy się w WCU. Powyżej 1 500 WCU płacisz więcej niż cena podstawowa. Rate-based rule kosztuje 2 WCU bazowo.
- Rate-based rule blokuje „w okolicy” limitu, bez gwarancji co do pojedynczego żądania.
Klasyfikacja danych: PII i PHI
PII (personally identifiable information) to dane identyfikujące osobę: imię i nazwisko, e-mail, telefon, adres, numer dokumentu, numer karty. PHI (protected health information) to dane zdrowotne powiązane z osobą, chronione m.in. przez HIPAA. Klasyfikacja mówi Ci, gdzie takie dane mogą trafić: do bazy szyfrowanej KMS tak, do logów debugowych nie.
- Amazon Macie automatycznie znajduje dane wrażliwe w S3 (machine learning + pattern matching). To odpowiedź na „znajdź PII w bucketach”, nie na „zamaskuj PII w logach”.
- CloudWatch Logs data protection chroni logi (niżej). Powertools for AWS Lambda (Python) ma narzędzie data masking:
erase(nieodwracalnie,*****),encrypt/decrypt(przez KMS) dla pól w Twoich obiektach.
Maskowanie w CloudWatch Logs
Analogia: drukarka w rejestracji, która sama zamazuje PESEL na każdym wydruku. Wszyscy widzą gwiazdki, a tylko kierownik z kluczykiem zobaczy oryginał.
- Data protection policy na log group albo na całe konto (wszystkie grupy). Każda grupa ma maks. jedną politykę na poziomie grupy. Polityka konta i grupy sumują się.
- Wybierasz managed data identifiers (e-mail, numer karty, adres IP, klucze AWS…) i do 10 custom data identifiers (regex ≤ 200 znaków).
- Wykrywanie i maskowanie dzieje się przy ingestii. Zdarzenia zapisane przed włączeniem polityki nie zostaną zamaskowane.
- Maskowanie obowiązuje na wszystkich wyjściach: konsola, Logs Insights, metric filters, subscription filters. Oryginał zobaczy tylko principal z
logs:Unmask. - Audit findings (opcjonalnie) wysyłasz do innej log group, S3 albo Firehose. Działa dla klas Standard i Infrequent Access.
aws logs put-data-protection-policy --log-group-identifier /app/orders \
--policy-document file://policy.json # Audit + Deidentify (MaskConfig)
aws logs put-account-policy --policy-type DATA_PROTECTION_POLICY ... # dla wszystkich grup
Sanityzacja: wejście, wyjście, logi
- Wejście: odrzucaj złe dane jak najwcześniej. W API Gateway: request validation (JSON Schema, 400). Przed API: WAF (SQLi/XSS). W kodzie: zapytania parametryzowane zamiast sklejania SQL.
- Wyjście: zwracaj tylko potrzebne pola (projekcja w DynamoDB, mapping template w API Gateway), nie odsyłaj stack trace’ów ani wewnętrznych ID klientowi.
- Logi: nie loguj tokenów, haseł, całych nagłówków
Authorizationani payloadów z PII. Loguj identyfikatory, a nie dane. Jako siatka bezpieczeństwa: data protection policy w CloudWatch Logs. - Sekrety: nigdy w kodzie ani w zwykłych env vars (patrz sekrety).
Aplikacje multi-tenant: silo, pool, bridge
Tenant to klient Twojego SaaS (firma). Dane tenantów możesz trzymać na trzy sposoby. Analogia: osobne mieszkania (silo), wspólny akademik z zamykanymi szafkami (pool) albo akademik z kilkoma prywatnymi apartamentami dla VIP-ów (bridge).
| Model | Co robi | Kiedy |
|---|---|---|
| Silo | osobne zasoby na tenanta (konto, tabela, bucket, stos) | ścisłe wymagania izolacji/compliance; brak „noisy neighbor”, ale drożej i trudniej w operacjach |
| Pool | wspólne zasoby, dane rozdzielone kluczem (tenantId) | efektywność kosztowa i skala; izolację musisz wymusić polityką |
| Bridge | mieszanka: część warstw silo, część pool | typowy przypadek w praktyce |
W modelu pool sama logika aplikacji („WHERE tenant = …”) to za mało: jeden błąd w kodzie i tenant A czyta dane B. Pewniejsze jest tenant-scoped credentials: usługa po odczytaniu tenanta z JWT robi sts:AssumeRole z session tag tenant=acme, a polityka roli wpuszcza tylko do wierszy i prefiksów tego tenanta.
{ "Effect": "Allow",
"Action": ["dynamodb:GetItem", "dynamodb:Query", "dynamodb:PutItem"],
"Resource": "arn:aws:dynamodb:eu-west-1:111122223333:table/Orders",
"Condition": { "ForAllValues:StringEquals": {
"dynamodb:LeadingKeys": ["${aws:PrincipalTag/tenant}"] } } },
{ "Effect": "Allow", "Action": ["s3:GetObject", "s3:PutObject"],
"Resource": "arn:aws:s3:::docs-bucket/${aws:PrincipalTag/tenant}/*" }
dynamodb:LeadingKeys= wartość klucza partycji. Nazwa jest w liczbie mnogiej nawet dla pojedynczego elementu i wymagaForAllValues. Do ograniczania kolumn służydynamodb:Attributes(plusSelect,ReturnValues).- Session tags: przekazujesz je w
AssumeRole,AssumeRoleWithWebIdentity,AssumeRoleWithSAMLlubGetFederationToken. Trust policy roli musi zezwalać nasts:TagSession. Limity: maks. 50 tagów, klucz ≤ 128 znaków, wartość ≤ 256 znaków. W politykach czytasz je jakoaws:PrincipalTag/<klucz>. - Tag sesji o tym samym kluczu co tag roli nadpisuje go. Tag transitive przechodzi dalej przy role chaining (tagi roli nie mogą być transitive).
- Cognito identity pool potrafi sam zamienić claimy z tokenu na principal tags (attributes for access control), bez własnego kodu z AssumeRole.
- Silo w DynamoDB = tabela na tenanta i polityka na ARN tabeli; w S3 = bucket na tenanta albo prefiks + polityka.
Uwierzytelnianie usługa → usługa
| Opcja | Co robi | Kiedy |
|---|---|---|
| Rola IAM + SigV4 | usługa wołająca ma rolę (Lambda execution role, task role), SDK podpisuje żądanie; API Gateway z autoryzacją AWS_IAM sprawdza execute-api:Invoke | obie strony w AWS; najmniej kodu, brak sekretów |
| Cognito client credentials | app client z client secret dostaje access token ze scopes zdefiniowanymi w resource server (M2M) | wywołujący spoza AWS IAM (partner, serwis on-premises), autoryzacja przez OAuth 2.0 scopes |
| mTLS na custom domain API Gateway | klient pokazuje certyfikat X.509; truststore (łańcuch CA) leży w S3 | „klienci uwierzytelniają się certyfikatem”, IoT, B2B; wyłącz domyślny endpoint execute-api |
| Cross-account AssumeRole | rola w koncie docelowym z trust policy na konto źródłowe | mikroserwisy w różnych kontach (patrz IAM) |
Szczegóły authorizerów API Gateway są w rozdziale API Gateway: stage’e i bezpieczeństwo, a scopes, resource servers i tokeny w rozdziale Cognito. mTLS wymaga custom domain, a cały łańcuch zaufania wystawcy certyfikatu klienta (aż do root CA) musi być w truststore. Certyfikaty klientów możesz wydawać z AWS Private CA.
- Certyfikat ACM dla CloudFront w Regionie aplikacji (np. eu-west-1). Kusi, bo „tam jest ALB”. CloudFront widzi tylko certyfikaty z us-east-1.
- „Certyfikat importowany odnowi się sam”. Nie. Managed renewal dotyczy certyfikatów wydanych przez ACM. Importowany odnawiasz i reimportujesz sam.
- WAF na NLB albo na HTTP API. WAF działa na warstwie 7 i obsługuje REST API, ALB, CloudFront, AppSync, Cognito. Dla NLB/EC2: CloudFront lub ALB przed nimi.
- AWS Shield zamiast rate-based rule. Shield chroni przed DDoS na poziomie infrastruktury. „Ogranicz liczbę żądań z jednego IP” to rate-based rule w WAF.
- Macie do maskowania logów. Macie skanuje S3. Logi maskuje CloudWatch Logs data protection policy.
- „Polityka maskowania ukryje też stare logi”. Nie. Działa tylko na zdarzenia zapisane po jej utworzeniu.
- Izolacja tenantów tylko w kodzie („filtrujemy po tenantId”). Egzamin woli wymuszenie w IAM:
dynamodb:LeadingKeys+ session tags. dynamodb:Scanw polityce zForAllValues. Scan nie podaje klucza partycji, aForAllValueszwracatrue, gdy w żądaniu brak klucza. Efekt: dostęp do wszystkich tenantów. Nie dawaj Scan albo dodaj warunekNull.- Klucze dostępu IAM użytkownika w kodzie mikroserwisu. Między usługami AWS używaj ról (tymczasowe poświadczenia).
Twój SaaS ma 2 000 małych tenantów i 3 ogromnych, którzy w umowie żądają „fizycznie osobnej bazy”. Który model wybierzesz? (Podpowiedź: nie musisz wybierać jednego. Pool dla małych i silo dla trzech dużych to model bridge.)
Zespół wystawia stronę przez CloudFront z własną domeną shop.example.com. Aplikacja działa w eu-central-1. Certyfikat ACM utworzony w eu-central-1 nie pojawia się na liście w ustawieniach dystrybucji. Co zrobić?
CloudFront · custom domain · ACM · Region
Odpowiedź
Zamówić (lub zaimportować) certyfikat w us-east-1. CloudFront używa tylko certyfikatów ACM z US East (N. Virginia).
Dlaczego nie: eksport certyfikatu i import w CloudFront (CloudFront nie przyjmuje plików, tylko certyfikaty ACM/IAM), Private CA (przeglądarki mu nie ufają), zmiana Regionu aplikacji (niepotrzebna).
API REST w API Gateway jest atakowane: kilka adresów IP wysyła tysiące żądań na /login. Jak zablokować nadmiarowy ruch z pojedynczych IP przy minimalnym nakładzie pracy?
per IP · limit żądań · REST API
Odpowiedź
AWS WAF web ACL z rate-based rule (agregacja po IP, scope-down na ścieżkę /login) podpięty do stage’a REST API.
Dlaczego nie: throttling stage’a API Gateway (limit dla wszystkich klientów naraz, nie per IP), usage plan (per API key, nie per IP), Shield Advanced (DDoS infrastruktury, droższy, nie o to pytają).
Audyt wykazał adresy e-mail i numery kart w logach Lambdy w CloudWatch Logs. Deweloperzy muszą dalej czytać logi, ale bez tych danych. Zespół bezpieczeństwa ma mieć dostęp do oryginałów.
mask · logi · wybrane osoby widzą oryginał
Odpowiedź
Data protection policy na log group (managed data identifiers: EmailAddress, CreditCardNumber) i uprawnienie logs:Unmask tylko dla zespołu bezpieczeństwa. Do tego poprawka kodu, żeby PII w ogóle nie logował.
Dlaczego nie: Macie (skanuje S3), szyfrowanie log group kluczem KMS (deweloper z dostępem i tak widzi jawny tekst), metric filter (nie maskuje).
SaaS trzyma zamówienia wszystkich klientów w jednej tabeli DynamoDB z kluczem partycji TenantId. Trzeba zagwarantować na poziomie AWS, że kod obsługujący tenanta A nie odczyta danych tenanta B.
pool · tenant isolation · IAM · partition key
Odpowiedź
AssumeRole z session tagiem tenant i polityka z ForAllValues:StringEquals na dynamodb:LeadingKeys = ${aws:PrincipalTag/tenant}.
Dlaczego nie: osobna tabela na tenanta (to silo, a pytanie dotyczy istniejącej wspólnej tabeli), filtr w kodzie (nie wymusza izolacji), dynamodb:Attributes (ogranicza kolumny, nie wiersze).
Serwis partnera działa poza AWS i ma wywoływać Twoje API Gateway bez kontekstu użytkownika. Chcesz OAuth 2.0 z uprawnieniami orders/read i orders/write.
machine-to-machine · scopes · bez użytkownika
Odpowiedź
Cognito user pool: resource server z custom scopes + app client z client secret i grantem client credentials. API Gateway weryfikuje access token Cognito authorizerem (scopes na metodzie).
Dlaczego nie: identity pool (daje poświadczenia AWS, nie scopes), API key (to nie uwierzytelnianie), użytkownik IAM z kluczami u partnera (długoterminowe sekrety).
Urządzenia klientów mają się uwierzytelniać do REST API certyfikatami X.509 wydanymi przez firmowe CA. Nikt nie może ominąć tego mechanizmu.
certyfikat klienta · mutual TLS · nie da się obejść
Odpowiedź
Custom domain z mTLS (truststore z łańcuchem CA w S3), certyfikaty z AWS Private CA, i wyłączenie domyślnego endpointu execute-api.
Dlaczego nie: Lambda authorizer czytający certyfikat z nagłówka (klient może go podrobić), WAF (nie weryfikuje certyfikatów klienta), zostawienie domyślnego endpointu (omija mTLS).
🔬 Głębiej: drobiazgi rzadko pytane
- ACM ma też certyfikaty wydawane przez protokół ACME (np. na EC2). Nie da się ich używać z usługami zintegrowanymi i nie mają managed renewal ACM, bo odnawia je klient ACME.
- Klucz prywatny importowany do ACM musi być nieszyfrowany i mieć maks. 5 KB. Cały materiał (certyfikat, klucz, łańcuch) w PEM.
- Domain name w żądaniu certyfikatu: maks. 64 znaki (RFC 5280).
- WAF może przy wewnętrznym błędzie przepuścić żądanie do CloudFront (fail open). Nowy adres w IP set może przez chwilę działać w jednym miejscu, a w innym jeszcze nie.
- Custom data identifier w CloudWatch Logs: maks. 10 na politykę, regex do 200 znaków. Jedna polityka ma jedną instrukcję audit.
Null+ForAllValues: dokumentacja IAM zaleca dodać"Null": {"klucz": "false"}, żeby brak klucza w żądaniu nie dawał dopasowania.
- At rest = KMS, in transit = TLS z certyfikatem ACM (publiczny, bez opłaty, auto-odnawianie przy DNS) albo z Private CA (wewnętrzny).
- CloudFront i edge-optimized API → certyfikat w us-east-1; ALB i Regional API → ten sam Region.
- Importowany certyfikat = brak auto-odnowienia. Exportable public cert (od 06.2025) = klucz poza AWS, płatny.
- SSH:
create-key-pairalbossh-keygen+import-key-pair; klucza prywatnego AWS nie trzyma. - WAF: web ACL na CloudFront/ALB/REST API/AppSync/Cognito; rate-based rule per IP; managed rule groups.
- PII w logach → CloudWatch Logs data protection (maskowanie przy ingestii,
logs:Unmask). PII w S3 → Macie. - Multi-tenant: silo / pool / bridge; pool +
dynamodb:LeadingKeys+${aws:PrincipalTag/tenant}+sts:TagSession. - Usługa → usługa: rola IAM + SigV4, Cognito client credentials (M2M), mTLS na custom domain.
Wdrożenia i CI/CD
Jak opisać infrastrukturę kodem (CloudFormation, SAM, CDK), jak zbudować z niej potok (CodeBuild, CodePipeline, CodeArtifact), jak bezpiecznie wypuścić nową wersję (CodeDeploy, canary, blue/green) i jak to wszystko przetestować. Po tej części rozpoznasz, które polecenie, sekcję szablonu albo konfigurację wdrożenia ma na myśli pytanie, i wiesz, co się stanie, gdy wdrożenie się nie uda.
CloudFormation: infrastruktura jako przepis
opisujesz, co ma istnieć, a nie jak to zbudowaćPomyśl o przepisie na ciasto. Nie piszesz „podejdź do szafki, wyjmij mąkę”, tylko „250 g mąki, 3 jajka”. Kucharz sam ustala kolejność. AWS CloudFormation działa tak samo: w szablonie (template, JSON albo YAML) opisujesz zasoby i ich właściwości, a CloudFormation sam ustala kolejność tworzenia, aktualizacji i usuwania. To jest infrastructure as code (IaC).
Z jednego szablonu powstaje stos (stack): grupa zasobów zarządzana jako całość. Tworzysz stos, aktualizujesz go nowym szablonem i usuwasz go razem ze wszystkimi zasobami. Jeśli coś się nie uda, CloudFormation domyślnie wycofuje zmiany (rollback) do ostatniego działającego stanu.
Ręczne klikanie w konsoli jest jak gotowanie bez przepisu: drugi raz nie wyjdzie tak samo. Szablon trzymasz w Git, przeglądasz w code review i wdrażasz identycznie na dev, test i prod.
3.3.43.4.33.2.4
- Jedyna wymagana sekcja szablonu to
Resources. Reszta (Parameters,Mappings,Conditions,Outputs,Transform…) jest opcjonalna. - Change set = podgląd zmian przed aktualizacją stosu („czy ta zmiana coś zastąpi?”). Kolumna
Replacement:True/False/Conditional. - Współdzielenie wartości między stosami:
Outputs+Export→Fn::ImportValue(ta sama Region i konto). Nie usuniesz stosu, którego eksport ktoś importuje. DeletionPolicy: Retainzostawia zasób po usunięciu stosu,Snapshotrobi migawkę (RDS, EBS, ElastiCache, Redshift…). Domyślnie zasób jest usuwany (wyjątek: RDS → Snapshot).- Hasła nie wpisuj do szablonu: dynamic references
{{resolve:secretsmanager:…}}i{{resolve:ssm-secure:…}}, albo parametr zNoEcho: true. - Szablon z zasobami IAM wymaga
CAPABILITY_IAM, a z nazwanymi zasobami IAMCAPABILITY_NAMED_IAM. Szablon z makrami/Transform (np. SAM) przy tworzeniu wprost wymagaCAPABILITY_AUTO_EXPAND. Bez tego dostajeszInsufficientCapabilities. - Kod Lambdy z dysku do szablonu:
aws cloudformation package(wysyła artefakty do S3 i podmienia ścieżki), potemaws cloudformation deploy(tworzy i wykonuje change set). - EC2 ma dać znać, że skończył instalację:
CreationPolicy+cfn-signal. Konfiguracja instancji z metadanych:cfn-init+AWS::CloudFormation::Init.
UPDATE_IN_PROGRESS, UPDATE_COMPLETE_CLEANUP_IN_PROGRESS, UPDATE_ROLLBACK_COMPLETE, UPDATE_FAILED) są prawdziwe; identyfikatory fizyczne zasobów i przyczyna błędu są ilustracyjne. Zmiana TableName tabeli DynamoDB rzeczywiście wymaga zastąpienia (Replacement).Anatomia szablonu
| Sekcja | Co robi | Pułapka egzaminacyjna |
|---|---|---|
AWSTemplateFormatVersion | Wersja formatu, jedyna wartość "2010-09-09" | To nie jest data Twojego szablonu |
Description | Opis tekstowy (max 1 024 bajty) | Musi być zaraz po wersji formatu |
Metadata | Dodatkowe dane, np. AWS::CloudFormation::Init (dla cfn-init), AWS::CloudFormation::Interface (kolejność parametrów w konsoli) | Konfiguracja instancji siedzi w metadanych zasobu |
Parameters | Wartości podawane przy tworzeniu/aktualizacji stosu (max 200) | Typy AWS-specific walidują wartość, zanim ruszy stos |
Mappings | Stała tablica klucz → wartość, czytana przez Fn::FindInMap | Typowo: AMI per Region, rozmiar per środowisko |
Conditions | Warunki (Fn::Equals, Fn::If…) decydujące, czy zasób/output powstanie | Np. „twórz replikę tylko, gdy Env = prod” |
Transform | Makra, np. AWS::Serverless-2016-10-31 (SAM), AWS::Include | Szablon SAM to szablon CloudFormation z Transform |
Resources | Jedyna wymagana sekcja: zasoby (max 500) | Type + Properties + atrybuty (DependsOn, DeletionPolicy…) |
Outputs | Wartości zwracane przez stos (max 200), opcjonalnie Export | Eksport = wartość dla innych stosów w tej samej Region |
AWSTemplateFormatVersion: "2010-09-09"
Description: Orders API
Parameters:
Env: { Type: String, AllowedValues: [dev, prod], Default: dev }
KeyName: { Type: AWS::EC2::KeyPair::KeyName } # konsola pokaże listę istniejących kluczy
AmiId: { Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>,
Default: /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64 }
DbPass: { Type: String, NoEcho: true } # maskowane gwiazdkami
Mappings:
Size: { dev: { Type: t3.micro }, prod: { Type: m7g.large } }
Conditions:
IsProd: !Equals [!Ref Env, prod]
Resources:
Web:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref AmiId
InstanceType: !FindInMap [Size, !Ref Env, Type]
KeyName: !Ref KeyName
Alarm:
Type: AWS::CloudWatch::Alarm
Condition: IsProd # powstaje tylko na prod
Properties: { … }
Outputs:
WebIp:
Value: !GetAtt Web.PublicIp
Export: { Name: !Sub "${AWS::StackName}-WebIp" }
Parametry: typy, które egzamin lubi
- Typy podstawowe:
String,Number,List<Number>,CommaDelimitedList. Ograniczenia:AllowedValues,AllowedPattern,MinLength/MaxLength,MinValue/MaxValue,ConstraintDescription,Default. - AWS-specific parameter types:
AWS::EC2::KeyPair::KeyName,AWS::EC2::VPC::Id,AWS::EC2::Subnet::Id,List<AWS::EC2::SecurityGroup::Id>,AWS::EC2::Image::Id,AWS::Route53::HostedZone::Id… CloudFormation sprawdza, czy taki obiekt istnieje w koncie i Regionie, a konsola pokazuje listę wyboru. Jeśli wartość ma pochodzić z innego konta, użyj zwykłegoString. - SSM parameter types:
AWS::SSM::Parameter::Value<String>,…Value<AWS::EC2::Image::Id>. W parametrze podajesz nazwę parametru Parameter Store, a CloudFormation pobiera aktualną wartość. Klasyka: najnowsze AMI z publicznego parametru/aws/service/ami-amazon-linux-latest/…. - Parametr nie może mieć typu SSM
SecureString. Do sekretów służą dynamic references (niżej). NoEcho: truemaskuje wartość gwiazdkami w konsoli, CLI i API, ale nie maskuje tego, co sam wpiszesz doMetadata,Outputsczy właściwości zasobu.
Funkcje wewnętrzne (intrinsic functions)
| Funkcja (skrót YAML) | Co zwraca | Kiedy |
|---|---|---|
Ref (!Ref) | Wartość parametru albo „główny identyfikator” zasobu (np. nazwa bucketu, ID instancji) | Najczęstsze odwołanie |
Fn::GetAtt (!GetAtt X.Arn) | Konkretny atrybut zasobu: Arn, DomainName, PublicIp… | Potrzebujesz ARN, a Ref daje nazwę |
Fn::Sub | Podstawia ${Param}, ${Res.Attr}, ${AWS::Region} w tekście | Budowanie ARN-ów i nazw |
Fn::Join | Skleja listę z separatorem | !Join [":", [a, b]] |
Fn::FindInMap | Wartość z Mappings (mapa, klucz 1, klucz 2) | AMI per Region, rozmiar per środowisko |
Fn::ImportValue | Wartość wyeksportowana przez inny stos | Cross-stack reference (ta sama Region i konto) |
Fn::If, Fn::Equals, Fn::And, Fn::Or, Fn::Not | Logika warunków | Sekcja Conditions, wartości warunkowe |
Fn::Select / Fn::Split | Element listy po indeksie / dzielenie tekstu na listę | !Select [0, !GetAZs ""] |
Fn::GetAZs | Lista AZ w Regionie | Podsieci w kolejnych AZ |
Fn::Base64 | Koduje tekst w Base64 | UserData instancji EC2 |
Fn::Cidr | Lista bloków CIDR wyciętych z większego bloku | Podsieci VPC |
Fn::GetStackOutput | Output innego stosu bez eksportu, także z innego konta/Regionu | Nowość; słaba referencja |
Pseudo parameters to wartości, które CloudFormation zna zawsze, bez deklarowania: AWS::AccountId, AWS::Region, AWS::StackName, AWS::StackId, AWS::Partition, AWS::URLSuffix, AWS::NotificationARNs i AWS::NoValue (z Fn::If usuwa właściwość, jakby jej nie było).
!Ref MyBucket zwraca nazwę bucketu, !GetAtt MyBucket.Arn jego ARN. Dla funkcji Lambda Ref daje nazwę, dla kolejki SQS URL, a dla instancji EC2 ID instancji. Jeśli pytanie chce ARN do polityki IAM, prawie zawsze odpowiedzią jest GetAtt … .Arn albo Fn::Sub z arn:${AWS::Partition}:….
Aktualizacje: change set, zachowania i rollback
Zanim wymienisz silnik w jadącym samochodzie, chcesz wiedzieć, czy trzeba będzie stanąć. Change set to ten podgląd: tworzysz go z nowego szablonu, czytasz listę zmian (Add, Modify, Remove + Replacement) i dopiero potem go wykonujesz (execute) albo kasujesz. Sam change set niczego nie zmienia.
| Zachowanie przy aktualizacji | Co się dzieje | Fizyczne ID |
|---|---|---|
| Update with No Interruption | Zmiana w miejscu, zasób działa dalej | Bez zmian |
| Updates with Some Interruption | Zmiana w miejscu z przerwą (np. restart instancji EC2 przy zmianie typu) | Bez zmian |
| Replacement | Nowy zasób powstaje, referencje są przepinane, stary jest usuwany w fazie cleanup | Nowe (dane w starym zasobie znikają) |
Gdy aktualizacja się nie uda, stos przechodzi w UPDATE_ROLLBACK_IN_PROGRESS i wraca do poprzedniej konfiguracji (UPDATE_ROLLBACK_COMPLETE). Gdy nie uda się utworzenie stosu, kończy w ROLLBACK_COMPLETE, a taki stos możesz już tylko usunąć i utworzyć od nowa.
- Rollback triggers: do 5 alarmów CloudWatch (zwykłych albo composite) i czas monitorowania 0–180 min (domyślnie 0). Jeśli alarm przejdzie w
ALARMw trakcie operacji lub w czasie monitorowania, CloudFormation wycofa zmiany. StanINSUFFICIENT_DATAdomyślnie nie wyzwala rollbacku. - Stack failure options: „Preserve successfully provisioned resources” (CLI:
--disable-rollbackalbo--on-failure DO_NOTHINGprzycreate-stack). Udane zasoby zostają, nieudane czekają na poprawkę i ponowienie. Przydaje się do debugowania długich stosów. UPDATE_ROLLBACK_FAILED: rollback sam się nie udał (np. ktoś ręcznie usunął zasób). Stosu nie zaktualizujesz. Naprawiasz przyczynę i wołasz Continue update rollback (continue-update-rollback), ewentualnie pomijając problematyczne zasoby (--resources-to-skip).- Aktualizację w toku można przerwać:
cancel-update-stack(stos wraca do poprzedniego stanu).
Atrybuty zasobów
| Atrybut | Co robi | Kiedy |
|---|---|---|
DependsOn | Wymusza kolejność tworzenia (i odwrotną przy usuwaniu) | Zależność, której CloudFormation nie widzi z Ref/GetAtt (np. EC2 potrzebuje bramy internetowej z attachmentem) |
DeletionPolicy | Delete (domyślnie), Retain, RetainExceptOnCreate, Snapshot | Bucket/tabela ma przeżyć usunięcie stosu. Domyślnie Snapshot dla AWS::RDS::DBCluster i AWS::RDS::DBInstance bez DBClusterIdentifier |
UpdateReplacePolicy | To samo co wyżej, ale dla starego zasobu przy Replacement | Zmiana wymusza zastąpienie bazy, a chcesz zachować migawkę starej |
CreationPolicy | Stos czeka na Count sygnałów w czasie Timeout (ISO 8601, domyślnie PT5M, max 12 h) | EC2/Auto Scaling ma zgłosić „aplikacja gotowa” przez cfn-signal |
UpdatePolicy | Jak aktualizować Auto Scaling group (rolling, replacing), aliasy Lambda (CodeDeploy) | Stopniowa wymiana instancji w ASG |
Condition | Zasób powstaje tylko, gdy warunek jest prawdziwy | Zasoby tylko dla prod |
Snapshot działa tylko dla zasobów, które mają migawki: m.in. AWS::EC2::Volume, AWS::RDS::DBInstance, AWS::RDS::DBCluster, AWS::ElastiCache::CacheCluster, AWS::ElastiCache::ReplicationGroup, AWS::Redshift::Cluster, AWS::Neptune::DBCluster, AWS::DocDB::DBCluster. Dla S3 czy DynamoDB wybierasz Retain. Migawki zostają po usunięciu stosu (i kosztują).
Bootstrap EC2: cfn-init, cfn-signal, cfn-hup, WaitCondition
Instancja EC2 „istnieje” dla CloudFormation, gdy tylko wystartuje, a nie gdy aplikacja działa. Żeby stos czekał na prawdziwą gotowość, używasz helper scripts (pakiet aws-cfn-bootstrap, preinstalowany na Amazon Linux):
cfn-initczytaMetadata → AWS::CloudFormation::Initzasobu i wykonuje ją:packages,groups,users,sources,files,commands,services(w tej kolejności), opcjonalnie wconfigSets.cfn-signalwysyła sukces/porażkę doCreationPolicylubWaitCondition(wymaga uprawnieniacloudformation:SignalResource; dane sygnału max 4 096 bajtów). Brak sygnału przed timeoutem =CREATE_FAILEDi rollback.cfn-hupto demon, który cointervalminut (domyślnie 15) sprawdza zmiany metadanych i uruchamia hooki, np. ponownycfn-initpo aktualizacji stosu.cfn-get-metadatapobiera metadane zasobu.AWS::CloudFormation::WaitCondition+WaitConditionHandleto starszy mechanizm (np. czekanie na zasób spoza CloudFormation). Dla EC2 i Auto Scaling AWS zalecaCreationPolicy.
Web:
Type: AWS::EC2::Instance
CreationPolicy: { ResourceSignal: { Count: 1, Timeout: PT15M } }
Metadata:
AWS::CloudFormation::Init:
config:
packages: { yum: { httpd: [] } }
services: { systemd: { httpd: { enabled: true, ensureRunning: true } } }
Properties:
UserData: !Base64
Fn::Sub: |
#!/bin/bash
/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource Web --region ${AWS::Region}
/opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource Web --region ${AWS::Region}
Sekrety: dynamic references
Zamiast wpisywać wartość do szablonu, wpisujesz odnośnik, który CloudFormation rozwiązuje w chwili operacji na stosie:
{{resolve:ssm:/app/db/host:3}}– zwykły parametr Parameter Store (opcjonalnie wersja).{{resolve:ssm-secure:/app/db/pass:2}}–SecureString; działa tylko we właściwościach, które to wspierają (np. hasło RDS, hasło użytkownika IAM).{{resolve:secretsmanager:prod/db:SecretString:password}}– sekret z Secrets Manager (format:secret-id:SecretString:json-key:version-stage:version-id).
Limity i wyjątki: max 60 dynamic references w szablonie. Nie działają w AWS::CloudFormation::Init ani w UserData EC2, a bezpieczne wartości (ssm-secure, Secrets Manager) nie działają w custom resources. Drift detection ich nie sprawdza. Przy Transform (SAM) referencje rozwiązuje się dopiero przy wykonaniu change setu. Szczegóły Secrets Manager vs Parameter Store: rozdział o sekretach.
Wiele stosów: nested stacks, eksporty, StackSets
| Mechanizm | Co robi | Kiedy |
|---|---|---|
Nested stacks (AWS::CloudFormation::Stack + TemplateURL w S3) | Stos-dziecko jako zasób rodzica; aktualizujesz i usuwasz przez root stack | Wielokrotnie używany komponent (np. standardowy ALB), który ma żyć razem z rodzicem |
Cross-stack reference (Export → Fn::ImportValue) | Stos A publikuje wartość, stosy B, C ją importują | Niezależne cykle życia (sieć zespołu A, aplikacje zespołów B, C). Nazwa eksportu unikalna w Regionie i koncie |
Fn::GetStackOutput | Czyta output innego stosu bez eksportu, także cross-account/cross-Region | Słaba referencja: nic nie blokuje zmiany źródła |
| StackSets | Jeden szablon wdrażany do wielu kont i Regionów z konta administratora | Ta sama rola/konfiguracja w 40 kontach organizacji. Uprawnienia self-managed albo service-managed (AWS Organizations, auto-deploy do nowych kont) |
Twarda zasada eksportów: dopóki ktoś importuje wartość, nie usuniesz stosu eksportującego i nie zmienisz eksportowanej wartości. Najpierw usuń importy (sprawdzisz je przez list-imports).
Ochrona i porządek: stack policy, termination protection, drift
- Stack policy: dokument JSON (
Effect,Actionnp.Update:Replace,Update:Delete,Principal: "*",Resource,Condition) chroniący zasoby przed aktualizacją. Po ustawieniu polityki wszystko jest chronione, dopóki jawnie nie zezwolisz (Allow). Jedna polityka na stos; można ją tymczasowo nadpisać przy aktualizacji. - Termination protection: blokuje usunięcie stosu. Domyślnie wyłączona. Dla nested stacks włączasz ją tylko na root stack.
- Drift detection: porównuje rzeczywistą konfigurację z szablonem. Statusy zasobów:
IN_SYNC,MODIFIED,DELETED,NOT_CHECKED. Drift niczego nie naprawia, tylko raportuje. - Uprawnienia: rola usługi CloudFormation (
--role-arn) pozwala użytkownikowi wdrażać zasoby, do których sam nie ma uprawnień (wystarczy muiam:PassRolena tę rolę).
Custom resources
Gdy CloudFormation czegoś nie umie (wyczyścić bucket przed usunięciem, zawołać zewnętrzne API, pobrać wartość z innego systemu), dopisujesz własny zasób: Type: Custom::Nazwa (albo AWS::CloudFormation::CustomResource) z jedyną wymaganą właściwością ServiceToken = ARN funkcji Lambda lub tematu SNS w tej samej Regionie. CloudFormation wysyła zdarzenie z RequestType (Create, Update, Delete), ResourceProperties i ResponseURL (pre-signed URL S3). Funkcja musi wysłać tam SUCCESS albo FAILED (max 4 096 bajtów danych). Brak odpowiedzi = stos czeka do timeoutu (domyślnie 3 600 s, czyli 1 h) i pada.
Polecenia i narzędzia
# 1. spakuj lokalny kod (Lambda, nested templates) do S3 i podmień ścieżki
aws cloudformation package --template-file template.yaml \
--s3-bucket my-artifacts --output-template-file packaged.yaml
# 2. utwórz i wykonaj change set (stos powstanie albo się zaktualizuje)
aws cloudformation deploy --template-file packaged.yaml --stack-name orders \
--parameter-overrides Env=prod --capabilities CAPABILITY_NAMED_IAM
# --no-execute-changeset → tylko utwórz change set do przejrzenia
- Szablon wprost w żądaniu (
--template-body): max 51 200 bajtów. Większy szablon musi leżeć w S3 (--template-url, max 1 MB). URL musi zaczynać się odhttps://; adresy S3 static website nie działają.aws cloudformation deploydla szablonu większego niż 51 200 bajtów wymaga--s3-bucket. packageobsługuje m.in.CodewAWS::Lambda::Function,CodeUriwAWS::Serverless::Function,TemplateURLwAWS::CloudFormation::Stack. Folder pakuje do .zip.- cfn-lint sprawdza szablon lokalnie (schematy zasobów, błędne właściwości, złe referencje).
aws cloudformation validate-templatesprawdza tylko składnię. Żadne nie gwarantuje, że wdrożenie się uda. - AWS Infrastructure Composer (do października 2024 „AWS Application Composer”): wizualny edytor „przeciągnij i upuść”, który generuje szablon CloudFormation/SAM. Dokumentacja zapowiada, że samodzielna konsola Composera zniknie 7 grudnia 2026; edytor wizualny zostaje wbudowany w konsole CloudFormation i innych usług.
- „Użyj
DependsOn, żeby przekazać wartość” –DependsOntylko porządkuje kolejność. Wartość przekazujesz przezRef/GetAtt, które same tworzą zależność. - „Nested stacks do współdzielenia VPC między zespołami” – kusi, bo „łączy stosy”. Ale niezależne cykle życia to eksporty i
Fn::ImportValue. Nested stacks to komponent jednego rodzica. - „
Fn::ImportValuez innej Regionu” – eksporty działają tylko w tym samym koncie i Regionie. Na wiele kont/Regionów: StackSets (wdrożenie) alboFn::GetStackOutput(odczyt). - „Stack policy chroni przed usunięciem stosu” – nie. Stack policy chroni zasoby przed aktualizacją; przed usunięciem stosu chroni termination protection, a przed utratą zasobu
DeletionPolicy: Retain. - „Hasło jako parametr String z Default” – trafi do szablonu i historii. Poprawnie:
{{resolve:secretsmanager:…}}, ewentualnieNoEchobez wartości domyślnej. - „Parametr typu SecureString” – nie istnieje.
AWS::SSM::Parameter::Value<String>działa dlaString/StringList, a sekret to{{resolve:ssm-secure:…}}. - „Wykonaj
update-stack, żeby zobaczyć, co się zmieni” – to od razu aktualizuje. Podgląd daje change set (albodeploy --no-execute-changeset). - „Stos w
ROLLBACK_COMPLETEzaktualizuj poprawionym szablonem” – po nieudanym utworzeniu stos można tylko usunąć. - „
WaitConditiondla EC2” – działa, ale zalecane jestCreationPolicy+cfn-signal.
Zespół sieciowy utrzymuje stos z VPC i podsieciami. Trzy zespoły aplikacyjne mają w swoich stosach używać ID tych podsieci, a ich stosy mają własny cykl życia. Jak to zrobić z najmniejszym nakładem?
osobne stosy · własny cykl życia · ta sama Region
Odpowiedź
Outputs z Export w stosie sieciowym i Fn::ImportValue w stosach aplikacji. To dokładnie cross-stack reference.
Dlaczego nie: nested stacks wiążą cykl życia z jednym rodzicem; parametry wpisywane ręcznie łatwo pomylić; StackSets służą do wdrażania tego samego szablonu w wielu kontach.
Przed aktualizacją produkcyjnego stosu z bazą RDS chcesz wiedzieć, czy zmiana nie spowoduje utworzenia nowej instancji bazy. Co robisz?
przed aktualizacją · podgląd · czy zastąpi
Odpowiedź
Tworzysz change set i sprawdzasz pole Replacement dla bazy. Dla ochrony możesz dodać UpdateReplacePolicy: Snapshot oraz stack policy zabraniającą Update:Replace.
Dlaczego nie: drift detection porównuje stan z obecnym szablonem, nie z nowym; validate-template sprawdza tylko składnię.
Po usunięciu stosu bucket S3 z logami audytowymi ma zostać. Co dodajesz do szablonu?
usunięcie stosu · zasób ma przetrwać
Odpowiedź
DeletionPolicy: Retain na zasobie bucketu.
Dlaczego nie: Snapshot nie jest wspierany dla S3; termination protection blokuje usunięcie całego stosu, a nie pozwala go usunąć z zachowaniem bucketu; stack policy dotyczy aktualizacji.
Stos tworzy instancje EC2, które instalują aplikację skryptem UserData trwającym ok. 10 minut. Stos zgłasza CREATE_COMPLETE, zanim aplikacja działa, a kolejne zasoby (rekord DNS) wskazują na niegotowy serwer. Jak to naprawić?
czekaj na gotowość aplikacji · EC2 · sygnał
Odpowiedź
CreationPolicy z ResourceSignal (np. Timeout: PT15M) i cfn-signal na końcu UserData. Zależne zasoby poczekają na sygnał.
Dlaczego nie: DependsOn czeka tylko na utworzenie instancji, nie na aplikację; domyślny timeout PT5M byłby za krótki.
Wdrożenie szablonu z rolą IAM o nazwie orders-lambda-role kończy się błędem InsufficientCapabilities. Co dodać do polecenia?
nazwany zasób IAM · capabilities
Odpowiedź
--capabilities CAPABILITY_NAMED_IAM. Nazwane zasoby IAM wymagają właśnie tej zgody.
Dlaczego nie: CAPABILITY_IAM wystarcza tylko dla zasobów IAM bez własnych nazw; CAPABILITY_AUTO_EXPAND dotyczy makr.
Szablon potrzebuje własnej logiki: przy usuwaniu stosu ma opróżnić bucket S3, bo inaczej usunięcie się nie powiedzie. Jak?
logika niedostępna w CloudFormation · przy Delete
Odpowiedź
Custom resource opartym o Lambdę (ServiceToken = ARN funkcji), która przy RequestType: Delete kasuje obiekty i odpowiada SUCCESS na ResponseURL.
Dlaczego nie: DeletionPolicy: Delete nie usuwa niepustego bucketu; cfn-hup działa na instancji EC2.
🔬 Głębiej: rzadziej pytane szczegóły
- Change set ma też wariant dla nested stacks (obejmuje całą hierarchię) i „drift-aware change sets”.
RetainExceptOnCreate: jakRetain, ale jeśli rollback dotyczy operacji, która zasób dopiero utworzyła, zasób zostanie usunięty (nie zostawiasz śmieci po nieudanym tworzeniu).CreationPolicydla Auto Scaling group ma teżAutoScalingCreationPolicy.MinSuccessfulInstancesPercent.- Nowsze funkcje:
Fn::ForEach(pętle, wymaga TransformAWS::LanguageExtensions),Fn::Length,Fn::ToJsonString; CloudFormation Hooks sprawdzają zasoby przed utworzeniem (max 100 hooków na konto i Region); modules i resource import (włączenie istniejącego zasobu do stosu). - Limity: 2 000 stosów na konto i Region (podnoszalny), nazwa stosu 128 znaków, wartość parametru 4 096 bajtów, 1 000 stack sets na konto administratora.
- Stack policy przy aktualizacji można tymczasowo nadpisać (
--stack-policy-during-update-body); po aktualizacji wraca oryginalna.
W starszych testach próbnych możesz spotkać limity „200 zasobów, 60 parametrów, 60 outputów w szablonie”. Aktualna dokumentacja podaje 500 zasobów, 200 parametrów, 200 outputów i 200 mappings. Jeśli pytanie opiera się na starej liczbie, idea odpowiedzi zwykle się nie zmienia: duży szablon dzielisz na nested stacks.
- Szablon = przepis; stos = to, co z niego powstało. Wymagana jest tylko sekcja
Resources. Ref= nazwa/ID,GetAtt= atrybut (ARN),Sub= tekst z podstawieniami,FindInMap= tablica,ImportValue= eksport innego stosu.- Change set pokazuje, co się zmieni i czy coś zostanie zastąpione. Błąd aktualizacji = automatyczny rollback.
DeletionPolicy(Retain/Snapshot/Delete) iUpdateReplacePolicychronią dane; stack policy chroni przed aktualizacją, termination protection przed usunięciem stosu.- EC2 gotowa:
CreationPolicy+cfn-signal; konfiguracja:cfn-init; zmiany na żywo:cfn-hup. - Sekrety przez
{{resolve:secretsmanager|ssm-secure:…}}. IAM w szablonie wymagaCAPABILITY_(NAMED_)IAM. package→ S3,deploy→ change set. Szablon > 51 200 B musi iść z S3 (max 1 MB).
SAM i CDK: krótszy przepis, ten sam kucharz
oba kończą jako szablon CloudFormationSzablon CloudFormation dla jednej funkcji Lambda z API i rolą to kilkadziesiąt linii. To jak pisanie przepisu, w którym za każdym razem tłumaczysz, jak rozbić jajko. AWS SAM (Serverless Application Model) i AWS CDK (Cloud Development Kit) to dwa skróty: SAM to krótszy YAML dla aplikacji serverless, CDK to prawdziwy język programowania (TypeScript, Python, Java, C#, Go). Oba na końcu produkują zwykły szablon CloudFormation i wdrażają go jako stos.
SAM rozpoznasz po linii Transform: AWS::Serverless-2016-10-31 i typach AWS::Serverless::*. CDK rozpoznasz po cdk synth, cdk deploy i „constructs”. Wybór na egzaminie jest prosty: serverless + YAML + testy lokalne → SAM; logika, pętle, abstrakcje w kodzie → CDK.
1.1.73.2.43.3.43.4.33.4.5
- Szablon SAM musi mieć
Transform: AWS::Serverless-2016-10-31. CloudFormation rozwija go do zwykłych zasobów (funkcja + rola IAM + uprawnienia + API…). - Lokalne testy:
sam local invoke(jedno wywołanie z plikiem zdarzenia),sam local start-api(lokalny API Gateway, port 3000),sam local start-lambda(lokalny endpoint Lambda, port 3001),sam local generate-event(przykładowe zdarzenia S3, SQS, API…). Wszystko w kontenerach Docker. - Cykl:
sam build→sam deploy --guided(pierwszy raz; zapisuje ustawienia dosamconfig.toml) → potem samosam deploy. Szybka pętla w dev:sam sync --watch(nie na produkcję). - Bezpieczne wdrożenie Lambdy w SAM:
AutoPublishAlias+DeploymentPreference(Canary10Percent5Minutes,Linear10PercentEvery1Minute,AllAtOnce…) +Alarms+ hookiPreTraffic/PostTraffic. Pod spodem działa CodeDeploy, a alarm cofa ruch automatycznie. - Uprawnienia w SAM: policy templates (
DynamoDBCrudPolicy,S3ReadPolicy,SQSPollerPolicy…) zamiast ręcznego JSON-a. - CDK: L1 =
Cfn*(1:1 z CloudFormation), L2 = wygodne klasy z domyślnymi ustawieniami i metodamigrant*, L3 = patterns (kilka zasobów naraz). Przed pierwszymcdk deployw koncie/Regionie:cdk bootstrap(stosCDKToolkit).
💻 Kod + template.yaml
📦 .aws-sam/build
🐳 Docker (lokalnie)
☁️ AWS (S3 + CloudFormation)
.aws-sam/build, porty 3000/3001 i plik samconfig.toml są prawdziwe; nazwy stosu i bucketu oraz komunikat o braku Dockera są ilustracyjne.Szablon SAM
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31 # to robi z YAML-a szablon SAM
Globals:
Function: { Runtime: python3.13, Timeout: 10, MemorySize: 256, Tracing: Active }
Resources:
OrdersFn:
Type: AWS::Serverless::Function
Properties:
CodeUri: src/
Handler: app.handler
Policies:
- DynamoDBCrudPolicy: { TableName: !Ref OrdersTable } # policy template
Events:
GetOrder: { Type: Api, Properties: { Path: /orders/{id}, Method: get } }
AutoPublishAlias: live # nowa wersja + alias "live" przy każdej zmianie kodu
DeploymentPreference:
Type: Canary10Percent5Minutes # 10% ruchu, po 5 min reszta
Alarms: [!Ref ErrorsAlarm] # alarm = automatyczny rollback
Hooks: { PreTraffic: !Ref PreTrafficFn, PostTraffic: !Ref PostTrafficFn }
OrdersTable:
Type: AWS::Serverless::SimpleTable # tabela DynamoDB z kluczem głównym, bez sort key
| Typ SAM | Co tworzy | Kiedy |
|---|---|---|
AWS::Serverless::Function | Lambda + (gdy brak Role) rola IAM + uprawnienia/źródła zdarzeń z Events; z AutoPublishAlias także Version i Alias | Każda funkcja |
AWS::Serverless::Api | API Gateway REST API (stages, auth, OpenAPI) | Pełne funkcje REST API |
AWS::Serverless::HttpApi | API Gateway HTTP API | Tańsze, prostsze API |
AWS::Serverless::SimpleTable | Tabela DynamoDB z jednym kluczem głównym | Prosta tabela; gdy potrzebujesz sort key/GSI, użyj AWS::DynamoDB::Table |
AWS::Serverless::LayerVersion | Lambda layer | Wspólne biblioteki |
AWS::Serverless::StateMachine | Step Functions | Orkiestracja |
AWS::Serverless::Application | Zagnieżdżona aplikacja (z AWS Serverless Application Repository albo lokalnego szablonu) | Gotowy komponent |
AWS::Serverless::Connector | Uprawnienia między dwoma zasobami (Source → Destination, Read/Write) | „Funkcja ma pisać do tabeli” bez pisania polityki |
AWS::Serverless::GraphQLApi, WebSocketApi | GraphQLApi = AppSync GraphQL API; WebSocketApi = API Gateway WebSocket API (nie AppSync) | Nowsze typy |
Globals ustawia wspólne wartości dla Function, Api, HttpApi, SimpleTable, StateMachine (i kilku nowszych typów). Zasób może je nadpisać: wartości proste (string, liczba) są zastępowane, mapy (np. zmienne środowiskowe) scalane, a listy (np. Layers) dokładane.
Events funkcji to m.in. Api, HttpApi, S3, SQS, SNS, DynamoDB, Kinesis, Schedule, EventBridgeRule, CloudWatchLogs, Cognito, MSK, MQ. SAM sam dopisze uprawnienie i mapowanie źródła (event source mapping).
Policy templates (wybrane): DynamoDBCrudPolicy, DynamoDBReadPolicy, S3ReadPolicy, S3CrudPolicy, SQSPollerPolicy, SQSSendMessagePolicy, SNSPublishMessagePolicy, LambdaInvokePolicy, StepFunctionsExecutionPolicy, KMSDecryptPolicy, SSMParameterReadPolicy, AWSSecretsManagerGetSecretValuePolicy. Każdy dostaje parametr (nazwę tabeli, bucketu, kolejki) i daje uprawnienia tylko do tego zasobu (least privilege). Policies przyjmuje też nazwy/ARN polityk zarządzanych i zwykłe dokumenty IAM.
SAM CLI: polecenia
| Polecenie | Co robi | Kiedy |
|---|---|---|
sam init | Nowy projekt z szablonu startowego | Start |
sam build | Instaluje zależności i buduje artefakty do .aws-sam/build | Przed local i deploy |
sam validate (--lint) | Sprawdza szablon (z --lint przez cfn-lint) | CI, przed wdrożeniem |
sam local invoke -e event.json | Jedno wywołanie funkcji w kontenerze Docker | Test jednostkowy/debug funkcji |
sam local start-api | Lokalny API Gateway na http://127.0.0.1:3000 | Testy przez HTTP (curl, Postman) |
sam local start-lambda | Lokalny endpoint Lambda (port 3001), wołany SDK/CLI z --endpoint-url | Testy automatyczne wywołujące „Lambdę” |
sam local generate-event s3 put | Przykładowe zdarzenie danej usługi (S3, SQS, SNS, API Gateway, DynamoDB…) | Plik do -e |
sam package | Wysyła artefakty do S3, zwraca szablon ze ścieżkami S3 (jak aws cloudformation package) | Rzadko ręcznie; deploy robi to sam |
sam deploy --guided | Pyta o stos, Region, capabilities…, zapisuje odpowiedzi w samconfig.toml, tworzy i wykonuje change set | Pierwsze wdrożenie |
sam deploy --config-env prod | Bierze parametry ze środowiska [prod] w samconfig.toml | Wiele środowisk z jednego projektu |
sam sync --watch | Obserwuje pliki i synchronizuje zmiany; zmiany kodu (--code) idą wprost przez API usług, z pominięciem CloudFormation | Szybka pętla w dev; na prod: sam deploy lub pipeline |
sam logs / sam traces | Logi CloudWatch / ślady X-Ray funkcji z terminala | Debug po wdrożeniu |
sam remote invoke | Wywołuje funkcję wdrożoną w AWS | Testy w chmurze |
sam pipeline init --bootstrap | Generuje startowy pipeline CI/CD (CodePipeline, Jenkins, GitLab CI/CD, GitHub Actions, Bitbucket) i zasoby dla etapów | „Szybko zbuduj pipeline dla aplikacji SAM” |
sam delete | Usuwa stos i artefakty | Sprzątanie |
# samconfig.toml (w katalogu głównym projektu, format TOML)
version = 0.1
[default.deploy.parameters]
stack_name = "orders-dev"
resolve_s3 = true
capabilities = "CAPABILITY_IAM"
[prod.deploy.parameters]
stack_name = "orders-prod"
parameter_overrides = "Env=prod"
# sam deploy --config-env prod
Stopniowe wdrażanie Lambdy w SAM
Nowy kucharz najpierw gotuje dla jednego stolika na dziesięć, a szef sali patrzy, czy nikt nie odsyła talerzy. Tak działa canary. W SAM włączasz to trzema właściwościami funkcji:
AutoPublishAlias: live– przy każdej zmianie kodu SAM publikuje nową wersję funkcji i przepina na nią aliaslive. Klienci wołają alias, nie$LATEST.DeploymentPreference.Type– jak przesuwać ruch na nową wersję:Canary10Percent5Minutes/10Minutes/15Minutes/30Minutes(10%, potem reszta),Linear10PercentEvery1Minute/2Minutes/3Minutes/10Minutes(po 10% co N minut),AllAtOnce.AlarmsiHooks– alarmy CloudWatch w stanieALARMalbo nieudany hookPreTraffic/PostTrafficpowodują, że CodeDeploy cofa ruch na starą wersję. Hook to funkcja Lambda, która musi odpowiedzieć CodeDeploy wywołaniemPutLifecycleEventHookExecutionStatus(Succeeded/Failed).
Z DeploymentPreference SAM dopisuje do stosu AWS::CodeDeploy::Application, DeploymentGroup dla funkcji i rolę CodeDeployServiceRole. Mechanika canary/linear i hooków: CodeDeploy. Wersje i aliasy: konfiguracja Lambdy.
AWS CDK
CDK to klocki LEGO. Pojedynczy klocek to construct; z klocków budujesz stack (jeden stos CloudFormation), a stosy składasz w app. Program w TypeScript/Pythonie uruchamiasz poleceniem cdk synth, które produkuje szablony CloudFormation do katalogu cdk.out (cloud assembly). cdk deploy wdraża je jako stosy.
| Poziom | Co to jest | Przykład |
|---|---|---|
| L1 (CFN resources) | Klasa 1:1 z typem CloudFormation, nazwa zaczyna się od Cfn, zero domyślnych wartości | s3.CfnBucket – pełna kontrola, nowa właściwość CFN od razu dostępna |
| L2 (curated) | Wygodna klasa z rozsądnymi domyślnymi ustawieniami i metodami pomocniczymi (grantRead, addEventNotification) | s3.Bucket, lambda.Function |
| L3 (patterns) | Gotowa architektura z kilku zasobów | ecs_patterns.ApplicationLoadBalancedFargateService |
const table = new dynamodb.Table(this, 'Orders', {
partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING } });
const fn = new lambda.Function(this, 'OrdersFn', { runtime: lambda.Runtime.NODEJS_22_X,
handler: 'index.handler', code: lambda.Code.fromAsset('src') });
table.grantReadWriteData(fn); // CDK sam dopisze minimalną politykę IAM do roli funkcji
| Polecenie CDK | Co robi |
|---|---|
cdk init app --language typescript | Nowy projekt |
cdk bootstrap | Raz na środowisko (konto + Region): stos CDKToolkit z bucketem S3 na assety, repozytorium ECR na obrazy i rolami IAM do wdrożeń |
cdk synth | Generuje szablony CloudFormation (cdk.out) |
cdk diff | Różnica między kodem a wdrożonym stosem (jak change set) |
cdk deploy | Synth + wdrożenie przez CloudFormation (pyta o zgodę na zmiany IAM/security) |
cdk watch / cdk deploy --hotswap | Szybkie wdrożenia w dev, gdzie się da z pominięciem CloudFormation |
cdk destroy | Usuwa stos |
cdk context, cdk doctor, cdk import, cdk drift | Kontekst (cache w cdk.context.json), diagnostyka, import zasobów, drift |
Testy CDK (moduł aws-cdk-lib/assertions): fine-grained assertions – const t = Template.fromStack(stack); t.hasResourceProperties('AWS::Lambda::Function', {…}); t.resourceCountIs('AWS::SNS::Subscription', 1); – oraz snapshot tests, które porównują cały zsyntetyzowany szablon z zapisanym wzorcem (np. toMatchSnapshot() w Jest). Snapshot wykrywa każdą zmianę, assertion sprawdza jedną rzecz.
Context: wartości klucz–wartość z cdk.json, cdk.context.json albo --context. Wyniki zapytań do konta (np. lista AZ, AMI, VPC lookup) CDK zapisuje w cdk.context.json, żeby kolejne synth były powtarzalne; ten plik commitujesz.
sam local i gotowe canary. CDK: dużo powtarzalnej infrastruktury, chcesz pętli, klas i testów jednostkowych infrastruktury. Czysty CloudFormation: proste, deklaratywne szablony, StackSets, pełna kontrola. Możesz też łączyć: sam local potrafi testować funkcje z aplikacji CDK (po cdk synth).sam sync od sam deploy?sam deploy zawsze idzie przez change set CloudFormation. sam sync dla zmian samego kodu woła API usług bezpośrednio (szybko, ale stos chwilowo nie odpowiada szablonowi), dlatego dokumentacja zaleca go tylko w środowiskach deweloperskich.- „Brak linii Transform, a typ
AWS::Serverless::Function” – CloudFormation nie zna tego typu bezTransform: AWS::Serverless-2016-10-31. - „
sam local invoketestuje funkcję w AWS” – nie, w lokalnym kontenerze Docker. Kod w kontenerze może za to rozmawiać z prawdziwymi zasobami w chmurze (np. tabelą DynamoDB podaną przez--env-vars), a lokalny test nie sprawdza uprawnień IAM między zasobami w chmurze. To trzeba przetestować po wdrożeniu. - „
sam sync --watchna produkcji” – kusi szybkością, ale omija CloudFormation dla zmian kodu. Na prod:sam deployalbo pipeline. - „Canary bez
AutoPublishAlias” –DeploymentPreferenceprzesuwa ruch między wersjami aliasu; bez aliasu nie ma czego przesuwać. - „Rollback canary wymaga ręcznej akcji” – nie, jeśli podasz
Alarms: CodeDeploy sam cofnie ruch na starą wersję. - „
cdk deploypada z błędem o brakującym bucketcie/roli CDK” – środowisko nie jest zbootstrapowane:cdk bootstrap aws://KONTO/REGION. - „L1 to najwygodniejszy poziom” – odwrotnie: L1 to surowe
Cfn*; wygodne domyślne ustawienia igrant*daje L2, gotowe architektury L3.
Programista chce przetestować na laptopie funkcję Lambda wywoływaną przez upload do S3, zanim cokolwiek wdroży. Co zrobić najmniejszym kosztem?
lokalnie · zdarzenie S3 · bez wdrożenia
Odpowiedź
sam local generate-event s3 put > event.json, potem sam local invoke OrdersFn -e event.json.
Dlaczego nie: konsola Lambda wymaga wdrożonej funkcji; start-api emuluje API Gateway, nie S3.
Nowa wersja funkcji ma dostać 10% ruchu, po 10 minutach całość, a przy wzroście błędów ruch ma wrócić automatycznie. Aplikacja jest w SAM. Co konfigurujesz?
10% · potem całość · automatyczny powrót
Odpowiedź
AutoPublishAlias + DeploymentPreference: Type: Canary10Percent10Minutes + Alarms (alarm na Errors aliasu).
Dlaczego nie: Linear10PercentEvery10Minutes przesuwa po 10% co 10 minut (100 minut w sumie); wagi aliasu ustawiane ręcznie nie mają automatycznego rollbacku.
Aplikacja SAM ma środowiska dev, test i prod z różnymi nazwami stosów i parametrami. Jak wdrażać bez wpisywania flag za każdym razem?
wiele środowisk · SAM CLI · parametry zapisane
Odpowiedź
Sekcje [dev], [test], [prod] w samconfig.toml i sam deploy --config-env prod.
Dlaczego nie: osobne szablony dla każdego środowiska powielają kod; Globals nie zależą od środowiska.
Zespół pisze infrastrukturę w CDK (TypeScript) i chce w CI sprawdzać, że funkcja Lambda ma zawsze Timeout 30 s. Jak?
test infrastruktury · konkretna właściwość
Odpowiedź
Fine-grained assertion: Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Function', { Timeout: 30 }).
Dlaczego nie: snapshot test wyłapie każdą zmianę, nie tylko timeout; cdk diff porównuje z wdrożonym stosem, nie jest testem.
Funkcja w SAM ma tylko czytać obiekty z jednego bucketu. Jak nadać uprawnienia z najmniejszym wysiłkiem i zgodnie z least privilege?
SAM · jeden bucket · tylko odczyt
Odpowiedź
Policies: - S3ReadPolicy: { BucketName: !Ref Bucket } (albo AWS::Serverless::Connector z Permissions: [Read]).
Dlaczego nie: zarządzana polityka AmazonS3ReadOnlyAccess daje odczyt wszystkich bucketów.
🔬 Głębiej: SAM i CDK w szczegółach
- SAM szuka konfiguracji kolejno: plik z
--config-file,samconfig.toml,samconfig.yaml/.yml. Struktura:[środowisko.polecenie.parameters], domyślne środowisko todefault. sam deploy --resolve-s3sam tworzy bucket na artefakty;--resolve-image-repostworzy repozytoria ECR dla funkcji zPackageType: Image.sam syncbez--watchrobi jednorazową synchronizację;--codesynchronizuje tylko kod (funkcje, layery, definicje API/state machine),--skip-deploy-syncpomija początkowe wdrożenie CloudFormation, gdy szablon się nie zmienił.AutoPublishAliaspublikuje nową wersję, gdy zmieni się URI kodu w S3 (czyli kod), a dla zmian konfiguracji pomagaAutoPublishCodeSha256/AutoPublishAliasAllProperties.- CDK Pipelines (
pipelines.CodePipeline) to construct budujący samoaktualizujący się pipeline dla aplikacji CDK. - W CDK zamiast metod
grant*na konstrukcie można używać klas Grants (np.BucketGrants.fromBucket(bucket)), które działają dla L1 i L2.
- SAM = CloudFormation +
Transform: AWS::Serverless-2016-10-31+ krótkie typyAWS::Serverless::*+Globals+ policy templates. - Lokalnie (Docker):
sam local invoke -e,start-api(3000),start-lambda(3001),generate-event. sam build→sam deploy --guided(zapisujesamconfig.toml) →--config-envdla środowisk.sam sync --watchtylko dev.AutoPublishAlias+DeploymentPreference(Canary/Linear/AllAtOnce) +Alarms+PreTraffic/PostTraffic= bezpieczne wdrożenie przez CodeDeploy.- CDK: app → stacks → constructs (L1
Cfn*, L2, L3).cdk bootstrapraz na konto+Region, potemsynth/diff/deploy. Testy:Template.fromStack+ snapshot.
CI/CD: taśma produkcyjna dla kodu
commit wchodzi z jednej strony, wdrożenie wychodzi z drugiejPomyśl o myjni samochodowej z taśmą. Samochód wjeżdża (commit), przechodzi przez stanowiska po kolei (pobranie kodu, budowanie, testy, akceptacja, wdrożenie) i jeśli któreś stanowisko wykryje problem, taśma staje, zanim brudne auto wyjedzie do klienta. To jest CI/CD: continuous integration (każdy commit jest budowany i testowany) i continuous delivery/deployment (każda zielona zmiana może trafić, albo sama trafia, na produkcję).
W AWS role są podzielone tak: AWS CodePipeline to sama taśma (orkiestrator etapów), AWS CodeBuild to stanowisko, które kompiluje i testuje, AWS CodeDeploy wdraża (osobny rozdział), a kod leży w repozytorium Git: GitHub, GitLab, Bitbucket (przez AWS CodeConnections) albo AWS CodeCommit. Paczki bibliotek trzyma AWS CodeArtifact.
3.1.33.4.63.4.73.4.93.3.3
- CodeBuild czyta instrukcje z pliku
buildspec.ymlw katalogu głównym źródeł (nazwa i miejsce domyślne, można nadpisać).version: 0.2, fazyinstall→pre_build→build→post_build, potemartifacts,cache,reports. - Sekrety w buildzie:
env: parameter-store:ienv: secrets-manager:, nie zwykłevariables(te widać jawnie w konsoli i CLI). Rola CodeBuild potrzebujessm:GetParameters/secretsmanager:GetSecretValue. - Budowanie obrazów Docker w CodeBuild wymaga privileged mode. Build w VPC (dostęp do RDS w prywatnej podsieci) wymaga NAT gateway, żeby wyjść do internetu.
- Szybsze buildy: cache w S3 (współdzielony między hostami) albo lokalny (source, Docker layer, custom). Domyślny timeout buildu 60 min (5–2 160 min).
- CodePipeline: etapy (stages) z akcjami kategorii
source,build,test,deploy,approval,invoke. Artefakty między akcjami idą przez bucket S3 pipeline'u. - Manual approval: pipeline staje, może wysłać powiadomienie przez SNS; brak decyzji w 7 dni = akcja nieudana. Zatwierdza ktoś z uprawnieniem
codepipeline:PutApprovalResult. - Pipeline typu V2: triggery z filtrami na Git tags, gałęzie, pull requesty i ścieżki plików, zmienne na poziomie pipeline'u, tryby QUEUED/PARALLEL. Typ V1 tego nie ma.
- Cross-account pipeline: klucz KMS zarządzany przez klienta (customer managed key) zamiast domyślnego + role w drugim koncie. Cross-region: bucket artefaktów w każdej Regionie z akcjami.
- CodeArtifact: prywatne repozytorium paczek (npm, PyPI, Maven…) z upstream i external connection do publicznych rejestrów. Token ważny domyślnie 12 h.
INSTALL, PRE_BUILD, BUILD, POST_BUILD, UPLOAD_ARTIFACTS), limit 7 dni na approval i filtry triggerów V2 są prawdziwe; nazwy gałęzi, tagów, commitów i treść błędu testu są ilustracyjne.AWS CodeBuild
CodeBuild to wynajęty na minuty pracownik: dostaje świeży kontener z obrazem (np. aws/codebuild/standard albo Twój obraz z ECR), pobiera kod, wykonuje polecenia z buildspec.yml, wysyła artefakty i logi, a potem znika. Nie utrzymujesz serwerów buildów i płacisz za czas buildu.
version: 0.2
env:
variables: { APP_ENV: "test" } # jawne, widoczne w konsoli
parameter-store: { DB_HOST: "/orders/test/db-host" } # wymaga ssm:GetParameters
secrets-manager: { DB_PASS: "orders/test/db:password" } # secret-id:json-key
exported-variables: [ IMAGE_TAG ] # widoczne dla kolejnych akcji pipeline'u
phases:
install:
runtime-versions: { python: 3.13 }
commands: [ pip install -r requirements.txt ]
pre_build:
commands:
- aws ecr get-login-password | docker login --username AWS --password-stdin $REPO
- export IMAGE_TAG=$CODEBUILD_RESOLVED_SOURCE_VERSION
build:
commands:
- pytest --junitxml=reports/unit.xml
- docker build -t $REPO:$IMAGE_TAG . # wymaga privileged mode
finally: [ echo "zawsze, nawet gdy komenda wyżej padnie" ]
post_build:
commands: [ docker push $REPO:$IMAGE_TAG ]
reports:
unit-tests: { files: [ unit.xml ], base-directory: reports, file-format: JUNITXML }
artifacts:
files: [ appspec.yml, scripts/**/*, dist/**/* ]
cache:
paths: [ "/root/.cache/pip/**/*" ]
| Element | Co robi | Na egzaminie |
|---|---|---|
version | 0.2 (zalecana; 0.1 wciąż wspierana) | W 0.2 każda komenda działa w tej samej powłoce, zmienne przechodzą między komendami |
phases | install, pre_build, build, post_build; w każdej commands, finally, on-failure (ABORT/CONTINUE/RETRY), run-as | Logowanie do ECR w pre_build, docker push w post_build |
runtime-versions | Wybór wersji języka w fazie install | Działa na obrazach standard (Ubuntu 5.0+ / AL2 4.0+) |
env | variables, parameter-store, secrets-manager, exported-variables, git-credential-helper | Sekrety nigdy w variables |
artifacts | Pliki do zachowania (files, base-directory, discard-paths, secondary-artifacts) | Wynik trafia do S3 albo do następnej akcji pipeline'u |
reports | Raporty testów (JUnit XML – domyślny format, NUnit, TestNG, Cucumber JSON, Visual Studio TRX) i pokrycia kodu | „Pokaż wyniki testów w konsoli CodeBuild” |
cache | Ścieżki do zachowania między buildami | Przyspieszenie (zależności npm/pip/Maven) |
Faza UPLOAD_ARTIFACTS jest próbowana zawsze, nawet gdy faza BUILD się nie uda. Polecenia z bloku finally wykonują się nawet po błędzie komend w tej fazie. Zmienna CODEBUILD_BUILD_SUCCEEDING ma wartość 1 (sukces) albo 0 (porażka), więc w post_build możesz zareagować na wynik.
CodeBuild: środowisko, cache, sieć, limity
- Zmienne wbudowane:
CODEBUILD_BUILD_ID,CODEBUILD_BUILD_NUMBER,CODEBUILD_BUILD_SUCCEEDING,CODEBUILD_INITIATOR(np.codepipeline/my-pipeline),CODEBUILD_RESOLVED_SOURCE_VERSION(commit ID, dostępny poDOWNLOAD_SOURCE),CODEBUILD_SOURCE_VERSION,CODEBUILD_SRC_DIR,CODEBUILD_WEBHOOK_TRIGGER,CODEBUILD_START_TIME,AWS_REGION/AWS_DEFAULT_REGION. - Cache S3: przechowywany w buckecie, dostępny dla wielu hostów buildów; dobry dla małych i średnich artefaktów. Możesz podać
key(wersjonowane kopie cache). - Cache lokalny: na hoście buildu, dostępny tylko dla tego hosta, natychmiastowy. Tryby: source cache (metadane Git), Docker layer cache (tylko Linux, wymaga privileged mode), custom cache (katalogi z buildspec).
- Privileged mode (
privilegedMode, domyślniefalse): uruchamia demona Docker w kontenerze buildu. Bez tegodocker buildsię nie uda. - VPC: podajesz VPC, podsieci (prywatne) i security groups. Build dostaje dostęp do RDS/ElastiCache w VPC, ale do internetu (np. pobranie paczek, wywołania AWS API przez publiczne endpointy) potrzebuje NAT gateway; internet gateway nie wystarczy.
- Timeouty: build 5–2 160 min (36 h), domyślnie 60 min; czas w kolejce 5–480 min.
- Lokalne buildy: CodeBuild agent (obraz Docker, x86_64 i ARM) uruchamia buildspec na Twoim komputerze, żeby debugować bez płacenia za buildy w chmurze.
- Logi buildu idą do CloudWatch Logs i/lub S3. Build może startować z webhooka (push/PR w GitHub, GitLab, Bitbucket), z harmonogramu EventBridge albo z CodePipeline.
AWS CodePipeline
Pipeline to lista etapów (stages, 2–50), a każdy etap zawiera akcje (actions) uruchamiane po kolei albo równolegle (runOrder). Akcja ma kategorię i dostawcę (provider): np. Source/GitHub przez CodeConnections, Build/CodeBuild, Deploy/CodeDeploy, Deploy/CloudFormation, Deploy/ECS, Deploy/Elastic Beanstalk, Deploy/S3, Approval/Manual, Invoke/Lambda, Invoke/Step Functions. Akcje wymieniają się artefaktami (input/output artifacts) przez bucket S3 pipeline'u (artifact store w tej samej Regionie i koncie co pipeline).
Gdy akcja się nie uda, etap ma status Failed, wykonanie pipeline'u się zatrzymuje i nie przechodzi dalej. Nieudany etap możesz ponowić (retry) bez startowania całego pipeline'u od nowa; w V2 możesz też skonfigurować automatyczny retry etapu i rollback etapu do ostatniego udanego wykonania.
| Cecha | V1 | V2 |
|---|---|---|
| Zmienne akcji (action-level variables) | ✓ | ✓ |
| Zmienne pipeline'u podawane przy starcie | ✗ | ✓ |
| Triggery z filtrami: Git tags, gałęzie, pull requesty, ścieżki plików | ✗ | ✓ |
Tryby wykonania QUEUED, PARALLEL (domyślny: SUPERSEDED) | tylko SUPERSEDED | ✓ |
| Rollback etapu, warunki etapu, automatyczny retry, akcja Commands, nadpisanie rewizji źródła | ✗ | ✓ |
- Wyzwalanie: źródła CodeCommit i S3 wykrywają zmiany przez reguły EventBridge (zalecane zamiast okresowego pollingu). Źródła GitHub/GitLab/Bitbucket przez CodeConnections używają webhooków (trigger typu push lub pull request, w V2 z filtrami). Pipeline możesz też uruchomić ręcznie (
start-pipeline-execution) albo z harmonogramu EventBridge. - SUPERSEDED (domyślnie): nowsze wykonanie może „przeskoczyć” starsze, które czeka przed zablokowanym etapem; starsze kończy się statusem
Superseded. QUEUED: wykonania czekają w kolejce w kolejności. PARALLEL: wykonania niezależne, równolegle. - Zmienne: akcje publikują zmienne wyjściowe (np.
#{SourceVariables.CommitId}, zmienne eksportowane z CodeBuild przezexported-variables), a kolejne akcje je czytają. - Cross-region: akcja może działać w innej Regionie, ale w każdej Regionie z akcjami potrzebujesz bucketu na artefakty (konsola tworzy je sama, CLI/CloudFormation nie).
- Cross-account: domyślny klucz KMS (AWS managed) nie wystarczy, bo drugie konto nie odszyfruje artefaktów. Tworzysz customer managed key, dajesz do niego dostęp roli pipeline'u i drugiemu kontu, a w drugim koncie rolę, którą pipeline przyjmuje (assume role).
- AWS CodeConnections (dawniej AWS CodeStar Connections) łączy CodePipeline z GitHub, GitHub Enterprise Server, GitLab i Bitbucket. Akcja źródłowa daje domyślnie ZIP (
CODE_ZIP), a zCODEBUILD_CLONE_REFpełny klon Git (tylko dla następnej akcji CodeBuild; np. gdy build potrzebuje historii Git). - Monitoring: zdarzenia zmian stanu pipeline'u/etapu/akcji idą do EventBridge, więc na „pipeline failed” podepniesz SNS lub Lambdę.
Gałęzie, tagi i środowiska
Typowy układ: gałąź = strumień pracy, tag = konkretna wersja (release). Pipeline dla main wdraża na test, a tag v1.4.0 uruchamia wdrożenie na produkcję (trigger V2 z filtrem tagów). Środowiska dev/test/prod to osobne etapy (albo osobne pipeline'y), każdy z własnymi parametrami (np. pliki konfiguracyjne CloudFormation, samconfig.toml --config-env, zmienne etapu API Gateway, aliasy Lambdy). Do integracji z innymi zespołami wskazujesz zatwierdzone wersje: alias Lambdy test → konkretna wersja, tag obrazu w ECR, etap API Gateway.
"triggers": [{ "providerType": "CodeStarSourceConnection",
"gitConfiguration": { "sourceActionName": "Source",
"push": [{ "tags": { "includes": ["v*"] } }] } }] # V2: start tylko na tag v*
CodeArtifact
Prywatna „hurtownia” paczek. Domena grupuje repozytoria (np. całej firmy); każda paczka jest przechowywana raz na domenę, a repozytorium należy do jednej domeny na zawsze. Repozytorium obsługuje npm/yarn, pip/twine (PyPI), Maven/Gradle, NuGet, Cargo, RubyGems i inne. Repozytorium może mieć do 10 upstreamów (inne repozytoria CodeArtifact) i jedno external connection do publicznego rejestru (public:npmjs, public:pypi, public:maven-central, public:nuget-org…). Wersja paczki pobrana raz z zewnątrz jest zawsze zachowywana w repozytorium z external connection, więc paczki już pobrane są dostępne nawet podczas awarii publicznego rejestru.
aws codeartifact login --tool npm --domain acme --repository app-libs # konfiguruje npm + token
aws codeartifact get-authorization-token --domain acme --query authorizationToken --output text
# token: domyślnie 12 h, od 15 min do 12 h (--duration-seconds 900–43200; 0 = do końca sesji roli)
CodeCommit i Amplify
AWS CodeCommit to zarządzane prywatne repozytoria Git z dostępem przez IAM. W lipcu 2024 AWS ogłosił „de-emphasize”: nowi klienci nie mogli zakładać repozytoriów i zalecano migrację do innych dostawców Git. 24 listopada 2025 AWS ogłosił powrót CodeCommit do pełnej dostępności (General Availability): nowe konta znów mogą tworzyć repozytoria. W starszych testach próbnych CodeCommit jest często domyślnym źródłem pipeline'u („commit to CodeCommit triggers the pipeline”); mechanika (EventBridge → pipeline) się nie zmieniła. Uprawnienia: IAM (np. codecommit:GitPush), dostęp przez HTTPS (Git credentials lub helper) albo SSH.
AWS Amplify Hosting wdraża frontend (i backend Amplify) prosto z repozytorium Git: każda podłączona gałąź to osobne środowisko z własnym URL, a web previews wdrażają każdy pull request pod unikalny adres podglądu. „Najprostsze CI/CD dla aplikacji webowej/SPA z gałęziami feature/dev/main” → Amplify.
- „Hasło do bazy w
env: variablesbuildspec” – widoczne jawnie w konsoli i CLI. Poprawnie:parameter-store(SecureString) lubsecrets-manager. - „buildspec.yml w podkatalogu i build go nie widzi” – domyślnie musi leżeć w katalogu głównym źródeł; inną ścieżkę podajesz w projekcie (buildspec override).
- „Build w VPC nie może pobrać paczek, więc dodaj internet gateway” – CodeBuild w VPC potrzebuje NAT gateway (albo VPC endpoints do usług AWS), nie internet gateway.
- „
docker buildpada w CodeBuild – zmień obraz” – zwykle brakuje privileged mode. - „Approval wyśle e-mail sam z siebie” – powiadomienie idzie przez temat SNS, który musisz wskazać (i zasubskrybować). Bez decyzji przez 7 dni akcja kończy się jak nieudana.
- „Trigger na Git tag w pipeline V1” – filtry tagów/gałęzi/ścieżek to funkcja V2.
- „Cross-account pipeline z domyślnym kluczem S3/KMS” – drugie konto nie odszyfruje artefaktów; potrzebny customer managed KMS key.
- „CodeCommit nie przyjmuje nowych klientów” – było tak od lipca 2024; od 24 listopada 2025 usługa jest znów w pełni dostępna.
- „Upstream = publiczny rejestr” – upstream to inne repozytorium CodeArtifact; do npmjs/PyPI łączy external connection (jedno na repozytorium).
Projekt CodeBuild buduje obraz Docker i wypycha go do ECR. Build kończy się błędem „Cannot connect to the Docker daemon”. Co zmienić?
Docker w CodeBuild · demon
Odpowiedź
Włączyć privileged mode w środowisku projektu.
Dlaczego nie: zmiana compute type nie da demona Docker; uprawnienia IAM do ECR to inny błąd (odmowa przy push/login).
Testy integracyjne w CodeBuild muszą łączyć się z bazą RDS w prywatnej podsieci i pobierać paczki z internetu. Jak skonfigurować projekt?
CodeBuild · prywatna baza · internet
Odpowiedź
Konfiguracja VPC projektu (prywatne podsieci + security group z dostępem do RDS) i NAT gateway w publicznej podsieci.
Dlaczego nie: publiczny dostęp do RDS łamie bezpieczeństwo; internet gateway nie działa dla buildów w VPC.
Pipeline ma się zatrzymać przed wdrożeniem na produkcję, a kierownik ma dostać e-mail z prośbą o akceptację. Jak?
zatrzymaj · akceptacja człowieka · e-mail
Odpowiedź
Akcja Manual approval przed etapem Deploy, z tematem SNS, który ma subskrypcję e-mail kierownika. Kierownik potrzebuje codepipeline:PutApprovalResult.
Dlaczego nie: Lambda czekająca na odpowiedź jest zbędna i ma limity czasu; osobny pipeline nie zatrzyma tego.
Zespół chce, żeby wdrożenie produkcyjne startowało tylko po wypchnięciu tagu w formacie release-* do repozytorium GitHub. Co skonfigurować?
tag · filtr · GitHub
Odpowiedź
Pipeline typu V2 ze źródłem przez CodeConnections i triggerem push z filtrem tagów release-*.
Dlaczego nie: pipeline V1 nie filtruje tagów; webhook CodeBuild nie uruchomi całego pipeline'u z etapami.
Buildy npm trwają długo przez pobieranie zależności, a czasem padają, gdy publiczny rejestr npm ma awarię. Co poprawi oba problemy?
zależności · publiczny rejestr niedostępny · szybciej
Odpowiedź
Repozytorium CodeArtifact z external connection do public:npmjs (paczki zostają w repozytorium) oraz cache CodeBuild dla katalogu zależności.
Dlaczego nie: zwiększenie compute type nie pomoże przy awarii rejestru; commit node_modules do repozytorium to zła praktyka.
Pipeline w koncie Tools wdraża przez CloudFormation do konta Prod. Akcja w Prod nie może odczytać artefaktu z S3. Co jest najpewniej źle?
cross-account · artefakt · szyfrowanie
Odpowiedź
Artefakty są szyfrowane domyślnym kluczem AWS managed; trzeba customer managed KMS key z key policy dla konta Prod (i polityki bucketu dla roli z Prod).
Dlaczego nie: replikacja bucketu nie rozwiązuje uprawnień do klucza; cross-region dotyczy Regionów, nie kont.
🔬 Głębiej: liczby i rzadsze opcje
- CodePipeline: max 1 000 akcji w pipeline, 100 równoległych akcji w etapie, 50 równoczesnych wykonań na pipeline w trybie QUEUED/PARALLEL. Artefakt źródłowy: 7 GB z S3, 1 GB z CodeCommit/GitHub.
- Timeouty akcji: CloudFormation 3 dni, CodeDeploy 5 dni, CodeBuild 36 h, invoke Lambda – funkcja musi odpowiedzieć (
PutJobSuccessResult/PutJobFailureResult); manual approval 7 dni. - Statusy wykonania:
InProgress,Stopping,Stopped,Succeeded,Superseded,Failed. Wykonanie można zatrzymać („Stop and wait” albo „Stop and abandon”). - CodeBuild batch builds (
batch:w buildspec): build-list, build-matrix, build-graph – wiele buildów naraz (np. różne wersje runtime). on-failure: RETRY-3w fazie buildspec ponawia build (do 3 razy,RETRY-count0–100);CONTINUEidzie do następnej fazy mimo błędu;ABORTprzerywa build.- CodeArtifact: max 25 upstreamów przeszukiwanych przy rozwiązywaniu paczki; repozytorium można podpiąć z zasadami (resource policy) dla innych kont.
- CodePipeline = taśma (etapy, akcje, artefakty w S3), CodeBuild = budowanie i testy (
buildspec.ymlw root), CodeDeploy = wdrożenie. - Buildspec 0.2:
install→pre_build→build→post_build; sekrety przezparameter-store/secrets-manager;UPLOAD_ARTIFACTSzawsze próbowany. - Docker → privileged mode; VPC → NAT gateway; szybciej → cache S3/lokalny; timeout domyślnie 60 min.
- Manual approval + SNS, 7 dni. V2: tagi, gałęzie, PR, ścieżki, zmienne pipeline'u, QUEUED/PARALLEL.
- Cross-account → customer managed KMS key; cross-region → bucket artefaktów w każdej Regionie.
- CodeArtifact: domena → repozytoria, 10 upstreamów, 1 external connection, token 12 h. CodeCommit znów GA (od 24.11.2025). Amplify: gałąź = środowisko, PR = preview.
CodeDeploy i strategie wdrożeń
jak wymienić koło w jadącym autobusieNowa wersja aplikacji to nowe koło w autobusie pełnym pasażerów. Możesz zatrzymać autobus i wymienić wszystkie koła naraz (szybko, ale pasażerowie stoją). Możesz wymieniać po jednym (autobus jedzie wolniej). Możesz podstawić drugi, nowy autobus i przesadzić ludzi (drogo, ale gdy coś nie gra, wracają do starego w sekundę). Albo przesadzić najpierw jednego pasażera na dziesięciu i zobaczyć, czy nie narzeka. To są strategie wdrożeń: all-at-once, rolling, blue/green, canary.
AWS CodeDeploy automatyzuje te strategie dla trzech platform obliczeniowych (compute platforms): EC2/On-Premises (kopiuje pliki i uruchamia skrypty na serwerach przez CodeDeploy agent), AWS Lambda (przesuwa ruch aliasu między wersjami funkcji) i Amazon ECS (przesuwa ruch load balancera na nowy task set). Instrukcję wdrożenia zapisujesz w pliku appspec.yml.
3.4.53.4.83.4.113.3.3
- Kolejność hooków EC2 in-place:
ApplicationStop→DownloadBundle→BeforeInstall→Install→AfterInstall→ApplicationStart→ValidateService. Z load balancerem dochodząBeforeBlockTraffic/BlockTraffic/AfterBlockTrafficna początku iBeforeAllowTraffic/AllowTraffic/AfterAllowTrafficna końcu.DownloadBundle,Install,BlockTraffic,AllowTrafficsą zarezerwowane (bez skryptów). - Lambda: hooki tylko
BeforeAllowTrafficiAfterAllowTraffic. ECS:BeforeInstall,AfterInstall,AfterAllowTestTraffic,BeforeAllowTraffic,AfterAllowTraffic. - Konfiguracje EC2:
CodeDeployDefault.OneAtATime(domyślna),HalfAtATime,AllAtOncealbo własna (minimum healthy hosts). Lambda/ECS:Canary10Percent5Minutes…,Linear10PercentEvery1Minute…,AllAtOnce. - In-place tylko dla EC2/On-Premises. Lambda i ECS zawsze robią blue/green (przesuwanie ruchu).
- Rollback = CodeDeploy wdraża ostatnią dobrą rewizję jako nowe wdrożenie z nowym deployment ID. Automatycznie: gdy wdrożenie się nie uda albo gdy alarm CloudWatch przejdzie w
ALARM. - Typowe awarie: agent CodeDeploy nie działa, brak/zły IAM instance profile (agent nie pobierze rewizji z S3), skrypt hooka zwraca błąd lub przekracza timeout (domyślnie i maksymalnie 3 600 s),
ApplicationStopużywa skryptów z poprzedniej udanej rewizji.
Strategie wdrożeń: porównanie
| Strategia | Pojemność w trakcie | Przestój | Rollback | Koszt | Gdzie w AWS |
|---|---|---|---|---|---|
| All at once (in-place) | 0% przez chwilę | Tak | Wolny: ponowne wdrożenie starej wersji | Najniższy | CodeDeploy AllAtOnce, Beanstalk „All at once” |
| Rolling | Zmniejszona o partię | Nie (mniej pojemności) | Wolny: ponowne wdrożenie | Bez dodatkowych instancji | CodeDeploy OneAtATime/HalfAtATime, Beanstalk „Rolling” |
| Rolling with additional batch | Pełna | Nie | Wolny | +1 partia na czas wdrożenia | Beanstalk |
| Immutable | Pełna (nowe instancje w osobnej ASG) | Nie | Szybki: usunięcie nowych instancji | Podwójna flota na chwilę | Beanstalk |
| Blue/green | Pełna | Nie | Najszybszy: ruch wraca na stare środowisko | Dwa środowiska naraz | CodeDeploy (EC2, Lambda, ECS), Beanstalk swap URL (CNAME), Route 53 |
| Canary | Pełna | Nie | Szybki, mało użytkowników dotkniętych | Jak blue/green | CodeDeploy Lambda/ECS Canary…, API Gateway canary, Beanstalk traffic splitting |
| Linear | Pełna | Nie | Szybki | Jak blue/green | CodeDeploy Lambda/ECS Linear… |
| Traffic splitting | Pełna | Nie | Szybki | Podwójna flota na chwilę | Beanstalk (canary na nowych instancjach) |
Polityki wdrożeń Elastic Beanstalk opisuje rozdział o Beanstalk, a canary w API Gateway rozdział o operacjach API. Tu ważne jest jedno pytanie: „co jest ważniejsze: koszt, brak przestoju, czy szybki rollback?” Brak przestoju + najszybszy rollback = blue/green. Najmniej dotkniętych użytkowników = canary. Najtaniej i najprościej = all at once (z przestojem).
Elementy CodeDeploy
| Pojęcie | Co to |
|---|---|
| Application | Nazwa-kontener dla wdrożeń, przypisana do jednej platformy (EC2/On-Premises, Lambda, ECS) |
| Deployment group | Gdzie wdrażasz: dla EC2 instancje wskazane tagami i/lub grupy Auto Scaling (oraz on-premises po tagach); dla Lambdy funkcja; dla ECS serwis + load balancer + dwie target groups. Tu ustawiasz load balancer, alarmy, automatyczny rollback, triggery SNS |
| Deployment configuration | Tempo: ile instancji naraz musi być zdrowych (EC2) albo jak przesuwać ruch (Lambda/ECS) |
| Revision | Wersja do wdrożenia: dla EC2 archiwum (zip, tar, tgz) z kodem, skryptami i appspec.yml, w S3 albo GitHub; dla Lambda/ECS sam plik AppSpec (YAML/JSON) |
| CodeDeploy agent | Program na instancji EC2/on-prem, który odpytuje CodeDeploy, pobiera rewizję i uruchamia hooki. Nie dotyczy Lambdy ani ECS |
| Service role / instance profile | Rola usługi CodeDeploy (dostęp do EC2, ASG, ELB…) i rola instancji (pobranie rewizji z S3) |
appspec.yml dla każdej platformy
# EC2/On-Premises – plik appspec.yml w KATALOGU GŁÓWNYM rewizji
version: 0.0 # jedyna dozwolona wartość
os: linux
files:
- source: /dist
destination: /var/www/app
permissions:
- object: /var/www/app
owner: nginx
hooks:
ApplicationStop: [ { location: scripts/stop.sh, timeout: 60 } ]
BeforeInstall: [ { location: scripts/backup.sh } ]
AfterInstall: [ { location: scripts/config.sh, runas: root } ]
ApplicationStart: [ { location: scripts/start.sh } ]
ValidateService: [ { location: scripts/health.sh, timeout: 300 } ]
# AWS Lambda
version: 0.0
Resources:
- OrdersFn:
Type: AWS::Lambda::Function
Properties:
Name: orders-fn
Alias: live
CurrentVersion: "7"
TargetVersion: "8"
Hooks:
- BeforeAllowTraffic: PreTrafficCheckFn
- AfterAllowTraffic: PostTrafficCheckFn
# Amazon ECS
version: 0.0
Resources:
- TargetService:
Type: AWS::ECS::Service
Properties:
TaskDefinition: arn:aws:ecs:…:task-definition/web:12
LoadBalancerInfo: { ContainerName: web, ContainerPort: 80 }
Hooks:
- AfterAllowTestTraffic: TestTrafficCheckFn
Sekcja files i permissions istnieje tylko dla EC2/On-Premises. Dla Lambdy i ECS sekcja Resources mówi, co przełączyć, a hooki to nazwy funkcji Lambda, które muszą zgłosić wynik do CodeDeploy przez PutLifecycleEventHookExecutionStatus. Dla EC2 hooki to skrypty w rewizji.
Hooki EC2/On-Premises po kolei
BeforeBlockTraffic→BlockTraffic→AfterBlockTraffic(tylko z load balancerem: instancja jest wyrejestrowywana)ApplicationStop– zatrzymaj starą aplikację. Nie wykonuje się przy pierwszym wdrożeniu na instancję (nie ma jeszcze poprzedniego AppSpec) i używa skryptu z ostatniej udanej rewizji.DownloadBundle– agent kopiuje rewizję do katalogu tymczasowego (zarezerwowany)BeforeInstall– np. backup, odszyfrowanie plikówInstall– agent kopiuje pliki według sekcjifiles(zarezerwowany)AfterInstall– konfiguracja, uprawnienia plikówApplicationStart– uruchom usługi zatrzymane wApplicationStopValidateService– sprawdź, czy wdrożenie działa (ostatni hook bez load balancera)BeforeAllowTraffic→AllowTraffic→AfterAllowTraffic(z load balancerem: instancja wraca do target group)
W blue/green na EC2 nowe instancje przechodzą hooki instalacji i …AllowTraffic, a oryginalne instancje tylko …BlockTraffic. Skrypty mają do dyspozycji zmienne środowiskowe m.in. LIFECYCLE_EVENT, DEPLOYMENT_ID, DEPLOYMENT_GROUP_NAME, DEPLOYMENT_GROUP_ID, APPLICATION_NAME. Opcje hooka: location, timeout (domyślnie i maksymalnie 3 600 s na zdarzenie), runas.
Konfiguracje wdrożenia
| Konfiguracja | Co robi | Kiedy |
|---|---|---|
CodeDeployDefault.OneAtATime | EC2: po jednej instancji. Domyślna, gdy nic nie podasz | Maksimum dostępności, najwolniej |
CodeDeployDefault.HalfAtATime | EC2: do połowy instancji naraz (zaokrąglenie w dół); sukces, gdy co najmniej połowa się uda | Kompromis |
CodeDeployDefault.AllAtOnce | EC2: wszystkie naraz (sukces, gdy choć jedna się uda); blue/green: cały ruch naraz | Dev/test, szybko |
| własna (minimum healthy hosts) | EC2: liczba albo procent instancji, które muszą zostać zdrowe; opcjonalnie per AZ (zonal) | Np. „zawsze 75% zdrowych” |
CodeDeployDefault.LambdaCanary10Percent5Minutes (też 10, 15, 30 min) | 10% ruchu, po N minutach reszta | Szybka weryfikacja na małej próbce |
CodeDeployDefault.LambdaLinear10PercentEvery1Minute (też 2, 3, 10 min) | +10% co N minut (10 kroków) | Stopniowe dociążanie |
CodeDeployDefault.LambdaAllAtOnce | Cały ruch od razu | Bez stopniowania |
CodeDeployDefault.ECSCanary10Percent5Minutes/15Minutes, ECSLinear10PercentEvery1Minutes/3Minutes, ECSAllAtOnce | To samo dla ECS (z Network Load Balancer tylko ECSAllAtOnce) | Kontenery |
Rollback i ponowne wdrożenie
CodeDeploy nie „cofa” wdrożenia jak Ctrl+Z. Wdraża ostatnią znaną dobrą rewizję jako zupełnie nowe wdrożenie z nowym deployment ID. Automatyczny rollback włączasz w deployment group (albo nadpisujesz przy wdrożeniu) dla dwóch sytuacji: wdrożenie się nie powiodło oraz alarm CloudWatch osiągnął próg (do 50 alarmów na deployment group). Ręcznie robisz to, tworząc nowe wdrożenie wcześniejszej rewizji.
- Przed rollbackiem/redeploy agent usuwa pliki z ostatniej udanej instalacji według pliku
…/deployment-instructions/<deployment-group-ID>-cleanup. - Gdy plik już istnieje w miejscu docelowym, a nie pochodzi z poprzedniego wdrożenia, wybierasz zachowanie: Fail the deployment (domyślnie błąd „file already exists”), Overwrite the content, Retain the content (CLI:
--file-exists-behavior DISALLOW|OVERWRITE|RETAIN). - W blue/green na EC2 rollback jest szybki, bo stare instancje mogą jeszcze działać (o ile nie zostały zakończone po wdrożeniu).
Troubleshooting
| Objaw | Przyczyna | Naprawa |
|---|---|---|
| Wdrożenie wisi/pada na wszystkich instancjach od razu | Agent CodeDeploy nie jest zainstalowany albo nie działa | systemctl status codedeploy-agent, zainstaluj/uruchom agenta |
W logu agenta: CommandPoller: Missing credentials | Instancja nie ma IAM instance profile albo profil nie ma uprawnień | Dołącz instance profile z dostępem do S3 z rewizjami |
| Brak instancji w deployment group | Złe tagi instancji / zła grupa ASG | Popraw tagi lub ASG w deployment group |
Pada ApplicationStop, choć nowy skrypt jest poprawny | Ten hook uruchamia skrypt z poprzedniej udanej rewizji, a ten jest zepsuty | Wdróż z --ignore-application-stop-failures (to samo dla BeforeBlockTraffic/AfterBlockTraffic) |
| Hook „wisi” i pada po godzinie | Skrypt się nie kończy (np. proces na pierwszym planie) albo przekracza timeout (max 3 600 s) | Uruchamiaj usługi w tle, ustaw rozsądny timeout |
| „The deployment failed because a specified file already exists” | Pliki w miejscu docelowym spoza CodeDeploy | Opcja Overwrite/Retain albo skrypt czyszczący w BeforeInstall |
| Instancja zakończona w trakcie wdrożenia | Status Failed może pojawić się dopiero po godzinie | Nie zmieniaj ASG w trakcie wdrożenia |
Logi na instancji Linux: agent – /var/log/aws/codedeploy-agent/codedeploy-agent.log; wyjście skryptów – /opt/codedeploy-agent/deployment-root/<deployment-group-ID>/<deployment-ID>/logs/scripts.log; zbiorczo – /opt/codedeploy-agent/deployment-root/deployment-logs/codedeploy-agent-deployments.log. Agent trzyma domyślnie 5 ostatnich rewizji (:max_revisions:) i zawsze log ostatniego udanego wdrożenia. Logi można wysłać do CloudWatch Logs agentem CloudWatch.
Masz 9 instancji i CodeDeployDefault.HalfAtATime. Ile instancji jest wdrażanych naraz i ile musi się udać, żeby całe wdrożenie było udane?
Odpowiedź
Do 4 naraz (połowa z 9 zaokrąglona w dół). Wdrożenie się udaje, gdy uda się na 5 lub więcej instancjach (połowa zaokrąglona w górę). Tak liczy dokumentacja CodeDeploy dla przykładu 9 instancji.
- „In-place deployment dla Lambdy” – nie istnieje. Lambda i ECS to zawsze przesuwanie ruchu (blue/green: canary, linear, all-at-once).
- „Rollback przywraca stare deployment ID” – rollback to nowe wdrożenie z nowym ID, wdrażające ostatnią dobrą rewizję.
- „
ValidateServicew wdrożeniu Lambdy” – w Lambdzie są tylkoBeforeAllowTrafficiAfterAllowTraffic. - „Skrypt w hooku
InstallalboDownloadBundle” – te zdarzenia są zarezerwowane dla agenta. - „Hook Lambdy zakończył się bez błędu, więc CodeDeploy wie, że test przeszedł” – funkcja hooka musi jawnie wywołać
PutLifecycleEventHookExecutionStatusze statusemSucceeded/Failed. - „Blue/green z on-premises” – blue/green na platformie EC2/On-Premises działa tylko z instancjami EC2.
- „appspec.yml w katalogu scripts/” – dla EC2 plik musi być w katalogu głównym rewizji i nazywać się
appspec.yml. - „Canary = linear” – canary ma dwa kroki (np. 10%, potem 100%), linear wiele równych kroków.
Nowa wersja funkcji Lambda ma dostać 10% ruchu, po 5 minutach całą resztę, a przy błędach ruch ma wrócić automatycznie. Która konfiguracja CodeDeploy?
10% · 5 minut · reszta naraz
Odpowiedź
CodeDeployDefault.LambdaCanary10Percent5Minutes + alarm CloudWatch z automatycznym rollbackiem.
Dlaczego nie: LambdaLinear10PercentEvery1Minute robi dziesięć kroków; LambdaAllAtOnce nie daje próbki.
Wdrożenie in-place na EC2 pada na hooku ApplicationStop. Nowa rewizja ma poprawiony skrypt stop.sh. Dlaczego dalej pada i co zrobić?
ApplicationStop · poprzednia rewizja
Odpowiedź
ApplicationStop uruchamia skrypt z ostatniej udanej rewizji. Wdróż z opcją ignorowania błędów ApplicationStop (--ignore-application-stop-failures).
Dlaczego nie: zwiększenie timeoutu nie zmieni zepsutego starego skryptu; reinstalacja agenta nie pomoże.
Wdrożenie na EC2 kończy się błędem, a w logu agenta jest „Missing credentials - please check if this instance was started with an IAM instance profile”. Co naprawić?
agent · credentials · instance profile
Odpowiedź
Dołączyć do instancji IAM instance profile z uprawnieniami do odczytu rewizji z S3.
Dlaczego nie: klucze dostępu w pliku konfiguracyjnym to zła praktyka; rola usługi CodeDeploy nie zastępuje roli instancji.
Firma chce wdrożeń na EC2 bez przestoju i z możliwością natychmiastowego powrotu do poprzedniej wersji; koszt dodatkowych instancji przez chwilę jest akceptowalny. Co wybrać?
zero przestoju · natychmiastowy powrót · koszt OK
Odpowiedź
Blue/green deployment w CodeDeploy (np. kopia grupy Auto Scaling, przełączenie ruchu na ALB, stare instancje utrzymane przez pewien czas).
Dlaczego nie: in-place OneAtATime nie daje natychmiastowego powrotu; all-at-once ma przestój.
W wdrożeniu ECS blue/green zespół chce uruchomić testy na nowym task secie, zanim trafi tam ruch produkcyjny. Który hook i jaki element ALB?
ECS · test przed produkcją · test listener
Odpowiedź
Test listener na ALB i hook AfterAllowTestTraffic (funkcja Lambda testująca przez port testowy).
Dlaczego nie: ValidateService jest tylko w EC2; AfterAllowTraffic działa już po przełączeniu produkcji.
🔬 Głębiej: limity i rzadkie przypadki
- Jedno wdrożenie naraz na deployment group. Maksymalny czas: in-place EC2 12 h; blue/green EC2 109 h; Lambda 50 h (48 h między pierwszym a ostatnim przesunięciem ruchu).
- Do 10 grup Auto Scaling w deployment group, 1 000 deployment groups na aplikację, 50 własnych konfiguracji wdrożeń na konto.
- Wdrożenie w Auto Scaling: nowa instancja z ASG dostaje automatycznie ostatnią udaną rewizję (Auto Scaling launch deployment), z hookami od
ApplicationStopdoAfterAllowTraffic. - Blue/green ECS przez CloudFormation: hook
AWS::CodeDeploy::BlueGreenw szablonie (sekcjaHooks). - Agent musi wspierać SHA-256 (wersja 1.0.1.854+); bardzo stare wersje dają błąd „Validation of PKCS7 signed message failed”.
- CodeDeploy: EC2/On-Premises (agent + skrypty), Lambda (alias), ECS (task set).
appspec.yml,version: 0.0. - EC2: ApplicationStop → DownloadBundle → BeforeInstall → Install → AfterInstall → ApplicationStart → ValidateService (+ Block/AllowTraffic z LB).
- Lambda: BeforeAllowTraffic / AfterAllowTraffic. ECS: + BeforeInstall, AfterInstall, AfterAllowTestTraffic.
- OneAtATime (domyślnie), HalfAtATime, AllAtOnce; Lambda/ECS Canary, Linear, AllAtOnce. In-place tylko EC2.
- Rollback = nowe wdrożenie ostatniej dobrej rewizji (nowe ID), automatycznie po błędzie albo alarmie.
- Awaria: agent, instance profile, skrypt (timeout 3 600 s), ApplicationStop ze starej rewizji.
- Strategie: all-at-once (tanio, przestój), rolling (mniej pojemności), blue/green (szybki powrót, podwójny koszt), canary/linear (mała próbka, stopniowo).
Testowanie aplikacji w AWS
od testu w konsoli do testu całego przepływu zdarzeńTestowanie aplikacji serverless przypomina sprawdzanie instalacji wodnej w nowym domu. Każdą rurę możesz obejrzeć osobno na stole (test jednostkowy), ale to, czy woda dopłynie z kranu do odpływu, sprawdzisz dopiero po podłączeniu wszystkiego w budynku (test integracyjny i end-to-end). Dokumentacja Lambdy mówi to wprost: lokalnie nie odtworzysz w pełni kolejek, tabel, szyn zdarzeń ani polityk bezpieczeństwa, więc testy w chmurze dają najdokładniejszy obraz jakości.
Trzy poziomy, które warto rozróżniać: unit tests (logika biznesowa w izolacji, zależności zastąpione mockami), integration tests (dwa lub więcej komponentów, zwykle w chmurze, np. „funkcja przetwarza wiadomość z kolejki”) i end-to-end tests (cała aplikacja, zdarzenie przechodzi przez wszystkie usługi).
1.1.71.1.111.2.43.2.13.2.23.2.33.2.53.3.13.3.6
- Test events w konsoli Lambda: prywatne (tylko autor, do 10 na funkcję) albo shareable (dla innych użytkowników tego samego konta; przechowywane w rejestrze schematów EventBridge
lambda-testevent-schemas). - Gotowe ładunki zdarzeń (S3, SQS, SNS, API Gateway, DynamoDB Streams…):
sam local generate-event; uruchomienie lokalne:sam local invoke -e event.json. - Mock API dla zespołu frontendu, zanim backend istnieje: API Gateway mock integration (odpowiedź generuje sam API Gateway, bez backendu).
- Mocki w testach jednostkowych: stub klienta SDK (Python
botocore.stub.Stubber, JavaScript v3aws-sdk-client-mock), bez wywołań do AWS. - Testy integracyjne na osobnym środowisku: osobny stos/etap (np. etap
testw API Gateway, alias Lambdytestwskazujący zatwierdzoną wersję), osobne konto. Nie na produkcji. - Aplikacje sterowane zdarzeniami: EventBridge archive + replay (ponowne wysłanie zarchiwizowanych zdarzeń), testowe kolejki/reguły nasłuchujące efektów, DLQ do analizy błędów. Step Functions: TestState API (test jednego stanu, z mockami).
- Amazon Q Developer: generowanie testów jednostkowych, przegląd kodu (bezpieczeństwo, jakość), dokumentacja, implementacja funkcji, podpowiedzi kodu w IDE. Dawne komendy
/test,/review,/doc,/devto dawne nazwy tych możliwości — dokumentacja opisuje je dziś jako capabilities agentic coding, nie osobne komendy czatu. W pytaniach egzaminacyjnych możesz jeszcze spotkać stare nazwy.
Zdarzenia testowe
Funkcja Lambda dostaje JSON. Test to po prostu wywołanie funkcji z przygotowanym JSON-em, który wygląda jak prawdziwe zdarzenie. Skąd go wziąć?
| Narzędzie | Co robi | Kiedy |
|---|---|---|
| Konsola Lambda → Test | Szablony zdarzeń (S3 Put, SQS, API Gateway proxy…), zapis jako private lub shareable | Szybki test wdrożonej funkcji; shareable, gdy cały zespół ma używać tych samych zdarzeń |
sam local generate-event <usługa> <zdarzenie> | Generuje przykładowy ładunek, z opcjami (np. --bucket, --key) | Pliki zdarzeń w repozytorium, testy lokalne |
sam local invoke -e / sam local start-api / start-lambda | Uruchamia funkcję lokalnie w Dockerze (SAM i CDK) | Pętla deweloperska |
sam remote invoke / sam remote test-event | Wywołuje funkcję w chmurze; zarządza shareable test events w rejestrze schematów EventBridge | Test wdrożonej funkcji z terminala |
aws lambda invoke --payload | Wywołanie z CLI (w CLI v2 dla JSON-a dodaj --cli-binary-format raw-in-base64-out) | Skrypty |
| Konsola API Gateway → Test metody | Wywołuje metodę z podanymi nagłówkami, ścieżką, query i body; logi są symulowane, ale wywołanie backendu jest prawdziwe | Debug integracji i mapowań |
Shareable test events wymagają uprawnień do operacji rejestru schematów EventBridge (np. schemas:CreateSchema, schemas:DescribeSchema, schemas:UpdateSchema).
Mocki i zależności zewnętrzne
- API Gateway mock integration: typ integracji
MOCK. W integration request mapujesz{"statusCode": 200}, w integration response zwracasz przygotowane body. Zespół frontendu pracuje na „prawdziwym” URL, zanim backend powstanie. Też: szybkie odpowiedziOPTIONSdla CORS. - Stub klienta SDK w testach jednostkowych: Python
botocore.stub.Stubber(add_response,activate), JavaScript v3aws-sdk-client-mock(zalecany przez zespół SDK JS). Test sprawdza logikę i parametry wywołań bez sieci i kosztów. - Wstrzykiwanie zależności: twórz klienta SDK poza handlerem i przekazuj go do funkcji z logiką; wtedy w teście podmienisz go na mock. Endpoint zewnętrznego API trzymaj w zmiennej środowiskowej, żeby w teście wskazać atrapę.
- Emulacja: dokumentacja Lambdy wspomina integrację LocalStack w AWS Toolkit for VS Code do emulacji wielu usług lokalnie. Emulacja nie zastąpi testów w chmurze.
import boto3
from botocore.stub import Stubber
s3 = boto3.client("s3")
with Stubber(s3) as stub:
stub.add_response("get_object", {"Body": FakeBody(b'{"total": 42}')},
{"Bucket": "orders", "Key": "o-1.json"})
assert load_total(s3, "o-1.json") == 42 # zero wywołań do AWS
Środowiska testowe i zatwierdzone wersje
Testy integracyjne uruchamiasz na osobnych zasobach: osobny stos CloudFormation/SAM (np. orders-test przez samconfig.toml --config-env test), osobny etap API Gateway (dev, test, prod, każdy z własnymi stage variables, np. aliasem Lambdy, na który wskazuje), osobne konto w AWS Organizations. W pipeline to osobny etap „Test” po buildzie, przed approval i produkcją.
„Zatwierdzona wersja do testów integracyjnych” to zwykle alias Lambdy (np. test → wersja 8), z którego korzysta inny zespół, podczas gdy Ty publikujesz kolejne wersje. Po akceptacji przepinasz alias prod. Szczegóły aliasów: konfiguracja Lambdy; etapy i stage variables: API Gateway w praktyce.
Testowanie aplikacji sterowanych zdarzeniami
W architekturze zdarzeń wynik nie wraca do wywołującego: funkcja wrzuca wiadomość do kolejki, inna ją przetwarza, trzecia zapisuje do tabeli. Test musi więc wywołać zdarzenie i sprawdzić efekt uboczny w dalszym komponencie (wpis w tabeli, wiadomość w kolejce testowej, log).
- EventBridge archive + replay: archiwum zapisuje zdarzenia (wszystkie albo pasujące do wzorca, z czasem retencji). Replay wysyła zdarzenia z wybranego przedziału czasu ponownie na tę samą szynę, do wszystkich albo wybranych reguł. Zastosowania: odtworzenie błędu, test nowej wersji konsumenta prawdziwymi zdarzeniami. Archiwum może mieć opóźnienie, więc dokumentacja zaleca odczekać ok. 10 minut przed replay.
- Testowa reguła/kolejka nasłuchująca: dodatkowa reguła EventBridge albo subskrypcja SNS kierująca kopię zdarzeń do kolejki SQS w środowisku testowym; test czyta z niej i sprawdza, czy zdarzenie wyszło z poprawną treścią.
- DLQ / on-failure destinations: zdarzenia, których nie udało się przetworzyć, lądują w DLQ i można je zbadać i odtworzyć (redrive). Patrz SQS i zdarzenia Lambdy.
- Step Functions TestState API: testuje jeden stan (Task, Choice, Pass, Map, Parallel…) bez tworzenia maszyny stanów i bez wdrażania; może mockować odpowiedź usługi (wtedy rola IAM jest opcjonalna). Poziomy szczegółów (
inspectionLevel):INFO,DEBUG(przepływ danych przez InputPath/Parameters/ResultSelector/OutputPath),TRACE(żądanie i odpowiedź HTTP Task). - Step Functions Local jest według dokumentacji nieobsługiwany (unsupported, bez parytetu funkcji); AWS wskazuje zamiast niego TestState API. W starszych testach próbnych możesz spotkać „Step Functions Local” jako poprawną odpowiedź na „testuj workflow lokalnie”.
Amazon Q Developer
Amazon Q Developer to asystent AI (oparty na Amazon Bedrock) w IDE (VS Code, JetBrains, Visual Studio, Eclipse), w konsoli AWS i w terminalu. Na egzaminie kojarz go z: podpowiedziami kodu inline, czatem o kodzie i AWS, generowaniem testów jednostkowych, przeglądem kodu (security i jakość), generowaniem dokumentacji (README) i implementacją funkcji na podstawie opisu.
| Funkcja | Dawna nazwa w IDE | Co robi |
|---|---|---|
| Developing code features | /dev | Implementuje funkcję lub zmianę w projekcie na podstawie opisu, z kontekstem całego workspace |
| Unit test generation | /test | Generuje testy jednostkowe dla wskazanego kodu |
| Code reviews | /review | SAST (np. SQL injection, XSS, wycieki zasobów), wykrywanie sekretów w kodzie, problemy IaC, jakość kodu; reguły z Amazon Q detectors + generatywne AI |
| Documentation generation | /doc | Tworzy i aktualizuje README i inną dokumentację |
| Agentic coding | – | Domyślnie włączony w IDE: Q sam edytuje pliki (z podglądem diff i cofnięciem) i może uruchamiać polecenia powłoki |
| Transforming code | – | Automatyczne aktualizacje języka i systemu (np. wersji Javy) |
Stan na dziś według dokumentacji: funkcje /dev, /test, /doc, /review „used to be referred to” tymi komendami, teraz prosisz o nie w czacie (agentic coding). AWS zapowiedział koniec wsparcia wtyczek Amazon Q Developer do IDE 30 kwietnia 2027 i wskazuje Kiro jako następcę; „Q CLI” stało się „Kiro CLI”. Egzamin DVA-C02 wymienia Amazon Q Developer jako usługę w zakresie, a pytania (i starsze testy próbne) używają nazw /test, /review itd.: odpowiedź „użyj Amazon Q Developer do wygenerowania testów jednostkowych” pozostaje poprawna. Dostępny jest Free tier i subskrypcja Pro.
AWS CloudShell
Terminal w przeglądarce, uruchamiany z konsoli, z Twoimi uprawnieniami z konsoli (bez konfigurowania kluczy). Ma preinstalowane m.in. AWS CLI, SAM CLI, CDK, Docker i popularne języki. 1 GB trwałego miejsca w katalogu domowym na Region, bez opłat; dane z Regionu nieużywanego przez 120 dni są usuwane. Dobre do szybkich testów aws lambda invoke, sam remote invoke czy skryptów bez instalowania czegokolwiek lokalnie.
- Commit → CodeBuild uruchamia testy jednostkowe z mockami SDK (raport JUnit w CodeBuild reports).
- Wdrożenie na stos test (
sam deploy --config-env test). - Testy integracyjne w chmurze: czytają outputy stosu (URL API, nazwy kolejek), wysyłają żądania/zdarzenia i sprawdzają efekty w tabelach/kolejkach testowych.
- Manual approval → produkcja z canary (
DeploymentPreference) i hookiemPreTraffic, który robi smoke test nowej wersji. - Po incydencie: replay zdarzeń z archiwum EventBridge na środowisko testowe z poprawką.
- „Prywatne test events dla całego zespołu” – prywatne widzi tylko autor. Dla zespołu: shareable test events.
- „Frontend czeka na backend – postaw tymczasową Lambdę zwracającą stałe dane” – działa, ale najmniej pracy to API Gateway mock integration.
- „Testy integracyjne na produkcyjnym etapie API” – osobny etap/stos/konto testowe.
- „Odtwórz zdarzenia z CloudTrail” – do ponownego wysłania zdarzeń z szyny służy EventBridge archive + replay.
- „Step Functions Local to zalecany sposób testowania” – dziś nieobsługiwany; zalecane TestState API (lub testy w chmurze).
- „Amazon Q Developer wymaga osobnej komendy
/test” – dawniej tak; dziś prosisz w czacie. Na egzaminie liczy się, że Q Developer generuje testy i robi code review. - „
sam localwystarczy jako jedyny test” – lokalnie nie sprawdzisz uprawnień IAM ani prawdziwych integracji; potrzebne testy w chmurze.
Pięcioro programistów testuje tę samą funkcję Lambda w konsoli i chce używać wspólnego zestawu zdarzeń testowych. Najprostsze rozwiązanie?
konsola · wspólne zdarzenia · to samo konto
Odpowiedź
Shareable test events w konsoli Lambda.
Dlaczego nie: prywatne zdarzenia widzi tylko autor; trzymanie JSON-ów w S3 wymaga ręcznego kopiowania.
Zespół mobilny musi zacząć integrację z nowym endpointem REST, a backend będzie gotowy za trzy tygodnie. Jak udostępnić działający endpoint z przykładowymi odpowiedziami najmniejszym nakładem?
backend nie istnieje · przykładowe odpowiedzi · najmniej pracy
Odpowiedź
Metoda API Gateway z mock integration i zdefiniowaną odpowiedzią.
Dlaczego nie: Lambda ze stałą odpowiedzią to więcej kodu; statyczny plik w S3 nie odda metod i kodów odpowiedzi API.
Konsument zdarzeń EventBridge miał błąd przez dwie godziny i źle przetworzył zamówienia. Po poprawce trzeba przetworzyć te same zdarzenia jeszcze raz. Co powinno być skonfigurowane wcześniej?
te same zdarzenia · ponownie · EventBridge
Odpowiedź
Archiwum EventBridge na szynie; potem replay z przedziału tych dwóch godzin (do reguły konsumenta).
Dlaczego nie: DLQ zawiera tylko zdarzenia, których dostarczenie się nie udało, a tu dostarczenie się udało; CloudTrail nie wyśle zdarzeń ponownie.
Programista chce sprawdzić, czy stan Task w maszynie Step Functions poprawnie przekształca dane (ResultSelector, OutputPath), bez wdrażania całego workflow. Co użyć?
jeden stan · bez wdrażania · przepływ danych
Odpowiedź
TestState API z inspectionLevel: DEBUG (opcjonalnie z mockiem odpowiedzi usługi).
Dlaczego nie: Step Functions Local jest nieobsługiwany; uruchomienie całej maszyny wymaga wdrożenia.
Programista chce szybko wygenerować testy jednostkowe dla istniejącej klasy w IDE i sprawdzić kod pod kątem podatności. Które narzędzie AWS?
IDE · testy jednostkowe · podatności
Odpowiedź
Amazon Q Developer (generowanie testów jednostkowych i code review).
Dlaczego nie: CodeBuild uruchamia testy, ale ich nie pisze; X-Ray śledzi wywołania w działającej aplikacji.
🔬 Głębiej: drobiazgi
- TestState z mockiem nie wymaga roli IAM; bez mocka rola musi mieć uprawnienia do zasobów, które stan wywołuje.
TRACEdotyczy HTTP Task (opcjonalnie zrevealSecrets). - W API Gateway mock integration odpowiedź zależy od
statusCodezwróconego przez szablon mapowania integration request (np.{"statusCode": 200}), a body ustawiasz w integration response. - CloudShell w trybie VPC nie ma trwałego katalogu domowego; środowisko kończy się po 20–30 minutach bezczynności.
- Amazon Q Developer code review łączy generatywne AI z regułami (Amazon Q detectors, opisane w Amazon Q Detector Library).
- Unit (mocki SDK) → integration (w chmurze, osobny stos/etap/konto) → end-to-end. Testy w chmurze są najdokładniejsze.
- Zdarzenia: konsola Lambda (private do 10 / shareable w
lambda-testevent-schemas),sam local generate-event,sam remote invoke. - Mock API bez backendu: API Gateway mock integration. Mock SDK: Stubber / aws-sdk-client-mock.
- Zdarzenia ponownie: EventBridge archive + replay. Step Functions: TestState API (Local jest nieobsługiwany).
- Amazon Q Developer: testy jednostkowe, code review (SAST, sekrety, IaC), dokumentacja, implementacja; dawne
/test,/review,/doc,/dev. - CloudShell: terminal z CLI/SAM/CDK w przeglądarce, 1 GB na Region, 120 dni.
Obserwowalność, troubleshooting i optymalizacja
Domena 4 egzaminu (18% punktów): jak zobaczyć, co robi Twoja aplikacja, i jak szybko znaleźć przyczynę, gdy coś pęknie. Metryki i alarmy CloudWatch, logi i zapytania Logs Insights, ślady X-Ray, a na koniec atlas błędów: objaw → przyczyna → naprawa. Po tej części rozpoznasz, czy pytanie dotyczy liczby (metryka), zdarzenia (log), drogi żądania (trace) czy audytu (CloudTrail).
CloudWatch: metryki, alarmy i dashboardy
namespace, wymiary, rozdzielczość, EMF, M z N, brakujące daneMetryka to jak licznik w samochodzie: co chwilę zapisujesz jedną liczbę z godziną (data point), a potem patrzysz na wykres. CloudWatch przechowuje takie szeregi czasowe. Każda metryka ma nazwę (CPUUtilization), namespace (szufladę, np. AWS/EC2 albo Twoje MyApp/Orders) i zero lub więcej wymiarów (dimensions, pary nazwa=wartość, np. InstanceId=i-0abc).
Ważna konsekwencja: każda unikalna kombinacja wymiarów to osobna metryka. Orders z Env=prod i Orders z Env=prod, Region=eu to dwa różne szeregi. Statystyki pobierzesz tylko dla kombinacji, które faktycznie opublikowałeś. CloudWatch sam nie „zsumuje” ich za Ciebie (wyjątkiem są niektóre metryki usług AWS, np. EC2).
Alarm to strażnik, który co okres (period) patrzy na statystykę metryki i porównuje ją z progiem. Ma trzy stany: OK, ALARM i INSUFFICIENT_DATA (za mało danych, żeby ocenić). Akcje (SNS, Auto Scaling, EC2, Lambda, Systems Manager) odpalają się przy zmianie stanu; wyjątek: akcje Auto Scaling powtarzają się, dopóki alarm trwa w ALARM.
4.1.44.1.54.2.34.2.54.1.2
- EC2 nie raportuje pamięci RAM ani zajętości dysku. Te dane zbiera CloudWatch agent (
mem_used_percent,disk_used_percent), a rola instancji potrzebujeCloudWatchAgentServerPolicy. - Basic monitoring EC2: metryki co 5 minut, za darmo (status checks co 1 min). Detailed monitoring: co 1 minutę, płatne (
aws ec2 monitor-instances). - Własna metryka:
PutMetricData(uprawnieniecloudwatch:PutMetricData). High-resolution =StorageResolution=1(dane co 1 s, alarm co 10 lub 30 s). Domyślnie60(standard). Wysoka rozdzielczość jest tylko dla metryk własnych. - Embedded Metric Format (EMF): wypisujesz JSON z blokiem
_aws.CloudWatchMetricsdo logów, a CloudWatch sam wyciąga metryki. Asynchronicznie, bez wywołań API w kodzie, wystarczylogs:PutLogEvents. Idealne dla Lambdy i kontenerów. - Alarm M z N:
DatapointsToAlarm(M) zEvaluationPeriods(N). Punkty nie muszą być kolejne. Brakujące dane:TreatMissingData=missing(domyślnie),notBreaching,breaching,ignore. - Composite alarm łączy alarmy regułą
AND/OR/NOTi redukuje szum. Może wysłać SNS, wywołać Lambdę, utworzyć OpsItem/incydent w Systems Manager, ale nie wykona akcji EC2 ani Auto Scaling. - Percentyle (
p99) zamiast średniej, gdy pytają o „najwolniejsze 1% żądań” lub opóźnienia odczuwane przez użytkowników. - Powiadomienie o zbliżaniu się do limitu → alarm CloudWatch z konsoli Service Quotas. Powiadomienie o zakończeniu wdrożenia → reguła EventBridge (np.
CodeDeploy Deployment State-change Notification) → SNS.
missing/ignore rozstrzyga też po liczbie dostępnych punktów. Wartości metryk, progi i liczba okresów są ilustracyjne.Metryki: rozdzielczość, retencja i statystyki
Metryki żyją w jednym Regionie i nie da się ich usunąć. Wygasają same po 15 miesiącach bez nowych danych. Im starsze dane, tym grubsze ziarno (dane są agregowane do dłuższych okresów):
| Okres punktu | Dostępny przez | Uwagi |
|---|---|---|
| < 60 s (high-resolution) | 3 godziny | tylko metryki własne z StorageResolution=1 |
| 60 s (1 min) | 15 dni | potem dostępne jako 5-minutowe |
| 300 s (5 min) | 63 dni | potem jako 1-godzinne |
| 3600 s (1 h) | 455 dni (15 miesięcy) | najdłuższa retencja |
| Statystyka | Co liczy | Kiedy |
|---|---|---|
Sum, SampleCount | suma wartości / liczba punktów w okresie | liczniki: żądania, błędy, zamówienia |
Average | Sum/SampleCount | CPU, wykorzystanie; ukrywa wartości skrajne |
Minimum, Maximum | skrajne wartości w okresie | szczyty, np. IteratorAge Maximum |
Percentyl p95, p99 | 95% danych jest poniżej tej wartości | opóźnienia (latency) odczuwane przez użytkowników |
Trimmed mean TM(10%:90%), IQM, WM | średnia bez wartości odstających | „stabilna średnia bez pojedynczych pików” |
PutMetricData w praktyce
aws cloudwatch put-metric-data --namespace "MyApp/Orders" \
--metric-name OrdersPlaced --unit Count --value 3 \
--dimensions Env=prod,Channel=web --storage-resolution 1
- Do 30 wymiarów na metrykę, do 1000 metryk w jednym wywołaniu, żądanie do 1 MB (można wysłać gzip).
- Znacznik czasu: do 2 tygodni wstecz i do 2 godzin w przód względem bieżącego czasu.
- Values + Counts: do 150 unikalnych wartości z licznikami w jednym datum. Tak publikujesz wiele pomiarów naraz i nadal masz percentyle.
- Każde wywołanie
PutMetricDatakosztuje. Przy wysokiej rozdzielczości i dużym ruchu agreguj lokalnie albo użyj EMF. Limit API: 500 żądań/s na Region (podnoszalny). - Jednostka (
Unit) jest częścią danych: te same metryki z różnymi jednostkami agregują się osobno.
Embedded Metric Format i Powertools
EMF to „metryka przemycona w logu”. Lambda i tak wysyła logi do CloudWatch Logs, więc dopisujesz do linii JSON metadane, a usługa wyciąga z nich metryki. Kod nie czeka na wywołanie API i nie potrzebuje cloudwatch:PutMetricData.
{
"_aws": {
"Timestamp": 1735689600000,
"CloudWatchMetrics": [{
"Namespace": "MyApp/Orders",
"Dimensions": [["Service", "Env"]],
"Metrics": [{ "Name": "OrderValue", "Unit": "None" }]
}]
},
"Service": "checkout", "Env": "prod",
"OrderValue": 129.90,
"orderId": "o-123", "customerTier": "gold"
}
Timestampw milisekundach od epoki, zestaw wymiarów (DimensionSet) maks. 30 kluczy. Pola spoza metryk (orderId) zostają w logu i przydadzą się w Logs Insights (wysoka kardynalność bez kosztu metryk).- Biblioteki klienckie EMF: Node.js, Python, Java. Powertools for AWS Lambda – Metrics buforuje do 100 metryk w jednym obiekcie EMF i flushuje je na końcu wywołania (dekorator
@metrics.log_metrics). Namespace ustawisz zmiennąPOWERTOOLS_METRICS_NAMESPACE.
Metryki Lambdy, które musisz znać
| Metryka | Co mierzy | Pytanie egzaminacyjne |
|---|---|---|
Invocations | wywołania kodu (udane i z błędem); nie liczy throttlowanych | „ile razy funkcja ruszyła” |
Errors | wywołania zakończone błędem funkcji (wyjątek, timeout) | alarm na odsetek błędów: metric math Errors/Invocations |
Throttles | żądania odrzucone z TooManyRequestsException | brak współbieżności → reserved/provisioned concurrency, limit konta |
Duration | czas działania kodu (ms) | zbliża się do timeoutu? → p99 Duration |
ConcurrentExecutions | instancje obsługujące zdarzenia naraz | blisko limitu konta lub reserved concurrency |
IteratorAge | wiek ostatniego rekordu (Kinesis, DynamoDB Streams) | rośnie → konsument nie nadąża |
AsyncEventAge, AsyncEventsDropped | czas w wewnętrznej kolejce, zdarzenia porzucone | wywołania asynchroniczne: ponowienia, throttling |
DeadLetterErrors, DestinationDeliveryFailures | nieudane wysłanie do DLQ / destination | „zdarzenia giną mimo DLQ” → uprawnienia, rozmiar |
ProvisionedConcurrencySpilloverInvocations | wywołania poza provisioned concurrency | za mało PC → cold starty wracają |
Alarmy: okres, ewaluacja, brakujące dane, akcje
Alarm ocenia okno Period × EvaluationPeriods. Okno może trwać maksymalnie 1 dzień (dla okresów krótszych niż godzina) albo 7 dni (dla okresów ≥ 1 h). „3 z 5 po 1 min” znaczy: w ostatnich 5 minutach co najmniej 3 punkty przekroczyły próg.
| TreatMissingData | Co robi z dziurą | Kiedy |
|---|---|---|
missing (domyślnie) | jeśli w oknie brak wszystkich punktów → INSUFFICIENT_DATA | uniwersalnie |
notBreaching | dziura = „dobrze” | metryki rzadkie: Errors, liczba nieudanych logowań |
breaching | dziura = „źle” | heartbeat: brak danych oznacza, że coś padło |
ignore | zachowaj obecny stan | nie chcesz przełączeń przez dziury (domyślne dla AWS/DynamoDB) |
| Akcja alarmu | Co robi | Uwagi |
|---|---|---|
| SNS | e-mail, SMS, Lambda, SQS, HTTP | każdy stan; także composite |
| Lambda (bezpośrednio) | własna automatyzacja | „najprostszy sposób na własną reakcję” |
| EC2 action | stop, terminate, reboot, recover | tylko alarmy na metrykach EC2; nie composite |
| Auto Scaling | step/simple scaling policy | jedyna akcja powtarzana, dopóki alarm pozostaje w ALARM |
| Systems Manager | OpsItem (OpsCenter), incydent (Incident Manager) | tylko przy przejściu w ALARM |
- Metric math: nowe szeregi z wyrażeń, np.
100*Errors/Invocations. Alarm może patrzeć na wyrażenie. Pobierasz je przezGetMetricData. - Anomaly detection: model ML wyznacza pasmo oczekiwanych wartości (z sezonowością), alarm reaguje na wyjście powyżej, poniżej lub poza pasmo. Funkcja
ANOMALY_DETECTION_BAND. Dobre, gdy „normalny” poziom zmienia się w ciągu dnia i stały próg nie działa. - Composite alarm: np.
ALARM(HighCPU) AND ALARM(High5xx). Powiadamiasz tylko z composite, a alarmy składowe zostawiasz bez akcji. Tak gasisz „burzę alertów”.
Dashboardy, Synthetics i „Insights”
| Narzędzie | Co robi | Kiedy w pytaniu |
|---|---|---|
| Dashboards | wykresy metryk, alarmów, zapytań Logs Insights; wiele Regionów, a z cross-account observability także wiele kont | „jeden widok zdrowia aplikacji dla zespołu” |
| Synthetics canaries | skrypty Node.js/Python/Java uruchamiane wg harmonogramu (jako Lambda), headless przeglądarka, zrzuty ekranu | „wykryj awarię endpointu, zanim zgłoszą ją klienci”, „monitoruj ścieżkę użytkownika” |
| Application Signals | automatyczne metryki i ślady (wolumen, dostępność, latency, błędy) dla EC2/ECS/EKS/Lambda, SLO | „APM”, „SLO”, „bez ręcznej instrumentacji” |
| Container Insights | CPU, pamięć, dysk, sieć, restarty dla ECS, EKS, Kubernetes | „metryki na poziomie tasku/poda” |
| Lambda Insights | rozszerzenie (layer) zbiera CPU, pamięć, sieć, cold starty; dane przez EMF | „systemowe metryki Lambdy, wycieki pamięci” |
| Contributor Insights | „top N” kontrybutorów z logów (np. IP z największą liczbą błędów) | „który klient generuje najwięcej 5xx” |
Powiadomienia o limitach i wdrożeniach (4.2.5)
- Limity (quotas): w konsoli Service Quotas wybierasz limit wspierający alarmy i tworzysz alarm CloudWatch z progiem (np. 80% wykorzystania). Dane pochodzą z metryk użycia (namespace
AWS/Usage). Trusted Advisor też ma kategorię kontroli „service limits”. - Wdrożenia: CodeDeploy, CodePipeline i CloudFormation publikują zdarzenia w EventBridge. Reguła z
"detail-type": "CodeDeploy Deployment State-change Notification"i"state": "SUCCESS"lub"FAILURE"→ cel SNS. Dla potoku:CodePipeline Pipeline Execution State Change. Szczegóły w EventBridge i CodeDeploy. - Zmiana stanu alarmu też jest zdarzeniem (
CloudWatch Alarm State Change), więc możesz przekierować je przez EventBridge do dowolnego celu.
{
"source": ["aws.codedeploy"],
"detail-type": ["CodeDeploy Deployment State-change Notification"],
"detail": { "state": ["FAILURE"] }
}
- „Włącz detailed monitoring, żeby widzieć pamięć EC2” — kusi, bo „detailed” brzmi jak „więcej metryk”. Detailed zmienia tylko częstotliwość (1 min). Pamięć i dysk daje wyłącznie CloudWatch agent.
- High-resolution dla metryk AWS — metryki usług AWS są standardowe.
StorageResolution=1działa tylko dla metryk własnych. - Composite alarm ze stop/terminate EC2 albo skalowaniem — composite wysyła SNS, wywołuje Lambdę i tworzy OpsItem/incydent, ale akcji EC2 i Auto Scaling nie wykona.
breachingna rzadkiej metryce —Errorsnie pojawia się, gdy nie ma wywołań. Dziura liczona jako „źle” daje fałszywe alarmy w nocy. Dla takich metryk wybierznotBreaching.- Alarm, który „nie wysłał drugiego maila” — to nie błąd. Akcje (poza Auto Scaling) odpalają się przy zmianie stanu; wyjątek: akcje Auto Scaling powtarzają się, dopóki alarm trwa w ALARM.
PutMetricDataw każdej iteracji pętli w Lambdzie — wolne, drogie i grozi throttlingiem API. Lepiej EMF albo batch (wiele datum / Values+Counts w jednym wywołaniu).- Średnia zamiast percentyla — średnie latency 120 ms może ukrywać p99 = 4 s. Pytanie o „najgorsze doświadczenia użytkowników” →
p99.
Zespół chce alarmu, gdy wykorzystanie pamięci na flocie EC2 przekroczy 80%. W konsoli CloudWatch nie ma takiej metryki w AWS/EC2. Co zrobić?
pamięć EC2, brak metryki
Odpowiedź
Zainstalować CloudWatch agent (konfiguracja np. w Parameter Store), rola instancji z CloudWatchAgentServerPolicy, alarm na mem_used_percent w namespace agenta (domyślnie CWAgent).
Dlaczego nie: detailed monitoring tylko zagęszcza istniejące metryki; własny skrypt z PutMetricData działa, ale to więcej pracy niż agent.
Funkcja Lambda ma raportować wartość koszyka per klient (tysiące identyfikatorów) i biznesową metrykę OrderValue, bez dodawania opóźnienia do wywołania i z możliwie najmniejszym kodem.
bez opóźnienia, ephemeral, metryka z logów
Odpowiedź
Embedded Metric Format (np. Powertools Metrics): metryka OrderValue z niskokardynalnymi wymiarami (Service, Env), a customerId jako zwykłe pole logu do zapytań Logs Insights.
Dlaczego nie: PutMetricData synchronicznie dodaje opóźnienie; customerId jako wymiar tworzy tysiące płatnych metryk.
Alarm na CPU ma reagować na pojedyncze skoki, ale nie na jeden przypadkowy pik. Wymaganie: ALARM, gdy w ciągu 5 minut co najmniej 3 jednominutowe punkty przekroczą 90%.
3 z 5, nie muszą być kolejne
Odpowiedź
Period 60 s, EvaluationPeriods 5, DatapointsToAlarm 3 (alarm „M z N”). Na metrykach EC2 potrzebujesz detailed monitoring, bo basic daje punkty co 5 min.
Dlaczego nie: EvaluationPeriods 3 wymagałoby 3 przekroczeń z rzędu w 3 minutach.
Zespół dostaje dziesiątki maili, gdy jedna awaria bazy wyzwala alarmy CPU, latency i 5xx. Chce jednego powiadomienia, gdy jednocześnie rosną 5xx i latency.
reduce alarm noise, AND
Odpowiedź
Composite alarm ALARM(5xx) AND ALARM(Latency) z akcją SNS; alarmy składowe bez akcji.
Dlaczego nie: anomaly detection nie łączy alarmów; metric math łączy metryki, ale nie stany istniejących alarmów.
Programista chce dostać e-mail, gdy liczba współbieżnych wykonań Lambdy w koncie zbliży się do limitu Regionu, oraz drugi e-mail po każdym nieudanym wdrożeniu CodeDeploy.
quota usage alarm, deployment completion notification
Odpowiedź
(1) Alarm CloudWatch na metryce wykorzystania limitu (utworzony z konsoli Service Quotas) → SNS. (2) Reguła EventBridge na CodeDeploy Deployment State-change Notification ze stanem FAILURE → temat SNS (albo trigger/notification rule w CodeDeploy).
Dlaczego nie: CloudTrail rejestruje wywołania API, ale nie daje gotowego powiadomienia o progu limitu.
Strona sklepu „działa” według metryk serwera, ale klienci zgłaszają, że koszyk nie przechodzi do płatności. Jak wykrywać to proaktywnie co 5 minut?
proactive, user journey, endpoint
Odpowiedź
CloudWatch Synthetics canary z przeglądarką headless, która przechodzi ścieżkę koszyk → płatność, plus alarm na metryce sukcesu canary.
Dlaczego nie: alarmy na CPU/5xx nie widzą błędów logiki po stronie przeglądarki.
🔬 Głębiej: rzadziej testowane szczegóły
- Alarmy typu high-resolution (okres 10 lub 30 s) kosztują więcej; alarm na metryce high-res może też mieć zwykły okres będący wielokrotnością 60 s.
- Domyślnie alarm używa przesuwanego okna (sliding). Przy brakujących danych CloudWatch może pobrać dodatkowe, starsze punkty, żeby ocenić okno. Dlatego realne przejścia stanów bywają mniej „szkolne” niż w symulacji powyżej.
- Alarm może obserwować metryki z innych kont (cross-account observability), ale composite alarmów cross-account tworzyć nie można.
- Metric Streams wysyłają metryki w niemal real-time przez Data Firehose (np. do S3 lub zewnętrznego APM). Metrics Insights to zapytania SQL po metrykach.
- CloudWatch agent zbiera także własne metryki przez protokoły
StatsD(Linux i Windows) orazcollectd(tylko Linux), a także logi z plików (logs_collected). - Limity: 500 canaries na Region (domyślnie), 200 alarmów Metrics Insights.
- Metryka = namespace + nazwa + wymiary; każda kombinacja wymiarów to osobny szereg. Metryk nie usuniesz, wygasają po 15 miesiącach.
- EC2: 5 min (basic, free) vs 1 min (detailed); pamięć i dysk tylko przez CloudWatch agent.
- Własne metryki:
PutMetricData(StorageResolution 1 = high-res) albo EMF w logach (asynchronicznie, bez opóźnienia). - Alarm: Period × EvaluationPeriods, M z N, TreatMissingData (domyślnie
missing); akcje przy zmianie stanu (poza Auto Scaling). - Composite = mniej szumu (bez akcji EC2/ASG). Anomaly detection = próg zmienny w czasie. Synthetics = test z perspektywy klienta.
- Limity → alarm z Service Quotas; wdrożenia → EventBridge → SNS.
Logi, zapytania i audyt
log groups, retencja, filtry, Logs Insights, JSON, Lambda, CloudTrailLog to dziennik pokładowy aplikacji: co się stało, kiedy i z jakimi szczegółami. Metryka mówi „błędów jest 40 na minutę”, a log mówi „zamówienie o-123 padło, bo karta została odrzucona”. W CloudWatch Logs każdy wpis to log event (znacznik czasu + treść). Wpisy z jednego źródła (np. jednej instancji Lambdy) trafiają do log stream, a strumienie grupujesz w log group, która ma wspólną retencję, szyfrowanie, filtry i uprawnienia.
Trzy słowa, które egzamin rozróżnia (4.2.1): logowanie to zapisywanie zdarzeń, monitorowanie to obserwowanie znanych wskaźników i alarmowanie (metryki, alarmy), a obserwowalność (observability) to zdolność odpowiedzenia na pytania, których wcześniej nie przewidziałeś. Daje ją połączenie logów, metryk i śladów (traces) z wspólnymi identyfikatorami.
Osobny świat to CloudTrail: rejestr wywołań API na koncie, czyli „kto, co, kiedy i skąd zrobił w AWS”. Logi aplikacji odpowiadają na pytanie „co robi mój kod”, a CloudTrail na pytanie „kto usunął tę tabelę”.
4.1.34.2.14.2.24.2.74.3.94.1.2
- Domyślna retencja log group: bez wygasania (dane przechowywane bezterminowo). Koszty rosną → ustaw retencję (
PutRetentionPolicy, od 1 dnia do 10 lat). - Metric filter zamienia wzorzec w logach na metrykę (np. liczba „ERROR”), na której stawiasz alarm. Nie działa wstecz: liczy tylko zdarzenia po utworzeniu filtra.
- Subscription filter = strumień logów w czasie (prawie) rzeczywistym do Kinesis Data Streams, Data Firehose, Lambdy albo OpenSearch. Limit: 5 subscription filters na log group. Eksport do S3 (
CreateExportTask) nie jest real-time: dane dostępne do eksportu nawet po 12 h. - Logs Insights:
fields,filter,stats,sort,limit,parse. Dla Lambdy:filter @type = "REPORT"i pola@duration,@billedDuration,@maxMemoryUsed,@memorySize,@requestId. - Lambda pisze logi, jeśli rola wykonawcza ma
logs:CreateLogGroup,logs:CreateLogStream,logs:PutLogEvents(politykaAWSLambdaBasicExecutionRole). Brak logów = najczęściej brak tych uprawnień. Domyślna grupa:/aws/lambda/<nazwa-funkcji>. - Structured logging: logi w JSON z polami (
level,requestId,correlationId,orderId). Lambda ma wbudowany format JSON i filtrowanie poziomów (advanced logging controls). Powertools Logger dodaje kontekst Lambdy i correlation ID. - Szyfrowanie log group kluczem KMS: tylko klucz symetryczny, polityka klucza musi wpuścić usługę CloudWatch Logs; szyfrowane są dane przyjęte po powiązaniu klucza.
- CloudTrail: Event history = 90 dni zdarzeń zarządczych za darmo. Dłużej, data events (S3
GetObject, LambdaInvoke) albo wysyłka do S3/CloudWatch Logs → utwórz trail. CloudTrail Insights = nietypowa liczba wywołań API/błędów. CloudTrail Lake = zapytania SQL.
-- wybierz zapytanie
| – |
Log groups, retencja, szyfrowanie, klasy
- Retencja: domyślnie bezterminowo. Dozwolone wartości (dni): 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1096, 1827, 2192, 2557, 2922, 3288, 3653. Starsze zdarzenia usuwane są automatycznie.
- Szyfrowanie: dane w CloudWatch Logs są zawsze szyfrowane (AES-GCM). Własny klucz KMS:
aws logs associate-kms-keylub przy tworzeniu grupy. Klucz musi być symetryczny, a jego polityka musi pozwalać usłudzelogs.<region>.amazonaws.comna użycie klucza. Kontekst szyfrowania:kms:EncryptionContext:aws:logs:arn. - Deletion protection (domyślnie wyłączona) chroni log group przed usunięciem. Data protection (maskowanie danych wrażliwych, np. numerów kart) działa w obu klasach logów (szczegóły i
logs:Unmaskw ochronie danych). - Limity: pojedyncze zdarzenie do 1 024 KB, batch
PutLogEventsdo 1 MB,PutLogEvents5000 TPS na Region (podnoszalne), 1 aktywny eksport do S3 na konto, 100 metric filters i 5 subscription filters na log group.
| Klasa logów | Co ma | Kiedy |
|---|---|---|
| Standard | wszystko: Live Tail, metric filters, subscription filters, EMF, anomaly detection, GetLogEvents/FilterLogEvents | logi operacyjne, alarmy, real-time |
| Infrequent Access | tańsze przyjmowanie (ingestion); brak Live Tail, metric/subscription filters i EMF; odczyt przez Logs Insights | logi „na wszelki wypadek”, audyt, rzadkie analizy |
| Delivery | tylko do przekazania logów Lambdy do S3/Firehose; w CloudWatch zostają 2 dni | tanie przekierowanie logów |
Klasy log group nie zmienisz po utworzeniu. Klasy różnią się tylko ceną przyjmowania danych; przechowywanie i Logs Insights kosztują tyle samo.
Metric filters, subscription filters, eksport
| Mechanizm | Co robi | Kiedy |
|---|---|---|
| Metric filter | wzorzec → metryka (np. +1 za każde ERROR), do 3 wymiarów (tylko wzorce JSON/space-delimited) | alarm na treści logów: „5 błędów płatności w 5 min” |
| Subscription filter | dopasowane zdarzenia w czasie rzeczywistym do Kinesis Data Streams, Firehose, Lambdy, OpenSearch (base64 + gzip) | centralny SIEM, archiwum w S3 przez Firehose, reakcja na zdarzenie |
| Export to S3 | jednorazowe, asynchroniczne zadanie eksportu zakresu czasu; dane do 12 h opóźnienia, timeout zadania 24 h | okazjonalny zrzut do analizy; nie do ciągłej archiwizacji |
| Live Tail | podgląd napływających logów na żywo, z filtrem i podświetleniem; płatne za minutę sesji | debugowanie „tu i teraz” po wdrożeniu |
| Logs Insights | interaktywne zapytania po historii logów | analiza, wąskie gardła, raporty |
# metric filter: licz błędy płatności z logów JSON
aws logs put-metric-filter --log-group-name /aws/lambda/checkout \
--filter-name PaymentErrors \
--filter-pattern '{ $.level = "ERROR" && $.errorType = "PaymentDeclined" }' \
--metric-transformations metricName=PaymentErrors,metricNamespace=MyApp,metricValue=1,defaultValue=0
Logs Insights: składnia, którą trzeba umieć przeczytać
| Komenda | Co robi | Przykład |
|---|---|---|
fields | wybiera pola do wyniku | fields @timestamp, @message, @logStream |
filter | warunek (=, !=, <, like /regex/, in) | filter level = "ERROR" and @message like /timeout/ |
stats | agregacja: count, sum, avg, min, max, pct; grupowanie by, bin(5m) | stats count(*) by errorType |
sort, limit | kolejność, liczba wierszy | sort @timestamp desc | limit 20 |
parse | wyciąga pola z nieustrukturyzowanego tekstu (glob * lub regex) | parse @message "orderId=* " as orderId |
dedup, pattern, display | usuwa duplikaty, grupuje podobne komunikaty, pokazuje pola | pattern @message |
# najwolniejsze wywołania i nadmiar pamięci (Lambda)
filter @type = "REPORT"
| stats avg(@duration), max(@duration), pct(@duration, 99),
max(@maxMemoryUsed / 1000 / 1000) as maxMemMB,
max(@memorySize / 1000 / 1000) as configuredMB
by bin(5m)
# JSON: pola wykrywane automatycznie (także zagnieżdżone: user.id)
fields @timestamp, level, orderId, correlationId
| filter level = "ERROR"
| sort @timestamp desc | limit 50
- Pola systemowe:
@timestamp,@message,@logStream,@log,@ingestionTime. Dla logów JSON pola wykrywane są automatycznie. - Zapytanie działa maks. 60 minut, wyniki dostępne 7 dni. Poza składnią Logs Insights QL konsola obsługuje też OpenSearch PPL i SQL. Zapytania możesz zapisywać i dodawać do dashboardów.
Logowanie w Lambdzie (advanced logging controls)
| Ustawienie | Wartości | Uwagi |
|---|---|---|
LogFormat | Text (domyślnie) / JSON | JSON: Lambda opakowuje logi w obiekty JSON (timestamp, level, requestId) |
ApplicationLogLevel | TRACE, DEBUG, INFO (domyślnie), WARN, ERROR, FATAL | wymaga JSON; logi poniżej poziomu nie trafiają do CloudWatch |
SystemLogLevel | DEBUG, INFO (domyślnie), WARN | logi platformy: START, REPORT… |
LogGroup | dowolna istniejąca/nowa grupa | kilka funkcji do jednej grupy; przez CLI dopisz logs:PutLogEvents sam |
aws lambda update-function-configuration --function-name checkout \
--logging-config LogFormat=JSON,ApplicationLogLevel=WARN,SystemLogLevel=INFO,LogGroup=/shop/prod
REPORT RequestId: 8f50… Duration: 15.74 ms Billed Duration: 147 ms
Memory Size: 128 MB Max Memory Used: 56 MB Init Duration: 130.49 ms
Linia REPORT to złoto do optymalizacji: Init Duration pojawia się tylko przy zimnym starcie, a Max Memory Used blisko Memory Size oznacza ryzyko braku pamięci. Gdy funkcja ma włączone śledzenie, dochodzi linia XRAY TraceId, która łączy log ze śladem.
Strategia logowania i structured logging (4.2.2, 4.2.7)
- JSON zamiast tekstu: pola filtrujesz w Logs Insights i metric filters bez
parse. - Correlation ID: ten sam identyfikator (np. z nagłówka żądania lub
X-Amzn-Trace-Id) w każdym logu każdej usługi. Dzięki temu jednym zapytaniem odtworzysz drogę żądania przez kilka funkcji. - Poziomy: DEBUG wyłączony na produkcji (koszty), ERROR zawsze z kontekstem (identyfikatory, nie dane osobowe ani sekrety).
- Zdarzenia biznesowe i akcje użytkowników (logowanie, zakup) jako osobne, ustrukturyzowane wpisy z
userIdi typem zdarzenia. - Powertools Logger:
@logger.inject_lambda_contextdodaje request ID, cold start, nazwę funkcji;set_correlation_id; nazwa serwisu zPOWERTOOLS_SERVICE_NAME. - Na EC2 i on-premises logi z plików wysyła CloudWatch agent (sekcja
logs_collectedw konfiguracji JSON; konfigurację możesz trzymać w SSM Parameter Store).
from aws_lambda_powertools import Logger
logger = Logger() # service z POWERTOOLS_SERVICE_NAME
@logger.inject_lambda_context(correlation_id_path="headers.x-correlation-id")
def handler(event, context):
logger.info("order placed", extra={"orderId": event["orderId"]})
CloudTrail i AWS Config
| Element | Co daje | Kiedy |
|---|---|---|
| Event history | 90 dni management events per Region, włączone domyślnie, bez konfiguracji | „kto wczoraj zmienił security group” |
| Trail | ciągła dostawa zdarzeń do S3 (opcjonalnie do CloudWatch Logs, średnio ok. 5 min opóźnienia); multi-Region, organization trail | retencja > 90 dni, alarmy na wywołaniach API |
| Data events | operacje na danych: S3 GetObject/PutObject/DeleteObject, Lambda Invoke, DynamoDB itd.; domyślnie wyłączone, płatne, duży wolumen | „kto pobrał ten obiekt z S3” |
| Insights events | wykrywa nietypowy wolumen wywołań API lub odsetek błędów | „nagły wzrost TerminateInstances” |
| CloudTrail Lake | event data stores + zapytania SQL | analiza zdarzeń SQL-em bez Athena |
| Log file integrity validation | pliki digest (SHA-256) co godzinę | „udowodnij, że logów nie zmieniono” |
Config vs CloudTrail w jednym zdaniu: CloudTrail mówi kto wywołał jakie API, a AWS Config mówi jak wyglądała konfiguracja zasobu w czasie i czy jest zgodna z regułami.
- „Metric filter policzy błędy z zeszłego tygodnia” — nie. Filtry nie działają wstecz. Historię przeanalizujesz w Logs Insights.
- Eksport do S3 jako „real-time” — eksport jest asynchroniczny i opóźniony (do 12 h). Ciągła dostawa → subscription filter + Firehose → S3.
- „Do log group może być tylko 1 (albo 2) subscription filtry” — w starszych testach próbnych spotkasz limit 1 filtra, a po zmianie z 2020 r. 2 filtrów. Aktualna dokumentacja podaje 5 na log group (limit nienegocjowalny).
- Rozmiar zdarzenia 256 KB — starsze materiały podają 256 KB na zdarzenie (limit podniesiono w kwietniu 2025). Aktualnie tabela limitów podaje 1 024 KB (batch nadal 1 MB).
- Asymetryczny klucz KMS do log group — CloudWatch Logs wspiera tylko klucze symetryczne. Brak wpisu dla usługi Logs w polityce klucza = błąd przy powiązaniu.
- Brak logów Lambdy → „włącz logowanie w konsoli” — Lambda loguje zawsze, jeśli rola ma uprawnienia
logs:*zAWSLambdaBasicExecutionRole. Zwykle winna jest rola. - Filtrowanie poziomów logów przy formacie Text —
ApplicationLogLeveldziała tylko zLogFormat=JSON. - CloudTrail do pytania „kto czytał obiekt S3” bez data events — management events nie obejmują
GetObject. Trzeba włączyć data events w trailu. - Live Tail / metric filter na klasie Infrequent Access — niedostępne; ta klasa jest tańsza właśnie dlatego.
UpdateFunctionCode, a jako data event także Invoke), nie wnętrze Twojego kodu. Wyjątki znajdziesz w CloudWatch Logs, a drogę żądania w X-Ray.Programista musi znaleźć 20 najwolniejszych wywołań funkcji Lambda z ostatnich 3 dni wraz z ich request ID, bez pisania kodu.
query logs, slowest, Lambda
Odpowiedź
CloudWatch Logs Insights: filter @type = "REPORT" | fields @requestId, @duration | sort @duration desc | limit 20.
Dlaczego nie: metryka Duration da statystyki, ale nie request ID; eksport do S3 + Athena to więcej pracy i opóźnienie.
Firma chce, aby każdy log z aplikacji trafiał w ciągu sekund do zewnętrznego systemu SIEM przez Amazon Data Firehose.
near real time, stream logs
Odpowiedź
Subscription filter na log group z celem Firehose (log group w klasie Standard).
Dlaczego nie: CreateExportTask do S3 jest jednorazowy i opóźniony do 12 h; metric filter tworzy tylko metrykę.
Zespół dodał metric filter na „PaymentDeclined” i alarm. Wczoraj wieczorem było 200 odmów, ale wykres metryki jest pusty dla wczorajszego dnia.
metric filter, historical data
Odpowiedź
Metric filters nie przetwarzają danych wstecz. Liczą tylko zdarzenia po utworzeniu filtra. Historię policz w Logs Insights (stats count(*) by bin(1h)).
Audytor wymaga, aby logi aplikacji były szyfrowane kluczem zarządzanym przez klienta i przechowywane dokładnie 1 rok, a potem usuwane.
customer managed key, retention
Odpowiedź
Symetryczny klucz KMS z polityką pozwalającą CloudWatch Logs + associate-kms-key (lub kmsKeyId przy tworzeniu), oraz retencja 365 dni na log group.
Dlaczego nie: domyślnie logi nigdy nie wygasają; S3 lifecycle dotyczy obiektów w S3, nie log groups.
Ktoś usunął tabelę DynamoDB w produkcji przedwczoraj. Jak najszybciej ustalić, kto to zrobił?
who deleted, API call, last 90 days
Odpowiedź
CloudTrail Event history: filtr po nazwie zdarzenia DeleteTable. Zawiera tożsamość wywołującego, IP i czas. Działa bez wcześniejszej konfiguracji przez 90 dni.
Dlaczego nie: AWS Config pokaże zmianę konfiguracji, ale pytanie „kto” rozstrzyga CloudTrail; logi CloudWatch aplikacji nie widzą wywołań konsoli.
Funkcja Lambda zalewa logi komunikatami DEBUG, co podnosi koszty. Programista chce bez zmiany kodu wysyłać do CloudWatch tylko WARN i wyżej.
log level filtering, no code change
Odpowiedź
Advanced logging controls: LogFormat=JSON i ApplicationLogLevel=WARN w konfiguracji funkcji.
Dlaczego nie: krótsza retencja nie zmniejsza kosztu przyjmowania logów; subscription filter nie blokuje zapisu.
🔬 Głębiej: rzadziej testowane szczegóły
- Logi wysyłane do subscription filter są zakodowane base64 i skompresowane gzip: konsument (np. Lambda) musi je zdekodować.
- Eksport do S3 obsługuje kubełki szyfrowane SSE-S3 (AES-256) i SSE-KMS, ale nie DSSE-KMS. Na koncie może działać tylko 1 aktywne zadanie eksportu.
- Live Tail: do 15 równoczesnych sesji na konto (domyślnie), do 10 log groups w jednej sesji.
- Logs Insights potrafi tworzyć field indexes, które zmniejszają koszt i przyspieszają zapytania po popularnych polach.
- CloudTrail Insights analizuje management i data events, a zdarzenie Insights powstaje w tym samym Regionie co dane źródłowe.
- Log group Lambdy możesz wskazać własną (np. wspólną dla kilku funkcji). W konsoli Lambda dodaje uprawnienie
logs:PutLogEvents, przez CLI musisz dodać je sam.
- Log group = retencja (domyślnie bez końca), KMS (symetryczny), filtry. Stream = źródło. Event = wpis.
- Metric filter → metryka (nie wstecz). Subscription filter → real-time do Kinesis/Firehose/Lambda/OpenSearch (5 na grupę). Export → S3, wolno.
- Logs Insights:
fields | filter | stats … by bin() | sort | limit,parse; Lambda:@type="REPORT",@duration,@maxMemoryUsed. - Lambda: rola z
AWSLambdaBasicExecutionRole, JSON + poziomy logów, własna log group. - Structured JSON + correlation ID = obserwowalność; Powertools Logger to robi za Ciebie.
- CloudTrail = kto wywołał API (90 dni za darmo; trail, data events, Insights, Lake). Config = historia konfiguracji.
AWS X-Ray: śledzenie żądań
trace, segment, subsegment, sampling, adnotacje, daemon, OpenTelemetryWyobraź sobie paczkę kurierską z numerem przesyłki. Każdy magazyn, przez który przechodzi, wbija pieczątkę z godziną przyjęcia i wydania. Na końcu widzisz całą trasę i od razu wiesz, w którym magazynie paczka leżała trzy dni. X-Ray robi to samo z żądaniem: numer przesyłki to trace ID, a pieczątki to segmenty.
Każda usługa, przez którą przechodzi żądanie (API Gateway, Lambda, aplikacja na EC2), wysyła segment: nazwę, czasy start/koniec, status HTTP, błędy. Wewnątrz segmentu są subsegmenty, czyli drobniejsze kroki, zwłaszcza wywołania w dół (DynamoDB, S3, zewnętrzne HTTP, zapytania SQL). Wszystkie segmenty z tym samym trace ID tworzą trace, a z wielu trace'ów X-Ray rysuje trace map (mapę usług).
Trace ID wędruje między usługami w nagłówku X-Amzn-Trace-Id. Tracing to trzecia noga obserwowalności: metryka powie „p99 = 4 s”, log powie „timeout w zamówieniu o-104”, a trace pokaże, że 3,8 s z tego to jedno wywołanie zewnętrznego API płatności.
4.2.44.2.64.1.24.3.8
- Annotations vs metadata: adnotacje to proste pary klucz–wartość (string, liczba, Boolean), indeksowane do wyszukiwania (filter expressions, groups,
GetTraceSummaries); do 50 na trace. Metadata = dowolne typy (obiekty, listy), nieindeksowane. „Filtruj ślady po ID klienta” → adnotacja. - Domyślny sampling: pierwsze żądanie w każdej sekundzie (reservoir 1) + 5% kolejnych (rate). Reguły samplingu zmieniasz w konsoli bez redeployu kodu.
- X-Ray daemon nasłuchuje na UDP 2000, buforuje segmenty i wysyła je do API X-Ray. Na EC2 instalujesz go sam (np. w user data), na ECS jako kontener sidecar, w Elastic Beanstalk włączasz opcją
XRayEnabled, a w Lambdzie działa automatycznie. - Uprawnienia:
xray:PutTraceSegmentsixray:PutTelemetryRecords(+GetSamplingRules/GetSamplingTargets), czyli politykaAWSXRayDaemonWriteAccessw roli instancji, tasku lub funkcji. - Lambda: włącz active tracing (
TracingConfig Mode=Active, w SAMTracing: Active). Bez tego trybPassThroughtylko przekazuje nagłówek. Sampling Lambdy jest stały (1 żądanie/s + 5%) i nie da się go skonfigurować. - Zmienne środowiskowe:
_X_AMZN_TRACE_ID(nagłówek śledzenia bieżącego wywołania w Lambdzie),AWS_XRAY_DAEMON_ADDRESS(host:port daemona, domyślnie127.0.0.1:2000),AWS_XRAY_CONTEXT_MISSING(RUNTIME_ERROR/LOG_ERROR/IGNORE_ERROR),AWS_XRAY_TRACING_NAME(nazwa serwisu w segmentach). - API Gateway: active tracing włączasz per stage (REST API). Kody w X-Ray:
Error= 4xx,Fault= 5xx,Throttle= 429. - Kierunek AWS: X-Ray SDK i daemon weszły w tryb utrzymania (maintenance mode) 25 lutego 2026 (tylko poprawki bezpieczeństwa). Nowa instrumentacja → OpenTelemetry / AWS Distro for OpenTelemetry (ADOT), a daemon zastępuje CloudWatch agent lub OpenTelemetry Collector. Starsze pytania nadal oczekują „X-Ray SDK + daemon”.
filter expression: (brak)
Segmenty, subsegmenty, mapa
| Pojęcie | Co to jest | Przykład |
|---|---|---|
| Trace | wszystkie segmenty jednego żądania (ten sam trace ID) | POST /orders od API Gateway do DynamoDB |
| Segment | praca jednej usługi: nazwa, czasy, HTTP, błędy; dokument do 64 kB | segment funkcji orders |
| Subsegment | krok wewnątrz segmentu, zwykle wywołanie w dół | DynamoDB PutItem, POST api.payments.example |
| Inferred segment | węzeł usługi, która sama nie wysyła segmentów, zbudowany z subsegmentu wołającego | DynamoDB, S3 na mapie |
| Trace map | graf usług z latency i odsetkiem błędów na krawędziach | „gdzie są błędy i wolne połączenia” |
| Group | zbiór śladów zdefiniowany filter expression; osobna mapa i metryki CloudWatch | grupa „gold customers” |
| Insights | automatyczne wykrywanie anomalii, gdy odsetek błędów (faults) wychodzi poza normę | „powiadom o nietypowym wzroście 5xx” |
Nagłówek: X-Amzn-Trace-Id: Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1. Root to trace ID (wersja 1, czas w 8 cyfrach hex, 24 cyfry losowe), Parent to ID segmentu rodzica, Sampled to decyzja samplingu podjęta przez pierwszą usługę. Dane śladów przechowywane są 30 dni.
Sampling rules
| Pole | Znaczenie | Uwagi |
|---|---|---|
Priority | 1–9999, niższy = ważniejszy | pierwsza pasująca reguła wygrywa |
Reservoir | stała liczba żądań na sekundę śledzona zawsze | wspólna dla wszystkich instancji (zarządza nią usługa) |
Rate (FixedRate) | procent żądań po wyczerpaniu reservoir | 0–100% (w lokalnym dokumencie JSON jako ułamek, np. 0.05) |
| Kryteria | ServiceName, ServiceType, Host, HTTPMethod, URLPath, ResourceARN, atrybuty | np. 100% dla POST /payments, 1% dla GET /health |
| Default rule | łapie wszystko, co nie pasuje do innych | reservoir 1/s + 5%; możesz zmienić wartości |
Reguły trzymane w X-Ray (a nie w pliku JSON w kodzie) mają dwie zalety: zmieniasz je bez redeployu, a reservoir liczony jest globalnie, więc 10 instancji nie mnoży „1 na sekundę” przez 10.
Instrumentacja kodu: adnotacje, metadata, subsegmenty
# Python, X-Ray SDK
from aws_xray_sdk.core import xray_recorder, patch_all
patch_all() # boto3, requests, … → automatyczne subsegmenty
def handler(event, context):
sub = xray_recorder.begin_subsegment("charge-card")
sub.put_annotation("customer_tier", "gold") # indeksowane → filtr
sub.put_metadata("cart", event["cart"], "orders") # nieindeksowane, dowolny obiekt
try:
charge(event)
finally:
xray_recorder.end_subsegment()
// Node.js (SDK v3)
const AWSXRay = require('aws-xray-sdk-core');
const ddb = AWSXRay.captureAWSv3Client(new DynamoDBClient({}));
- Klucz adnotacji: znaki alfanumeryczne (i podkreślnik); spacje i inne symbole nie zadziałają w filtrach. Wartość: string, liczba lub Boolean, bez obiektów i tablic.
put_metadatabez podanej przestrzeni nazw używadefault.- Powertools Tracer: dekorator
@tracer.capture_lambda_handler(adnotacja ColdStart, automatyczne przechwycenie odpowiedzi i wyjątków) itracer.put_annotation(...). - Filter expressions:
annotation.customer_tier = "gold",responsetime > 5,http.status != 200,service("orders") { fault },edge("api", "orders") { error }.
Daemon i miejsce uruchomienia
| Platforma | Jak uruchomić tracing | Uprawnienia |
|---|---|---|
| EC2 / on-premises | zainstaluj i uruchom daemon (np. w user data); lokalnie z -o (local mode, bez metadanych EC2) | rola instancji z AWSXRayDaemonWriteAccess; poza EC2 klucze/profil |
| ECS | kontener z daemonem jako sidecar w task definition, port 2000/udp; aplikacja ustawia AWS_XRAY_DAEMON_ADDRESS (np. xray-daemon:2000) | task role |
| Elastic Beanstalk | XRayEnabled: true w przestrzeni aws:elasticbeanstalk:xray (konsola lub .ebextensions/xray.config) | instance profile Beanstalka (ma już zapis do X-Ray) |
| Lambda | active tracing; Lambda sama uruchamia daemon | execution role (konsola doda sama) |
| API Gateway (REST) | „Enable X-Ray Tracing” na stage'u | – |
API X-Ray
| API | Do czego |
|---|---|
PutTraceSegments | wysłanie dokumentów segmentów (daemon lub bezpośrednio) |
PutTelemetryRecords | telemetria daemona (statystyki wysyłki) |
GetSamplingRules, GetSamplingTargets | SDK pobiera reguły i przydziały reservoir |
GetTraceSummaries | lista śladów w przedziale czasu, z filter expression |
BatchGetTraces | pełne ślady po trace ID |
GetServiceGraph | graf usług w JSON |
OpenTelemetry, ADOT, Transaction Search
- ADOT (AWS Distro for OpenTelemetry) zbiera metryki i ślady i wysyła je do X-Ray, CloudWatch, OpenSearch czy Amazon Managed Service for Prometheus. Jedno SDK, wiele backendów, standard branżowy.
- Harmonogram: X-Ray SDK i daemon były w pełni wspierane do 25 lutego 2026; od tego dnia są w maintenance mode (tylko poprawki bezpieczeństwa, bez nowych funkcji). AWS zaleca migrację do OpenTelemetry, a zamiast daemona CloudWatch agent lub OpenTelemetry Collector.
- CloudWatch Application Signals buduje na OpenTelemetry automatyczne metryki i ślady usług z SLO (patrz CloudWatch).
- Transaction Search: 100% spanów zapisywanych jako ustrukturyzowane logi w CloudWatch (ślady do 10 000 spanów), a część z nich indeksowana jako trace summaries w X-Ray. Odpowiedź na „chcę widzieć każdą transakcję, nie tylko próbkę”.
- Metadata do wyszukiwania śladów — metadata nie są indeksowane. Filtrować możesz tylko po adnotacjach (i polach systemowych).
- „Włącz X-Ray w kodzie” bez uprawnień — bez
xray:PutTraceSegmentsw roli segmenty nie dotrą. Na EC2: rola instancji, na ECS: task role, nie rola wykonawcza tasku (ta służy do pobierania obrazu i logów). - Daemon na porcie TCP 2000 — segmenty idą po UDP 2000 (SDK pyta o reguły samplingu po TCP pod tym samym adresem). Na ECS zmapuj
2000/udp. - „Ustaw sampling 100% w Lambdzie” — sampling Lambdy jest stały i nieedytowalny. Możesz za to wysłać więcej danych z upstreamu, który ma własne reguły (np. API Gateway), albo użyć Transaction Search.
- Śledzenie każdego żądania przez default rule — default to 1/s + 5%. „Brakuje części żądań w X-Ray” to zwykle sampling, a nie błąd.
- CloudTrail zamiast X-Ray — CloudTrail rejestruje wywołania API konta, nie opóźnienia między mikroserwisami. „Gdzie traci się czas w żądaniu?” → X-Ray.
- X-Ray SDK jako „rekomendowane” w nowym projekcie — w aktualnej dokumentacji rekomendacją jest OpenTelemetry/ADOT; w starszych testach poprawna odpowiedź to zwykle „X-Ray SDK + daemon”.
tier = "gold". Za to wszyscy mnie znajdą, bo X-Ray mnie indeksuje.Programista chce w konsoli X-Ray szybko wyszukiwać ślady po identyfikatorze zamówienia i typie klienta.
search, filter expressions, indexed
Odpowiedź
Annotations (put_annotation("order_id", …)) i filtr annotation.order_id = "o-123".
Dlaczego nie: metadata nie są indeksowane; subsegment z nazwą zamówienia nie daje wygodnego filtra.
Aplikacja na ECS (EC2 launch type) ma X-Ray SDK, ale ślady nie pojawiają się w konsoli. Logi aplikacji pokazują błędy wysyłki na 127.0.0.1:2000.
ECS, daemon, sidecar
Odpowiedź
Dodać kontener X-Ray daemon jako sidecar w task definition (port 2000/udp), ustawić AWS_XRAY_DAEMON_ADDRESS na adres daemona i dać task role uprawnienia AWSXRayDaemonWriteAccess.
Funkcja Lambda wywołuje DynamoDB i zewnętrzne API. Zespół chce zobaczyć, który z tych kroków odpowiada za opóźnienia, przy minimalnych zmianach.
latency breakdown, least effort
Odpowiedź
Active tracing na funkcji + instrumentacja klientów SDK/HTTP (np. captureAWSv3Client, patch_all lub Powertools Tracer). Subsegmenty pokażą czasy wywołań.
Dlaczego nie: metryka Duration pokazuje tylko całość; logi wymagałyby ręcznego mierzenia czasu.
Serwis obsługuje 2000 żądań/s. Zespół chce śledzić wszystkie żądania POST /payments, ale tylko 1% żądań GET /health, bez zmian w kodzie.
sampling rules, without redeploy
Odpowiedź
Własne sampling rules w X-Ray: reguła z wysokim priorytetem dla POST /payments (rate 100%), druga dla /health (rate 1%). SDK pobiera reguły z usługi.
Nowy projekt mikroserwisów ma używać tracingu, który będzie dalej rozwijany i pozwoli wysyłać dane do X-Ray i do innego backendu. Co wybrać?
vendor-neutral, future-proof
Odpowiedź
AWS Distro for OpenTelemetry (OpenTelemetry SDK + Collector albo CloudWatch agent). X-Ray SDK/daemon są od 25.02.2026 w maintenance mode.
🔬 Głębiej: rzadziej testowane szczegóły
- Ślad Lambdy w nowym formacie ma węzeł
AWS::Lambda(przygotowanie środowiska) iAWS::Lambda::Functionz subsegmentamiInitialization(cold start),InvocationiOverhead. AWS_XRAY_CONTEXT_MISSING: w Lambdzie ustawione naLOG_ERROR, żeby SDK nie rzucało wyjątków, gdy kod nagrywa dane poza otwartym segmentem.- API Gateway, gdy active tracing jest wyłączone, nadal zapisze segment, jeśli żądanie przyszło z usługi, która już podjęła decyzję o samplingu.
- Subsegmenty można wysyłać osobno (np. dla długich żądań albo by nie przekroczyć 64 kB dokumentu segmentu).
- Klucz adnotacji w X-Ray SDK for Python: do 500 znaków alfanumerycznych.
- Daemon:
-bzmienia port UDP,-nRegion,-mpamięć buforów (MB).
- Trace = segmenty jednego żądania (trace ID w
X-Amzn-Trace-Id); subsegmenty = wywołania w dół; mapa = graf usług. - Adnotacje (indeksowane, 50/trace, filtr) vs metadata (dowolny JSON, nieindeksowane).
- Sampling domyślnie 1/s + 5%; reguły w konsoli, bez redeployu; w Lambdzie stały.
- Daemon: UDP 2000; EC2 instalujesz, ECS sidecar, Beanstalk
XRayEnabled, Lambda automatycznie. Rola:AWSXRayDaemonWriteAccess. - Lambda: Active tracing; zmienne
_X_AMZN_TRACE_ID,AWS_XRAY_DAEMON_ADDRESS,AWS_XRAY_CONTEXT_MISSING. - Przyszłość: OpenTelemetry/ADOT; SDK i daemon X-Ray w maintenance mode od 25.02.2026.
Troubleshooting i optymalizacja
atlas błędów: objaw → przyczyna → naprawa, profilowanie, pamięć, Systems ManagerDiagnoza w chmurze przypomina pracę lekarza: najpierw objaw (kod HTTP, komunikat, rosnąca metryka), potem badanie (gdzie patrzysz: metryki, logi, ślady, zdarzenia), potem przyczyna i dopiero na końcu lekarstwo. Pytania egzaminacyjne z domeny 4 prawie zawsze podają objaw i każą wybrać przyczynę albo naprawę. Ten rozdział to ściąga: objaw → przyczyna → naprawa.
Pierwsza zasada: kod HTTP mówi, kto zawinił. 4xx = problem po stronie wywołującego (zły adres, brak uprawnień, przekroczony limit). 5xx = problem po stronie serwera lub integracji (backend padł, odpowiedział źle albo za wolno). 429 to osobna rodzina: „za dużo, za szybko”, czyli throttling.
Druga zasada: wybierz właściwy przyrząd. Metryka powie „ile i kiedy”, log „co dokładnie”, ślad X-Ray „gdzie w łańcuchu”, CloudTrail „kto wywołał API”, a AWS Config „jak zmieniła się konfiguracja”.
4.1.14.1.24.1.64.1.74.2.84.3.24.3.34.3.74.3.84.3.9
- API Gateway: 502 = Lambda proxy zwróciła zły format (lub funkcja padła); 504 = timeout integracji (maks. 29 s); 429 = throttling lub quota usage planu; 403 Missing Authentication Token = zła ścieżka/metoda albo brak deploymentu; 401 = authorizer odrzucił token.
- ALB z Lambdą: 502 = funkcja nie zdążyła przed swoim timeoutem, zwróciła błąd, została throttlowana albo odpowiedź > 1 MB; 503 = brak zarejestrowanych celów; 504 = cel nie odpowiedział w czasie.
- Encoded authorization failure message przy AccessDenied (np. EC2
UnauthorizedOperation) →aws sts decode-authorization-message, wymagasts:DecodeAuthorizationMessage. - Throttling (
ThrottlingException,ProvisionedThroughputExceededException,TooManyRequestsException, 429) → ponawiaj z exponential backoff i jitter (domyślny tryb retry SDK), zwiększ limit lub pojemność, rozłóż ruch. - Lambda „Task timed out”: sprawdź
Durationvs timeout; w VPC bez NAT funkcja nie wyjdzie do internetu (NAT gateway w publicznej podsieci albo VPC endpoint). Wolna Lambda → więcej pamięci = proporcjonalnie więcej CPU. - Minimalna pamięć:
Max Memory Usedz linii REPORT / Logs Insights, AWS Lambda Power Tuning (Step Functions testuje różne ustawienia), Compute Optimizer (rekomendacje pamięci Lambdy, EC2, ASG, EBS, ECS na Fargate; wymaga opt-in). - Wdrożenie padło: CloudFormation → zakładka Events, pierwszy
CREATE_FAILED;UPDATE_ROLLBACK_FAILED→continue-update-rollback(z--resources-to-skip). CodeDeploy → log agenta iscripts.logna instancji, rola instancji (instance profile). Beanstalk → tail/bundle logs. ECS →stoppedReason. - Dostęp do instancji bez SSH, bastionu i otwartych portów → Session Manager. Polecenie na wielu instancjach naraz → Run Command.
Gdzie patrzeć: przyrządy
| Pytanie | Przyrząd | Przykład |
|---|---|---|
| Ile, jak często, od kiedy? | Metryki CloudWatch | 5XXError, Throttles, IteratorAge |
| Co dokładnie się stało? | CloudWatch Logs / Logs Insights | stack trace, Task timed out, REPORT |
| Gdzie w łańcuchu usług ginie czas lub pojawia się błąd? | X-Ray / Application Signals | subsegment zewnętrznego API 2,9 s |
| Kto wywołał API / zmienił zasób? | CloudTrail | DeleteTable przez rolę X |
| Jak wyglądała konfiguracja przedtem? | AWS Config | security group przed zmianą |
| Czy endpoint działa z perspektywy klienta? | Synthetics canary | ścieżka logowania co 5 min |
Atlas błędów HTTP (API Gateway, ALB)
| Objaw | Przyczyna | Naprawa |
|---|---|---|
| API GW 400 (BAD_REQUEST_BODY / PARAMETERS) | request validator odrzucił body lub parametry | popraw żądanie lub model; komunikat w gateway response |
| API GW 401 (UNAUTHORIZED) | Lambda/Cognito authorizer nie uwierzytelnił wywołującego (brak/zły token) | poprawny nagłówek tokenu, ważny JWT |
| API GW 403 „Missing Authentication Token” | nieistniejąca ścieżka/metoda (lub API niewdrożone na stage) albo brak podpisu przy IAM | sprawdź URL, stage i metodę; redeploy; podpis SigV4 |
| API GW 403 (ACCESS_DENIED, INVALID_API_KEY, WAF_FILTERED, EXPIRED_TOKEN, INVALID_SIGNATURE) | authorizer/polityka zabrania, zły klucz API, reguła WAF, wygasłe poświadczenia, zły podpis | polityka zasobu, x-api-key, reguły WAF, odśwież poświadczenia |
| API GW 404 (RESOURCE_NOT_FOUND) | zasób nie istnieje po uwierzytelnieniu | ścieżka, base path mapping |
| API GW 429 (THROTTLED / QUOTA_EXCEEDED) | limit konta/stage'a/metody/usage planu lub wyczerpana quota klienta | backoff + retry, wyższy limit, usage plan (patrz API Gateway ops) |
| API GW 500 | błąd konfiguracji API lub authorizera (AUTHORIZER_FAILURE, API_CONFIGURATION_ERROR), brak uprawnienia API GW do wywołania Lambdy | logi wykonania API GW, lambda add-permission |
| API GW 502 | Lambda proxy zwróciła odpowiedź w złym formacie (brak statusCode/body jako string) albo funkcja zakończyła się błędem | poprawny format proxy, obsługa wyjątków (patrz API Gateway) |
| API GW 504 (INTEGRATION_TIMEOUT) | backend nie odpowiedział w limicie integracji (50 ms – 29 s) | przyspiesz backend, wzorzec asynchroniczny (202 + kolejka), przy Lambdzie timeout funkcji < integracji |
| ALB 502 | Lambda: timeout, błąd, throttling, odpowiedź > 1 MB; EC2: TCP RST, keep-alive celu krótszy niż idle timeout ALB | timeout/obsługa błędów funkcji; keep-alive aplikacji > idle timeout |
| ALB 503 | grupa docelowa bez zarejestrowanych (zdrowych) celów | rejestracja celów, health check (patrz ELB) |
| ALB 504 | brak połączenia z celem w 10 s albo cel nie odpowiedział przed idle timeoutem; NACL blokuje porty efemeryczne | security group/NACL, wydajność celu, idle timeout |
Metryki API Gateway: Latency (całość, łącznie z narzutem API GW) vs IntegrationLatency (sam backend). Duża różnica = narzut po stronie API Gateway (np. authorizer); prawie równe = wolny backend. 4XXError/5XXError liczą błędy klienta i serwera.
Atlas błędów Lambdy i integracji
| Objaw | Przyczyna | Naprawa |
|---|---|---|
Task timed out after 3.00 seconds | domyślny timeout 3 s za krótki; wolne wywołanie w dół; w VPC brak wyjścia do internetu/usług | timeout (maks. 900 s), więcej pamięci/CPU, NAT gateway lub VPC endpoint, timeouty klienta SDK |
| Funkcja „wolniejsza niż na laptopie” | za mało pamięci, a więc i CPU | podnieś pamięć (128 MB – 10 240 MB), Power Tuning |
Max Memory Used = Memory Size, wywołanie ucięte | brak pamięci (duże pliki, wyciek między wywołaniami) | więcej pamięci, strumieniowanie zamiast ładowania w całości |
Unable to import module / Runtime.ImportModuleError | handler w konfiguracji nie pasuje do pliku/funkcji albo brak biblioteki w pakiecie (/var/task) lub layerze; biblioteka natywna skompilowana na inną platformę | popraw Handler, dołącz zależności do .zip/layera, buduj na Amazon Linux (np. sam build --use-container) |
Sandbox.Timedout w fazie Init | zbyt ciężka inicjalizacja poza handlerem | dłuższy timeout, lżejszy init, provisioned concurrency |
TooManyRequestsException, metryka Throttles | brak wolnej współbieżności (limit konta, reserved concurrency) lub jedna funkcja zjada pulę | reserved concurrency dla krytycznych funkcji, wniosek o limit, retry z backoffem |
Długi pierwszy request (cold start), Init Duration w REPORT | tworzenie środowiska i kod inicjalizacji | provisioned concurrency, SnapStart (Java/Python/.NET), mniejszy pakiet, init poza handlerem |
| Brak logów lub śladów | rola wykonawcza bez logs:* / xray:Put* | AWSLambdaBasicExecutionRole, AWSXRayDaemonWriteAccess |
| Node.js: funkcja kończy się przed zapisem do DynamoDB | brak await na promise | await / zwróć promise |
IteratorAge rośnie (Kinesis, DynamoDB Streams) | konsument nie nadąża albo „trujący” rekord blokuje shard i jest ponawiany | więcej shardów, większy batch, ParallelizationFactor, BisectBatchOnFunctionError, MaximumRetryAttempts, on-failure destination (patrz źródła zdarzeń) |
| SQS: te same wiadomości przetwarzane wielokrotnie | visibility timeout krótszy niż czas przetwarzania; cały batch wraca przez jedną złą wiadomość | visibility timeout ≥ 6× timeout funkcji, ReportBatchItemFailures, idempotencja (patrz SQS) |
| DLQ się zapełnia | stały błąd w kodzie/danych, a nie chwilowy problem | alarm na ApproximateNumberOfMessagesVisible DLQ, analiza wiadomości, redrive po poprawce |
| Wywołania asynchroniczne „giną” | wyczerpane ponowienia, za stare zdarzenia; DLQ/destination bez uprawnień | AsyncEventsDropped, DeadLetterErrors, on-failure destination, uprawnienia roli |
AccessDeniedException przy wywołaniu usługi | brak akcji w polityce roli wykonawczej (implicit deny), jawny Deny, permissions boundary, SCP, polityka zasobu/klucza KMS | dodaj akcję; sprawdź polityki zasobów; CloudTrail pokaże odrzucone wywołanie |
EC2 API: UnauthorizedOperation z zakodowaną wiadomością | brak uprawnienia; szczegóły ukryte | aws sts decode-authorization-message --encoded-message … |
ProvisionedThroughputExceededException (DynamoDB), ThrottlingException | przekroczona pojemność tabeli/partycji (gorący klucz) lub limit API | backoff z jitter (SDK robi to sam), lepszy klucz partycji, on-demand, DAX (patrz DynamoDB) |
aws sts decode-authorization-message --encoded-message "eyJ…" \
--query DecodedMessage --output text | jq .
# pokaże: który principal, jaka akcja, jaki zasób i która polityka (allowed: false)
Wdrożenia: gdzie są logi (4.1.6)
| Usługa | Objaw | Gdzie patrzysz / co robisz |
|---|---|---|
| CloudFormation | CREATE_FAILED, ROLLBACK_COMPLETE | zakładka Events stosu: pierwsze zdarzenie *_FAILED ma właściwy „Status reason” (kolejne to skutki rollbacku); typowo brak uprawnień IAM, limit, nazwa już zajęta |
| CloudFormation | UPDATE_ROLLBACK_FAILED | zasób zmieniony poza CloudFormation; napraw ręcznie i aws cloudformation continue-update-rollback, w ostateczności --resources-to-skip |
| CloudFormation | DELETE_FAILED | ponów usuwanie z RetainResources (np. niepusty bucket S3) |
| CodeDeploy (EC2/on-prem) | „Missing credentials … IAM instance profile”, wdrożenie wisi | agent działa? (service codedeploy-agent status), rola instancji, log /var/log/aws/codedeploy-agent/codedeploy-agent.log |
| CodeDeploy | hook ApplicationStop/AfterInstall/ValidateService failed lub timeout | /opt/codedeploy-agent/deployment-root/<group-id>/<deployment-id>/logs/scripts.log; timeout w AppSpec; przy instancji zakończonej w trakcie status może czekać do godziny (patrz CodeDeploy) |
| ECS | task zatrzymany | stoppedReason/stopCode w describe-tasks (zatrzymane taski widać w konsoli tylko 1 h): CannotPullContainer (obraz, uprawnienia ECR, sieć), ResourceInitializationError (sekrety, logi, sieć), OutOfMemoryError (limit pamięci kontenera), TaskFailedToStart |
| Elastic Beanstalk | wdrożenie padło, środowisko „Severe” | Request logs: tail (ostatnie 100 linii) lub bundle (pełne); pliki w S3 przez presigned URL, usuwane po 15 min; rotacja logów do S3; strumień do CloudWatch Logs; enhanced health |
| Lambda (SAM/CodeDeploy) | rollback wdrożenia canary | alarm CloudWatch przypięty do wdrożenia, hooki PreTraffic/PostTraffic (patrz SAM) |
Health checks i readiness (4.2.8)
- ELB: health check celu (ścieżka, kod, progi). Niezdrowe cele nie dostają ruchu. Szczegóły w ELB.
- ECS:
healthCheckw definicji kontenera (CMDlubCMD-SHELL,interval,timeout,retries,startPeriod). Endpoint/health(liveness) powinien sprawdzać tylko proces, a/ready(readiness) także zależności. - Elastic Beanstalk: enhanced health reporting (agent zdrowia na instancjach, statusy kolorami).
- Synthetics canaries sprawdzają endpoint z zewnątrz, z perspektywy klienta (patrz CloudWatch).
Optymalizacja i profilowanie (4.3.2, 4.3.3, 4.3.7–4.3.9)
| Narzędzie | Co robi | Kiedy |
|---|---|---|
| Logs Insights na REPORT | max(@maxMemoryUsed) vs @memorySize, pct(@duration, 99) | „ile pamięci naprawdę potrzebuje funkcja” |
| AWS Lambda Power Tuning | open source; Step Functions uruchamia funkcję z różnymi ustawieniami pamięci i porównuje czas oraz koszt | „najlepszy stosunek kosztu do wydajności” |
| AWS Compute Optimizer | ML na metrykach z ostatnich 14 dni: Optimized / Not optimized; rekomendacje pamięci Lambdy, typów EC2, ASG, EBS, ECS na Fargate | „right-sizing na podstawie historycznego użycia”; trzeba się zapisać (opt-in) |
| Amazon CodeGuru Profiler | profilowanie aplikacji JVM i Python (także w Lambdzie): najdroższe linie kodu, wąskie gardła CPU | „która metoda zużywa najwięcej CPU” |
| Lambda Insights | CPU, pamięć, sieć per wywołanie | wycieki pamięci, nietypowe zużycie |
| X-Ray / Application Signals | rozkład opóźnień między usługami | „który krok jest wąskim gardłem” |
- W Lambdzie pamięć to jedyna gałka wydajności: CPU rośnie proporcjonalnie. Funkcje CPU-bound często są tańsze z większą pamięcią, bo kończą się szybciej.
- Optymalizacja zasobów: połączenia i klienty SDK tworzone poza handlerem (reużycie między wywołaniami), cache (patrz ElastiCache/DAX), batch zamiast pojedynczych wywołań, filtry zdarzeń zamiast filtrowania w kodzie, krótsza retencja logów i poziom WARN w produkcji.
- Wąskie gardła w logach (4.3.9):
stats avg(@duration), pct(@duration, 99) by bin(5m), porównanie z wolumenem; własne pomiary czasu jako pola JSON lub EMF.
Systems Manager przy diagnozie
| Narzędzie | Co robi | Kiedy |
|---|---|---|
| Session Manager | powłoka na instancji przez konsolę/CLI, bez otwartych portów, bastionu i kluczy SSH; sesje można logować (S3, CloudWatch Logs) i audytować w CloudTrail | „bezpieczny dostęp do prywatnej instancji, by przejrzeć logi” |
| Run Command | zdalne wykonanie dokumentu (np. skryptu) na wielu instancjach naraz | „zbierz logi / zrestartuj agenta na 200 instancjach” |
| Parameter Store | konfiguracja (np. pliku CloudWatch agenta) | jedna konfiguracja agenta dla floty |
| OpsCenter / Incident Manager | OpsItems i incydenty tworzone z alarmów | „zarządzaj incydentem z alarmu” |
- Na 429/Throttling „zwiększ timeout” albo „dodaj pamięć” — to nie pomoże. Throttling leczysz backoffem z jitter, limitem/pojemnością albo rozłożeniem ruchu (kolejka).
- Na 504 z API Gateway „zwiększ timeout Lambdy do 15 minut” — integracja i tak utnie po 29 s (domyślnie). Długie zadania → asynchronicznie (SQS/Step Functions) i zwróć 202.
- 403 „Missing Authentication Token” = problem z IAM — najczęściej to literówka w ścieżce, zła metoda albo brak redeployu na stage.
- Ponawianie bez backoffu — natychmiastowe retry przy throttlingu pogarsza sprawę (retry storm).
- „Wolna Lambda → zwiększ timeout” — timeout tylko pozwala dłużej czekać. Szybciej będzie z większą pamięcią (CPU) albo po usunięciu wąskiego gardła.
- Compute Optimizer „od razu po włączeniu” — potrzebuje opt-in i historii metryk (rekomendacje Lambdy z 14 dni).
- CodeDeploy „agent padł” vs „skrypt padł” — brak agenta lub roli: wdrożenie nie startuje na instancji; błąd skryptu: konkretny hook w
scripts.log. - SSH przez bastion jako „najbezpieczniej” — Session Manager nie wymaga otwartych portów ani kluczy i loguje sesje.
API Gateway → Lambda → DynamoDB. Metryka Latency API GW = 2,1 s, IntegrationLatency = 2,05 s, Duration Lambdy = 2,0 s, a SuccessfulRequestLatency DynamoDB = 8 ms. Gdzie jest wąskie gardło i jakim narzędziem je potwierdzisz?
Odpowiedź
Nie w API Gateway (Latency ≈ IntegrationLatency) i nie w DynamoDB (8 ms). Czas ginie w samej funkcji: w kodzie, zimnym starcie lub innym wywołaniu w dół. X-Ray z subsegmentami (lub Logs Insights na REPORT i Init Duration) pokaże, który krok. Jeśli to CPU: więcej pamięci, CodeGuru Profiler.
Klienci dostają 502 z REST API z integracją Lambda proxy. Logi funkcji pokazują poprawne zakończenie i zwrot {"result": "ok"}.
502, proxy, response format
Odpowiedź
Zły format odpowiedzi proxy: funkcja musi zwrócić {"statusCode": 200, "headers": {…}, "body": "<string>"}.
Dlaczego nie: brak uprawnienia dałby 500, timeout 504.
Wywołanie RunInstances z CLI zwraca UnauthorizedOperation i długi zakodowany ciąg. Jak ustalić, której akcji brakuje?
encoded authorization message
Odpowiedź
aws sts decode-authorization-message (uprawnienie sts:DecodeAuthorizationMessage). Odkodowana wiadomość pokaże akcję, zasób i kontekst odmowy.
Aplikacja na EC2 dostaje z DynamoDB ProvisionedThroughputExceededException w krótkich pikach ruchu. Co zrobić najpierw, z najmniejszym nakładem?
throttling, transient, least effort
Odpowiedź
Ponawianie z exponential backoff i jitter (SDK robi to domyślnie; zwiększ liczbę prób/tryb adaptive), a przy stałym wzroście: auto scaling pojemności lub tryb on-demand.
Dlaczego nie: większa instancja EC2 nie zwiększy pojemności tabeli.
Funkcja Lambda w prywatnej podsieci VPC kończy się Task timed out przy wywołaniu publicznego API płatności. Do RDS w tej samej VPC łączy się bez problemu.
VPC, internet access
Odpowiedź
NAT gateway w publicznej podsieci + trasa z prywatnej podsieci funkcji do NAT. Do usług AWS (np. S3, DynamoDB) zamiast tego VPC endpoint.
Dlaczego nie: zwiększenie timeoutu nie da trasy do internetu; publiczny adres IP dla funkcji w VPC nie działa.
Zespół chce ustalić najtańszą konfigurację pamięci funkcji Lambda przy zachowaniu czasu odpowiedzi, testując kilka wartości na realnym obciążeniu.
memory tuning, cost vs performance
Odpowiedź
AWS Lambda Power Tuning (Step Functions uruchamia funkcję z różną pamięcią i rysuje koszt vs czas). Alternatywa bez testów: rekomendacje Compute Optimizer z historii użycia.
Aktualizacja stosu CloudFormation zakończyła się UPDATE_ROLLBACK_FAILED, bo administrator ręcznie usunął instancję RDS, do której stos próbuje wrócić.
rollback failed, resource changed outside CloudFormation
Odpowiedź
ContinueUpdateRollback po naprawie przyczyny, a gdy zasobu nie da się przywrócić: --resources-to-skip dla tego zasobu.
Dlaczego nie: usunięcie stosu niszczy pozostałe zasoby; ponowny update nie jest możliwy w stanie UPDATE_ROLLBACK_FAILED.
Wdrożenie CodeDeploy na flotę EC2 kończy się błędem w kroku AfterInstall. Gdzie programista znajdzie wyjście skryptu?
deployment failure, service output logs
Odpowiedź
Na instancji: /opt/codedeploy-agent/deployment-root/…/logs/scripts.log (oraz log agenta /var/log/aws/codedeploy-agent/codedeploy-agent.log); podsumowanie zdarzeń w konsoli CodeDeploy. Dostęp bez SSH: Session Manager.
🔬 Głębiej: rzadziej testowane szczegóły
- Tryby retry SDK:
standard(domyślny, backoff z jitter, dłuższe opóźnienia dla throttlingu),adaptive(dodatkowo ogranicza tempo po stronie klienta),legacy. - Throttling DynamoDB ma kilka powodów: przekroczona pojemność tabeli/indeksu (provisioned), przekroczony limit partycji (gorący klucz, w obu trybach), limity konta i maksymalna przepustowość on-demand.
- CodeDeploy: gdy instancję zakończono pomiędzy zdarzeniami cyklu życia lub przed pierwszym krokiem, timeout następuje po 5 minutach; gdy w trakcie skryptu, nawet po godzinie.
- Beanstalk: żeby rotowane logi trafiały do S3, instance profile musi mieć prawo zapisu do kubełka Beanstalka (domyślny profil je ma).
- Nazwy błędów Lambdy w odpowiedzi (
errorType) zaczynające się odRuntime.pochodzą z runtime'u (np.Runtime.ImportModuleError), a nie z Twojego kodu. - CodeGuru Profiler wspiera języki JVM i Python 3.6+. W dokumentacji (stan na październik 2026) nie znalazłem zapowiedzi wycofania Profilera, ale inne usługi z rodziny CodeGuru zmieniały dostępność, więc w nowych materiałach częściej zobaczysz Application Signals i X-Ray.
- 4xx = klient, 5xx = serwer/integracja, 429 = throttling (backoff z jitter, limity, kolejka).
- API GW: 502 format proxy, 504 timeout 29 s, 403 Missing Authentication Token = zła ścieżka/brak deployu. ALB: 502 Lambda timeout/błąd, 503 brak celów.
- AccessDenied: polityka roli, Deny, boundary, SCP, polityka zasobu; zakodowana wiadomość →
sts decode-authorization-message. - Lambda: timeout/VPC NAT, pamięć = CPU, ImportModuleError = handler/pakiet, Throttles = współbieżność, IteratorAge = konsument nie nadąża.
- Wdrożenia: CFN Events (pierwszy FAILED), continue-update-rollback; CodeDeploy scripts.log + agent + instance profile; ECS stoppedReason; Beanstalk tail/bundle logs.
- Pamięć i koszt: REPORT/Logs Insights, Power Tuning, Compute Optimizer; profil CPU: CodeGuru Profiler. Dostęp: Session Manager, masowe polecenia: Run Command.
Słownik, liczby i egzamin próbny
wszystko w jednym miejscu, na ostatni wieczórSłownik: słowo-klucz w pytaniu → odpowiedź
Egzamin powtarza pewne frazy. Każda z nich mocno wskazuje na konkretną usługę lub funkcję. Kolumna „Rozdział” prowadzi do pełnego wyjaśnienia.
| Słowo-klucz / sytuacja | Odpowiedź | Rozdział |
|---|---|---|
| „decouple”, „loosely coupled”, „buffer spikes” | Kolejka/temat/szyna między komponentami (SQS, SNS, EventBridge) | Wzorce i odporność |
| „one event, multiple consumers”, „fan-out” | SNS → wiele kolejek SQS | Wzorce i odporność |
| „central coordinator”, „visual workflow”, „compensating transactions” | Orchestration — Step Functions | Wzorce i odporność |
| „services react to events independently” | Choreography — EventBridge | Wzorce i odporność |
| „throttling”, „ThrottlingException”, „Rate exceeded” | Retry z exponential backoff + jitter (SDK robi to sam) | Wzorce i odporność |
| „retries at the same time”, „thundering herd” | Dodaj jitter | Wzorce i odporność |
| „duplicate processing after retry”, „exactly once” | Klucz/token idempotencji | Wzorce i odporność |
| „dependency down for minutes”, „stop calling failing service” | Circuit breaker | Wzorce i odporność |
| „session lost when instance terminates”, „stateless” | Sesja w ElastiCache/DynamoDB | Wzorce i odporność |
| „explicit deny”, „which policy wins” | Explicit Deny > Allow > implicit deny | IAM |
| „cross-account access” | Allow po obu stronach / rola z trust policy | IAM |
| „third party”, „confused deputy” | sts:ExternalId w trust policy | IAM |
| „maximum permissions”, „prevent privilege escalation when creating roles” | Permissions boundary | IAM |
| „organization-wide guardrail”, „restrict all accounts” | SCP | IAM |
| „user can only access own folder” | Policy variable ${aws:username} | IAM |
| „access based on tags”, „ABAC” | aws:PrincipalTag / aws:ResourceTag w Condition | IAM |
| „least privilege based on CloudTrail activity” | IAM Access Analyzer policy generation | IAM |
| „resources shared outside account”, „unused permissions” | IAM Access Analyzer (external / unused access) | IAM |
| „test policy without making changes” | IAM policy simulator | IAM |
| „pass a role to a service” | iam:PassRole | IAM |
| „application on EC2 needs AWS access” | Instance profile (rola), nie klucze | CLI, SDK i STS |
| „which credentials does the SDK use”, „credential precedence” | Credential provider chain (CLI opcje → env → … → IMDS) | CLI, SDK i STS |
| „MFA for CLI” | sts get-session-token z --serial-number i --token-code | CLI, SDK i STS |
| „encoded authorization failure message” | sts decode-authorization-message | CLI, SDK i STS |
| „which identity am I using” | sts get-caller-identity | CLI, SDK i STS |
| „check permissions without running” | --dry-run (DryRunOperation) | CLI, SDK i STS |
| „filter CLI output”, „JMESPath” | --query (po stronie klienta); --filters (serwer) | CLI, SDK i STS |
| „results truncated”, „NextToken” | Paginacja / paginatory SDK / --max-items, --starting-token | CLI, SDK i STS |
| „wait until resource is ready” | Waitery (aws … wait, get_waiter) | CLI, SDK i STS |
| „SSRF”, „protect instance metadata” | IMDSv2 (HttpTokens=required) | CLI, SDK i STS |
| „developers access multiple accounts without long-term keys” | IAM Identity Center + aws sso login | CLI, SDK i STS |
| „browser-based shell”, „pre-authenticated CLI” | AWS CloudShell | CLI, SDK i STS |
| „Lambda in VPC needs internet” | Prywatne podsieci + NAT gateway w publicznej | VPC |
| „access S3/DynamoDB from VPC without internet”, „cheapest” | Gateway VPC endpoint | VPC |
| „private connectivity to AWS service”, „PrivateLink” | Interface VPC endpoint | VPC |
| „stateful firewall at instance level” | Security group | VPC |
| „block specific IP address”, „stateless”, „subnet level” | Network ACL | VPC |
| „is traffic being rejected”, „capture IP traffic information” | VPC Flow Logs (REJECT) | VPC |
| „path-based routing”, „host-based routing” | Application Load Balancer | ELB, ASG, Route 53 |
| „static IP”, „TCP/UDP”, „millions of requests per second” | Network Load Balancer | ELB, ASG, Route 53 |
| „third-party firewall appliances” | Gateway Load Balancer | ELB, ASG, Route 53 |
| „client IP address behind load balancer” | X-Forwarded-For | ELB, ASG, Route 53 |
| „in-flight requests during deregistration”, „connection draining” | Deregistration delay | ELB, ASG, Route 53 |
| „user must stay on same instance” | Sticky sessions (AWSALB) — lepiej stateless | ELB, ASG, Route 53 |
| „multiple TLS certificates on one listener” | SNI + ACM | ELB, ASG, Route 53 |
| „replace instances failing application health check” | ASG z ELB health checks | ELB, ASG, Route 53 |
| „run script before instance is in service / before termination” | Lifecycle hooks | ELB, ASG, Route 53 |
| „keep average CPU at 50%” | Target tracking scaling | ELB, ASG, Route 53 |
| „predictable daily peak” | Scheduled (lub predictive) scaling | ELB, ASG, Route 53 |
| „zone apex”, „naked domain to ALB/CloudFront” | Route 53 alias | ELB, ASG, Route 53 |
| „route to lowest latency Region” | Latency routing | ELB, ASG, Route 53 |
| „active-passive failover” | Failover routing + health check | ELB, ASG, Route 53 |
| „send 10% of traffic to new version (DNS)” | Weighted routing | ELB, ASG, Route 53 |
| „content by user country” | Geolocation routing (+ rekord default) | ELB, ASG, Route 53 |
| „bootstrap”, „install packages at launch” | EC2 user data (pierwszy start, root) | EC2 i storage |
| „SSRF”, „protect instance metadata”, „MOST secure metadata” | IMDSv2, HttpTokens=required | EC2 i storage |
| „instance ID / region from inside the instance” | IMDS 169.254.169.254/latest/meta-data | EC2 i storage |
| „memory utilization”, „disk space” w CloudWatch | CloudWatch agent (namespace CWAgent) | EC2 i storage |
| „highest I/O, temporary data, loss acceptable” | Instance store | EC2 i storage |
| „shared file system across AZs” | Amazon EFS | EC2 i storage |
| „interruptible, lowest cost compute” | Spot Instances / Fargate Spot (2 min ostrzeżenia) | EC2 i storage |
| „deploy code without managing infrastructure”, „upload ZIP, platform” | Elastic Beanstalk | Elastic Beanstalk |
| „fastest deployment, downtime acceptable” | Beanstalk All at once | Elastic Beanstalk |
| „maintain full capacity during deployment” | Rolling with additional batch / Immutable | Elastic Beanstalk |
| „quickest rollback”, „new instances, new ASG” | Beanstalk Immutable | Elastic Beanstalk |
| „percentage of traffic to new version”, „canary” w Beanstalk | Traffic splitting (NewVersionPercent, EvaluationTime) | Elastic Beanstalk |
| „swap URLs”, „zero downtime with separate environment” | Blue/green, eb swap (Swap environment URLs) | Elastic Beanstalk |
| „run once per deployment”, „DB migration on one instance” | container_commands + leader_only: true | Elastic Beanstalk |
| „.ebextensions”, „customize environment” | pliki .config (YAML/JSON) w paczce; .platform/hooks na AL2/AL2023 | Elastic Beanstalk |
| „long-running background tasks”, „periodic tasks” w Beanstalk | Worker environment (sqsd, cron.yaml) | Elastic Beanstalk |
| „application version limit reached” | Application version lifecycle policy | Elastic Beanstalk |
| „database decoupled from environment lifecycle” | RDS tworzone poza środowiskiem Beanstalk | Elastic Beanstalk |
| „grant S3/SNS permission to invoke function” | Resource-based policy (aws lambda add-permission) | Model Lambdy |
| „function needs to access DynamoDB/S3” | Execution role | Model Lambdy |
| „reuse connections”, „initialize SDK client once” | Kod poza handlerem (INIT) | Model Lambdy |
| „StatusCode 200 but function failed” | X-Amz-Function-Error / FunctionError | Model Lambdy |
| „TooManyRequestsException”, „429”, „Rate exceeded” z Lambdy | Throttling concurrency → reserved concurrency, backoff, podniesienie limitu | Konfiguracja Lambdy |
| „Task timed out after 3.00 seconds” | Zwiększ timeout (domyślnie 3 s, maks. 900 s) | Model Lambdy |
| „longer than 15 minutes” | Step Functions albo ECS/Fargate zamiast Lambdy | Model Lambdy |
| „CPU-bound function slow” | Więcej pamięci (CPU proporcjonalnie) | Konfiguracja Lambdy |
| „guarantee concurrency”, „limit function concurrency”, „protect other functions” | Reserved concurrency | Konfiguracja Lambdy |
| „eliminate cold starts”, „predictable latency” | Provisioned concurrency (wersja/alias) | Konfiguracja Lambdy |
| „Java cold start, low cost” | SnapStart | Konfiguracja Lambdy |
| „shift 10% traffic to new version”, „canary” w Lambdzie | Weighted alias (AdditionalVersionWeights) / CodeDeploy | Konfiguracja Lambdy |
| „share common libraries across functions” | Lambda layers (/opt) | Konfiguracja Lambdy |
| „dependencies larger than 250 MB” | Obraz kontenera (do 10 GB, ECR) | Konfiguracja Lambdy |
| „encrypt environment variables”, „encryption helpers” | KMS customer managed key, kms:Decrypt; lepiej Secrets Manager | Konfiguracja Lambdy |
| „dedicated HTTPS endpoint without API Gateway” | Lambda Function URL (AWS_IAM / NONE) | Konfiguracja Lambdy |
| „Lambda in VPC cannot reach internet” | NAT gateway (lub VPC endpoint dla usług AWS) | Konfiguracja Lambdy |
| „failed async events with error details” | On-failure destination | Wywołania i zdarzenia |
| „notify on success” po async | On-success destination | Wywołania i zdarzenia |
| „one bad message reprocesses whole batch” | ReportBatchItemFailures (batchItemFailures) | Wywołania i zdarzenia |
| „poison record blocks shard” | BisectBatchOnFunctionError, MaximumRetryAttempts, on-failure destination | Wywołania i zdarzenia |
| „consumer can't keep up”, „preserve order per partition key” | ParallelizationFactor (do 10) | Wywołania i zdarzenia |
| „process only matching messages”, „reduce invocations” | ESM FilterCriteria | Wywołania i zdarzenia |
| „limit concurrency from SQS”, „protect downstream database” | ESM ScalingConfig MaximumConcurrency | Wywołania i zdarzenia |
| „messages processed twice”, „duplicate” z SQS | Visibility timeout ≥ 6 × timeout + idempotencja | Wywołania i zdarzenia |
| „exactly once effect”, „idempotent” | Klucz idempotencji w DynamoDB (Powertools Idempotency) | Wywołania i zdarzenia |
| „near real time” + Lambda | Kinesis/DynamoDB Streams + ESM, Firehose z transformacją | Wywołania i zdarzenia |
| „infinite loop”, „recursive invocation” | Recursive loop detection (~16 wywołań) | Wywołania i zdarzenia |
| „containers, least operational overhead” | ECS na Fargate | Kontenery |
| „permissions for the application in the container” | Task role (taskRoleArn) | Kontenery |
| „pull image from private ECR”, „send logs”, „inject secrets” | Task execution role (executionRoleArn) | Kontenery |
| „multiple copies of container on same instance behind ALB” | Dynamic port mapping (bridge, hostPort 0) | Kontenery |
| „minimize number of instances” | Placement strategy binpack | Kontenery |
| „spread across AZs”, „one task per host” | Strategy spread / constraint distinctInstance | Kontenery |
| „docker push fails authentication” | aws ecr get-login-password | docker login | Kontenery |
| „clean up old images” | ECR lifecycle policy | Kontenery |
| „prevent image tags from being overwritten” | ECR tag immutability | Kontenery |
| „scan images for vulnerabilities” | ECR image scanning (basic / enhanced z Inspector) | Kontenery |
| „Kubernetes”, „existing K8s manifests” | Amazon EKS (Pod Identity / IRSA) | Kontenery |
| „unpredictable traffic”, „no capacity planning” (DynamoDB) | DynamoDB on-demand | DynamoDB: pojemność |
| „predictable traffic”, „lowest cost” (DynamoDB) | Provisioned + auto scaling (ew. reserved capacity) | DynamoDB: pojemność |
| „ProvisionedThroughputExceededException” przy niskim zużyciu tabeli | Gorąca partycja → klucz o wysokiej kardynalności, write sharding | DynamoDB: pojemność |
| „read-after-write”, „most up-to-date data” (DynamoDB) | ConsistentRead=true (tabela/LSI, nie GSI) | DynamoDB: pojemność |
| „item larger than 400 KB” | Obiekt w S3, wskaźnik w DynamoDB | DynamoDB: pojemność |
| „most accessed / throttled keys” | CloudWatch Contributor Insights for DynamoDB | DynamoDB: pojemność |
| „reduce consumed RCU” przy Scanie | Query na właściwym kluczu / GSI (nie FilterExpression, nie ProjectionExpression) | DynamoDB: API |
| „speed up scan of a large table” | Parallel scan (Segment, TotalSegments) | DynamoDB: API |
| „prevent overwriting an existing item” | ConditionExpression attribute_not_exists(pk) | DynamoDB: API |
| „concurrent updates”, „lost update”, „version number” | Optimistic locking (atrybut wersji + warunek) | DynamoDB: API |
| „increment counter without reading” | Atomic counter: UpdateItem SET n = n + :inc (nieidempotentny) | DynamoDB: API |
| „all-or-nothing”, „ACID” na wielu elementach DynamoDB | TransactWriteItems / TransactGetItems | DynamoDB: API |
| „UnprocessedItems”, „UnprocessedKeys” | Ponów nieprzetworzone z exponential backoff | DynamoDB: API |
| „SQL-compatible query language for DynamoDB” | PartiQL (ExecuteStatement) | DynamoDB: API |
| „query by a different attribute” na istniejącej tabeli | GSI | DynamoDB: indeksy |
| „alternate sort key” + „strongly consistent” na indeksie | LSI (tylko przy CreateTable) | DynamoDB: indeksy |
| „base table writes throttled because of index” | GSI back-pressure — WCU/klucz GSI | DynamoDB: indeksy |
| „react to item changes”, „before and after image” | DynamoDB Streams (NEW_AND_OLD_IMAGES) + Lambda | DynamoDB: Streams |
| „expire items automatically at no cost” | DynamoDB TTL (Number, sekundy epoch) | DynamoDB: TTL |
| „microsecond latency”, „DynamoDB”, „minimal code changes” | DAX | DynamoDB: DAX |
| „multi-Region active-active”, „low-latency writes in multiple Regions” | DynamoDB global tables | DynamoDB: global tables |
| „restore to any second in the last 35 days” | PITR (do nowej tabeli) | DynamoDB: backup |
| „analytics on DynamoDB without impacting performance” | Export to S3 (PITR) + Athena | DynamoDB: eksport |
| „users can access only their own items” | IAM dynamodb:LeadingKeys + zmienna polityki (np. Cognito sub) | DynamoDB: FGAC |
| „temporary access to a private object”, „without AWS credentials” | S3 presigned URL | S3 |
| „upload large files”, „resume”, „parallel upload” | Multipart upload | S3 |
| „long distance uploads”, „global users upload slowly” | S3 Transfer Acceleration | S3 |
| „503 Slow Down” | Więcej prefiksów + backoff | S3 |
| „unknown or changing access patterns” (S3) | S3 Intelligent-Tiering | S3 |
| „infrequently accessed, re-creatable data” | S3 One Zone-IA | S3 |
| „archive, retrieval within hours, cheapest” | S3 Glacier Deep Archive | S3 |
| „automatically move/delete objects after N days” | S3 Lifecycle (Transition / Expiration) | S3 |
| „recover accidentally deleted objects” | Versioning (usuń delete marker) | S3 |
| „replicate existing objects” | S3 Batch Replication | S3 |
| „replication within 15 minutes SLA” | S3 Replication Time Control | S3 |
| „S3 event to multiple consumers / FIFO / advanced filtering” | S3 → Amazon EventBridge | S3 |
| „browser blocked request to another origin” (S3) | Konfiguracja CORS na zasobniku docelowym | S3 |
| „static website with HTTPS and custom domain” | S3 + CloudFront (OAC) albo Amplify Hosting | S3 |
| „SQL queries directly on files in S3”, „ad hoc”, „serverless” | Amazon Athena | S3 |
| „audit key usage”, „control key rotation” (S3) | SSE-KMS z customer managed key | S3: szyfrowanie |
| „customer-provided keys”, „keys managed outside AWS” | SSE-C (HTTPS, nagłówki x-amz-server-side-encryption-customer-*) | S3: szyfrowanie |
| „encrypt before sending to S3”, „AWS must never see plaintext” | Client-side encryption (S3 Encryption Client) | S3: szyfrowanie |
| „two layers of encryption” | DSSE-KMS | S3: szyfrowanie |
| „reduce KMS costs/requests for S3” | S3 Bucket Keys | S3: szyfrowanie |
| „enforce HTTPS”, „encryption in transit” (S3) | Bucket policy Deny aws:SecureTransport = false | S3: polityki |
| „WORM”, „cannot be deleted even by root” | S3 Object Lock, compliance mode | S3: Object Lock |
| „simplify access for many applications to a shared bucket” | S3 Access Points | S3: access points |
| „disable ACLs”, „bucket owner owns all objects” | Object Ownership: Bucket owner enforced | S3: ACL |
| „high availability”, „automatic failover” (RDS) | Multi-AZ deployment | RDS |
| „scale read traffic”, „reporting queries” (RDS) | Read replicas / Aurora reader endpoint | RDS |
| „too many connections” z Lambdy | Amazon RDS Proxy | RDS |
| „connect to RDS without a password”, „use IAM role” | IAM database authentication (token 15 min) | RDS |
| „variable workload”, „scale to zero” (relacyjna baza) | Aurora Serverless | RDS |
| „cache only data that is requested” | Lazy loading (cache-aside) | Cache |
| „cache data is never stale” | Write-through | Cache |
| „leaderboard”, „sorted sets”, „pub/sub” | ElastiCache (Valkey / Redis OSS) | Cache |
| „simplest cache”, „multithreaded” | ElastiCache for Memcached | Cache |
| „store session state”, „stateless application” | ElastiCache lub DynamoDB | Cache |
| „full-text search”, „log analytics”, „dashboards” | Amazon OpenSearch Service | Cache i magazyny |
| „decouple”, „buffer requests”, „process later”, „worker” | Amazon SQS | SQS |
| „processed more than once”, „duplicate processing” (wolny konsument) | Zwiększ visibility timeout / ChangeMessageVisibility + idempotencja | SQS |
| „empty responses”, „reduce ReceiveMessage calls” | Long polling (WaitTimeSeconds do 20 s) | SQS |
| „strict ordering”, „exactly-once processing”, „no duplicates” (kolejka) | SQS FIFO + MessageGroupId + deduplikacja | SQS |
| „message larger than 256 KB / 1 MB” | SQS/SNS Extended Client Library + S3 | SQS |
| „poison message”, „isolate failed messages”, „reprocess later” | DLQ + maxReceiveCount, DLQ redrive | SQS |
| „delay delivery up to 15 minutes” | SQS delay queue / message timer | SQS |
| „scale workers on queue depth” | ASG target tracking na backlog per instance / ApproximateNumberOfMessagesVisible | SQS |
| „fan-out”, „multiple subscribers receive the same message” | SNS topic → kilka kolejek SQS | SNS |
| „only a subset of messages”, „filter without code” (SNS) | Subscription filter policy (FilterPolicyScope) | SNS |
| „push notification”, „SMS”, „email to users” | Amazon SNS (mobile push, SMS, email) | SNS |
| „ordered fan-out”, „deduplicated fan-out” | SNS FIFO topic → SQS FIFO | SNS |
| „react to AWS service events / state changes / API calls” | Reguła EventBridge (szyna default, CloudTrail events) | EventBridge |
| „SaaS events” (Zendesk, Datadog…) | EventBridge partner event bus | EventBridge |
| „transform event before target without code” | EventBridge input transformer | EventBridge |
| „replay past events”, „reprocess events after bug fix” | EventBridge archive + replay (lub Kinesis) | EventBridge |
| „code bindings”, „discover event structure” | EventBridge schema registry + schema discovery | EventBridge |
| „run once at a specific time”, „time zone”, „millions of schedules” | EventBridge Scheduler | EventBridge |
| „point-to-point integration”, „filter and enrich between source and target” | EventBridge Pipes | EventBridge |
| „call third-party HTTP API from event” | EventBridge API destination + connection | EventBridge |
| „real-time streaming”, „clickstream”, „IoT telemetry”, „multiple consumers read same data” | Kinesis Data Streams | Kinesis |
| „ProvisionedThroughputExceededException” (Kinesis) | Klucz o wysokiej kardynalności, backoff, więcej shardów / on-demand | Kinesis |
| „ordering per key” + „replay” (strumień) | Kinesis Data Streams (partition key, retencja do 365 dni) | Kinesis |
| „dedicated throughput per consumer”, „lowest read latency” | Kinesis enhanced fan-out | Kinesis |
| „near real time”, „load streaming data into S3/Redshift/OpenSearch/Splunk”, „no code” | Amazon Data Firehose | Kinesis |
| „real-time analytics with SQL / Apache Flink” | Amazon Managed Service for Apache Flink | Kinesis |
| „lease table”, „checkpoint” (Kinesis) | KCL + tabela DynamoDB | Kinesis |
| „orchestrate multiple Lambda functions”, „visual workflow”, „retry and error handling without code” | AWS Step Functions | Step Functions |
| „human approval”, „wait for external callback” | Step Functions Standard + .waitForTaskToken | Step Functions |
| „high-volume, short-duration workflows”, „cost per execution” | Step Functions Express | Step Functions |
| „wait for job to complete” (Batch, ECS, Glue) | Integracja .sync | Step Functions |
| „process millions of S3 objects in parallel” | Step Functions Distributed Map | Step Functions |
| „GraphQL”, „single endpoint for multiple data sources”, „real-time subscriptions” | AWS AppSync | AppSync i Amplify |
| „offline sync”, „conflict resolution” (mobile) | AppSync conflict detection (Amplify DataStore) | AppSync i Amplify |
| „host frontend from Git”, „preview per pull request”, „environment per branch” | Amplify Hosting | AppSync i Amplify |
| „Malformed Lambda proxy response”, 502 z API Gateway | Lambda proxy musi zwrócić {statusCode, headers, body} | API Gateway: budowa |
| „transform the request/response”, „without changing the backend” | Non-proxy integration + mapping templates (VTL) | API Gateway: budowa |
| „before the backend is ready”, „return a static response” | Mock integration | API Gateway: budowa |
| „reject invalid requests before invoking Lambda” | Request validator + model (JSON Schema) → 400 | API Gateway: budowa |
| „No 'Access-Control-Allow-Origin' header” | CORS: OPTIONS (mock) dla non-proxy; nagłówki zwraca Lambda przy proxy | API Gateway: budowa |
| „images/binary payload through API Gateway” | binaryMediaTypes + base64 w Lambda proxy | API Gateway: budowa |
| „cheapest API”, „JWT/OIDC authorizer”, „least features” | HTTP API | API Gateway: budowa |
| „accessible only from within a VPC” | Private REST API + interface VPC endpoint + resource policy | API Gateway: budowa |
| „changes not visible to clients” | Redeploy API do stage’a | API Gateway: stage’e |
| „same API, different environments/Lambda aliases” | Stage variables + alias w ARN integracji (+ add-permission) | API Gateway: stage’e |
| „send a small percentage of traffic to the new version of the API” | Canary release na stage’u | API Gateway: stage’e |
| „limit requests per customer”, „monetize API”, „quota per month” | Usage plan + API key | API Gateway: stage’e |
| „429 Too Many Requests” | Throttling (konto/stage/usage plan) → retry z backoff | API Gateway: stage’e |
| „504 Gateway Timeout” z API Gateway | Integracja przekroczyła timeout (domyślnie 29 s) | API Gateway: stage’e |
| „custom authorization logic”, „bearer token from third-party IdP” | Lambda authorizer (TOKEN / REQUEST) | API Gateway: stage’e |
| „reduce calls to the backend for identical GET requests” | Cache stage’a API Gateway (REST) | API Gateway: stage’e |
| „low cache hit ratio” | Zmniejsz klucz cache (cache policy), resztę przez origin request policy | CloudFront |
| „restrict access to S3 bucket only via CloudFront” | Origin Access Control (OAC) + bucket policy z AWS:SourceArn | CloudFront |
| „premium content”, „multiple files without changing URLs” | CloudFront signed cookies | CloudFront |
| „single file, time-limited link via CloudFront” | CloudFront signed URL | CloudFront |
| „lightweight header/URL manipulation at the edge”, „millions of requests” | CloudFront Functions | CloudFront |
| „network call / request body at the edge”, „origin request” | Lambda@Edge | CloudFront |
| „users still see old version after deploy” | Invalidation albo wersjonowane nazwy plików | CloudFront |
| „sign-up and sign-in”, „user directory”, „social login” | Cognito user pool | Cognito |
| „temporary AWS credentials for app users”, „guest access” | Cognito identity pool (authenticated / unauthenticated role) | Cognito |
| „customize claims in the token” | Pre token generation trigger | Cognito |
| „migrate users from legacy system on first login” | User migration trigger | Cognito |
| „authenticate users at the load balancer” | ALB authenticate-cognito / authenticate-oidc (HTTPS listener) | Cognito |
| „encrypt data larger than 4 KB with KMS”, „envelope encryption” | GenerateDataKey + szyfrowanie lokalne | KMS |
| „data key to be used later” | GenerateDataKeyWithoutPlaintext | KMS |
| „ThrottlingException from KMS” | Backoff, data key caching (Encryption SDK), S3 Bucket Keys, wyższa kwota | KMS |
| „temporary, programmatic permission to use a key” | KMS grant | KMS |
| „additional authenticated data”, „bind ciphertext to context” | Encryption context | KMS |
| „same key in multiple Regions” | Multi-Region keys | KMS |
| „automatically rotate database credentials” | Secrets Manager (rotacja Lambda / managed) | Sekrety |
| „hierarchical configuration”, „free”, „cheapest” | Parameter Store (standard) | Sekrety |
| „feature flags”, „gradual configuration rollout”, „automatic rollback” | AWS AppConfig | Sekrety |
| „reduce Secrets Manager API calls from Lambda” | Parameters and Secrets Lambda Extension / caching client | Sekrety |
| „reference a secret in a CloudFormation template” | Dynamic reference {{resolve:secretsmanager:…}} | Sekrety |
| „HTTPS for CloudFront custom domain” | Certyfikat ACM w us-east-1 | Ochrona danych |
| „certificate renewal without manual work” | ACM z walidacją DNS (nie import) | Ochrona danych |
| „private certificates for internal services”, „mutual TLS inside VPC” | AWS Private CA | Ochrona danych |
| „SSH key for EC2 generated locally” | ssh-keygen + aws ec2 import-key-pair | Ochrona danych |
| „SQL injection”, „cross-site scripting”, „OWASP” | AWS WAF (managed rule groups) | Ochrona danych |
| „block IPs that send too many requests” | WAF rate-based rule | Ochrona danych |
| „block traffic from specific countries” | WAF geo match / CloudFront geo restriction | Ochrona danych |
| „mask PII in logs”, „sensitive data in CloudWatch Logs” | CloudWatch Logs data protection policy + logs:Unmask | Ochrona danych |
| „discover PII in S3 buckets” | Amazon Macie | Ochrona danych |
| „tenant isolation in a shared DynamoDB table” | dynamodb:LeadingKeys + ${aws:PrincipalTag/tenant} (session tags) | Ochrona danych |
| „silo / pool / bridge” | Modele izolacji multi-tenant | Ochrona danych |
| „machine-to-machine”, „service without a user”, „OAuth scopes” | Cognito client credentials grant | Ochrona danych |
| „clients authenticate with certificates” | mTLS na custom domain API Gateway (truststore w S3) | Ochrona danych |
| „preview changes before updating the stack”, „will it replace” | Change set (kolumna Replacement) | CloudFormation |
| „share values between stacks”, „independent lifecycles” | Outputs + Export → Fn::ImportValue | CloudFormation |
| „deploy to multiple accounts and Regions” | StackSets | CloudFormation |
| „reusable component that lives with the parent” | Nested stacks (AWS::CloudFormation::Stack) | CloudFormation |
| „keep the bucket/table after stack deletion” | DeletionPolicy: Retain (Snapshot dla RDS, EBS…) | CloudFormation |
| „keep a snapshot of the old database after replacement” | UpdateReplacePolicy: Snapshot | CloudFormation |
| „prevent accidental deletion of the stack” | Termination protection (stack policy chroni przed aktualizacją) | CloudFormation |
| „protect a resource from being replaced or updated” | Stack policy (Update:Replace / Update:Delete) | CloudFormation |
| „wait until the application is ready”, „EC2 signal” | CreationPolicy + cfn-signal | CloudFormation |
| „install packages on instance from the template” | cfn-init + AWS::CloudFormation::Init | CloudFormation |
| „password in the template”, „NoEcho”, „secure” | Dynamic reference {{resolve:secretsmanager/ssm-secure}}; SecureString nie jest typem parametru | CloudFormation |
| „latest AMI” w parametrze | Parametr typu AWS::SSM::Parameter::Value | CloudFormation |
| „InsufficientCapabilities”, „IAM resources in template” | --capabilities CAPABILITY_IAM / CAPABILITY_NAMED_IAM / CAPABILITY_AUTO_EXPAND | CloudFormation |
| „package local code and deploy” | aws cloudformation package, potem deploy | CloudFormation |
| „template larger than 51,200 bytes” | Wgraj do S3 (--template-url, max 1 MB) | CloudFormation |
| „custom logic in a stack”, „empty bucket on delete” | Custom resource (Lambda + ServiceToken) | CloudFormation |
| „actual configuration differs from template” | Drift detection (tylko raportuje) | CloudFormation |
| „rollback on CloudWatch alarm during update” | Rollback triggers (do 5 alarmów) | CloudFormation |
| „UPDATE_ROLLBACK_FAILED” | Continue update rollback (--resources-to-skip) | CloudFormation |
| „ROLLBACK_COMPLETE after create” | Stos można tylko usunąć i utworzyć ponownie | CloudFormation |
| „get ARN of a resource” | Fn::GetAtt (Ref daje nazwę/ID) | CloudFormation |
| „Transform: AWS::Serverless-2016-10-31” | Szablon SAM (CloudFormation z makrem) | SAM i CDK |
| „test Lambda locally”, „without deploying” | sam local invoke / start-api / start-lambda (Docker) | SAM i CDK |
| „sample S3/SQS/API event for testing” | sam local generate-event | SAM i CDK |
| „canary”, „10% then the rest”, „Lambda”, „automatic rollback” | AutoPublishAlias + DeploymentPreference + Alarms (CodeDeploy pod spodem) | SAM i CDK |
| „least privilege for SAM function with minimal effort” | Policy templates (np. S3ReadPolicy) lub AWS::Serverless::Connector | SAM i CDK |
| „different config per environment in SAM CLI” | samconfig.toml + --config-env | SAM i CDK |
| „fast dev sync to cloud” | sam sync --watch (nie na produkcji) | SAM i CDK |
| „infrastructure in TypeScript/Python, loops, abstractions” | AWS CDK (cdk synth → szablon CloudFormation) | SAM i CDK |
| „CDK deploy fails, missing bucket/role” | cdk bootstrap (konto + Region) | SAM i CDK |
| „test CDK infrastructure” | aws-cdk-lib/assertions: fine-grained assertions, snapshot tests | SAM i CDK |
| „L1 / L2 / L3 construct” | L1 = Cfn* 1:1, L2 = domyślne + grant*, L3 = wzorce | SAM i CDK |
| „buildspec.yml”, „build phases” | CodeBuild: install → pre_build → build → post_build | CI/CD |
| „database password in build”, „secure” | env: parameter-store / secrets-manager (nie variables) | CI/CD |
| „docker build in CodeBuild fails”, „Docker daemon” | Privileged mode | CI/CD |
| „CodeBuild access to private RDS and internet” | Konfiguracja VPC + NAT gateway | CI/CD |
| „speed up builds”, „dependencies download” | Cache S3 lub lokalny | CI/CD |
| „show test results in CodeBuild” | Reports (JUnit XML…) | CI/CD |
| „debug build on laptop” | CodeBuild local agent | CI/CD |
| „pause pipeline for human approval”, „email” | Manual approval + temat SNS (7 dni) | CI/CD |
| „trigger on Git tag/branch/file path” | CodePipeline V2 (triggery z filtrami) | CI/CD |
| „cross-account pipeline”, „cannot decrypt artifact” | Customer managed KMS key + rola w drugim koncie | CI/CD |
| „cross-Region action” | Bucket artefaktów w każdej Regionie z akcjami | CI/CD |
| „private package repository”, „npm/pip” | CodeArtifact (domena, repozytorium, upstream) | CI/CD |
| „public registry outage”, „external connection” | CodeArtifact external connection (pobrane wersje zostają) | CI/CD |
| „simplest CI/CD for web app with branches and PR previews” | AWS Amplify Hosting | CI/CD |
| „CodeCommit”, „new customers” | Znów GA od 24.11.2025; w starszych testach „zamknięte dla nowych” | CI/CD |
| „appspec.yml”, „hooks order” | ApplicationStop → BeforeInstall → AfterInstall → ApplicationStart → ValidateService | CodeDeploy |
| „in-place deployment”, „Lambda” | Nie istnieje; Lambda i ECS to blue/green (przesuwanie ruchu) | CodeDeploy |
| „zero downtime and instant rollback” | Blue/green (CodeDeploy, Beanstalk swap URL) | CodeDeploy |
| „least users affected by a bad release” | Canary | CodeDeploy |
| „lowest cost, downtime acceptable” | All at once | CodeDeploy |
| „default deployment configuration EC2” | CodeDeployDefault.OneAtATime | CodeDeploy |
| „Lambda deploy 10% for 5 minutes” | CodeDeployDefault.LambdaCanary10Percent5Minutes | CodeDeploy |
| „validate new Lambda version before traffic” | Hook BeforeAllowTraffic (PutLifecycleEventHookExecutionStatus) | CodeDeploy |
| „test ECS new task set before production traffic” | Test listener + hook AfterAllowTestTraffic | CodeDeploy |
| „rollback” w CodeDeploy | Nowe wdrożenie ostatniej dobrej rewizji (nowy deployment ID); auto po błędzie lub alarmie | CodeDeploy |
| „Missing credentials” w logu agenta | IAM instance profile dla instancji EC2 | CodeDeploy |
| „ApplicationStop fails, new script is fixed” | --ignore-application-stop-failures (skrypt z poprzedniej rewizji) | CodeDeploy |
| „file already exists” podczas wdrożenia | --file-exists-behavior OVERWRITE / RETAIN | CodeDeploy |
| „hook times out after an hour” | Limit skryptu 3 600 s | CodeDeploy |
| „share Lambda test events with team” | Shareable test events (lambda-testevent-schemas) | Testowanie |
| „mock API before backend exists”, „least effort” | API Gateway mock integration | Testowanie |
| „unit test AWS SDK calls without network” | Stub/mock klienta SDK (botocore Stubber, aws-sdk-client-mock) | Testowanie |
| „integration tests must not touch production” | Osobny stos / etap API Gateway / konto + alias Lambdy | Testowanie |
| „reprocess past events after a bug fix” | EventBridge archive + replay | Testowanie |
| „test a single Step Functions state without deploying” | TestState API (inspectionLevel) | Testowanie |
| „Step Functions Local” | Nieobsługiwany; w starszych testach jeszcze poprawna odpowiedź | Testowanie |
| „generate unit tests / review code for vulnerabilities in IDE” | Amazon Q Developer (test generation, code review) | Testowanie |
| „browser terminal with CLI preinstalled” | AWS CloudShell | Testowanie |
| „memory utilization”, „disk space” na EC2 | CloudWatch agent (mem_used_percent, disk_used_percent) | CloudWatch metryki |
| „1-minute metrics for EC2” | Detailed monitoring | CloudWatch metryki |
| „sub-minute”, „every second”, „high resolution” | High-resolution custom metric (StorageResolution=1), alarm 10/30 s | CloudWatch metryki |
| „custom metrics asynchronously”, „from logs”, „embedded” | Embedded Metric Format (EMF), Powertools Metrics | CloudWatch metryki |
| „3 out of 5 data points” | Alarm M z N (DatapointsToAlarm / EvaluationPeriods) | CloudWatch metryki |
| „missing data”, „false alarms when no traffic” | TreatMissingData = notBreaching | CloudWatch metryki |
| „reduce alarm noise”, „only when both” | Composite alarm | CloudWatch metryki |
| „normal pattern changes by time of day”, „expected band” | Anomaly detection alarm | CloudWatch metryki |
| „error rate percentage” | Metric math (Errors/Invocations*100) | CloudWatch metryki |
| „slowest 1% of requests”, „tail latency” | Percentyl p99 | CloudWatch metryki |
| „monitor endpoint / user journey proactively” | CloudWatch Synthetics canary | CloudWatch metryki |
| „SLO”, „application performance monitoring without code changes” | CloudWatch Application Signals | CloudWatch metryki |
| „notify when approaching service quota” | Alarm CloudWatch z konsoli Service Quotas | CloudWatch metryki |
| „notify when deployment succeeds/fails” | EventBridge rule (CodeDeploy Deployment State-change Notification) → SNS | CloudWatch metryki |
| „top contributors”, „which IP causes most errors” | Contributor Insights | CloudWatch metryki |
| „count occurrences of a string in logs and alarm” | Metric filter + alarm | Logi i audyt |
| „stream logs in real time to Kinesis/Firehose/Lambda/OpenSearch” | Subscription filter | Logi i audyt |
| „archive logs to S3 occasionally” | CreateExportTask (nie real-time, do 12 h) | Logi i audyt |
| „query logs”, „ad hoc analysis”, „find slowest invocations” | CloudWatch Logs Insights (filter @type = "REPORT") | Logi i audyt |
| „view logs as they arrive”, „tail -f” | CloudWatch Logs Live Tail | Logi i audyt |
| „logs kept forever”, „reduce log storage cost” | Retention policy na log group (domyślnie bez wygasania) | Logi i audyt |
| „cheaper ingestion for rarely accessed logs” | Log class Infrequent Access | Logi i audyt |
| „encrypt log group with customer managed key” | Symetryczny klucz KMS + associate-kms-key | Logi i audyt |
| „structured logging”, „correlation ID” | Logi JSON, Lambda LogFormat=JSON, Powertools Logger | Logi i audyt |
| „only WARN and above without code change” (Lambda) | Advanced logging controls: ApplicationLogLevel | Logi i audyt |
| „Lambda writes no logs” | Rola wykonawcza bez AWSLambdaBasicExecutionRole | Logi i audyt |
| „who made the API call”, „who deleted” | CloudTrail (Event history 90 dni) | Logi i audyt |
| „who read the S3 object” | CloudTrail data events | Logi i audyt |
| „unusual API activity” | CloudTrail Insights | Logi i audyt |
| „SQL queries on CloudTrail events” | CloudTrail Lake | Logi i audyt |
| „configuration history”, „compliance of resources” | AWS Config | Logi i audyt |
| „end-to-end request path”, „which microservice is slow” | AWS X-Ray (trace, service map) | X-Ray |
| „search/filter traces by custom field”, „indexed” | X-Ray annotations | X-Ray |
| „store additional data in trace, not searchable” | X-Ray metadata | X-Ray |
| „trace more/less without redeploying” | X-Ray sampling rules | X-Ray |
| „UDP port 2000” | X-Ray daemon | X-Ray |
| „X-Ray on ECS” | Daemon jako sidecar + task role z AWSXRayDaemonWriteAccess | X-Ray |
| „X-Ray on Elastic Beanstalk” | XRayEnabled (aws:elasticbeanstalk:xray), .ebextensions | X-Ray |
| „trace Lambda” | Active tracing (TracingConfig Mode=Active, SAM Tracing: Active) | X-Ray |
| „_X_AMZN_TRACE_ID”, „X-Amzn-Trace-Id” | Nagłówek śledzenia X-Ray | X-Ray |
| „vendor-neutral tracing”, „OpenTelemetry” | AWS Distro for OpenTelemetry (ADOT) | X-Ray |
| „capture 100% of spans” | CloudWatch Transaction Search | X-Ray |
| „502 Bad Gateway” z API Gateway | Zły format odpowiedzi Lambda proxy / błąd funkcji | Troubleshooting |
| „504 Gateway Timeout” z API Gateway | Timeout integracji (29 s) → async | Troubleshooting |
| „Missing Authentication Token” | Zła ścieżka/metoda lub brak deploymentu | Troubleshooting |
| „encoded authorization failure message” | aws sts decode-authorization-message | Troubleshooting |
| „ThrottlingException”, „Rate exceeded”, „429” | Exponential backoff z jitter, limity | Troubleshooting |
| „Lambda in VPC can't reach internet” | NAT gateway w publicznej podsieci | Troubleshooting |
| „Unable to import module”, „Runtime.ImportModuleError” | Zły handler lub brak zależności w pakiecie | Troubleshooting |
| „right-size Lambda memory”, „optimal memory” | AWS Lambda Power Tuning / Compute Optimizer | Troubleshooting |
| „most expensive lines of code”, „CPU hotspots” | Amazon CodeGuru Profiler | Troubleshooting |
| „UPDATE_ROLLBACK_FAILED” | ContinueUpdateRollback (--resources-to-skip) | Troubleshooting |
| „CodeDeploy script failed” | scripts.log i codedeploy-agent.log na instancji | Troubleshooting |
| „access instance without SSH / bastion / open ports” | Systems Manager Session Manager | Troubleshooting |
| „run a command on many instances” | Systems Manager Run Command | Troubleshooting |
| „IteratorAge increasing” | Konsument strumienia nie nadąża / trujący rekord | Troubleshooting |
Ściąga: liczby, limity, wartości domyślne
Liczby, które egzamin lubi wplatać w scenariusze. Limity regionalne (soft) można zwykle podnieść przez Service Quotas; limity twarde — nie.
| Serwis · parametr | Wartość / domyślnie | Kiedy ma znaczenie |
|---|---|---|
| AWS SDK · retry_mode | standard (domyślny); adaptive; legacy | Throttling — adaptive dodaje rate limiter |
| AWS SDK · max_attempts | 3 (1 próba + 2 retry); 1 = bez retry | „Zwiększ liczbę ponowień” — AWS_MAX_ATTEMPTS |
| AWS SDK · maks. opóźnienie backoff | 20 s | Długie serie ponowień |
| DynamoDB · ClientRequestToken (TransactWriteItems) | ważny 10 min | Idempotentne ponowienia transakcji |
| IAM · sesja roli (DurationSeconds) | 900 s – maks. session duration roli (1–12 h); domyślnie 1 h | AssumeRole, AssumeRoleWithWebIdentity |
| IAM · role chaining | maks. 1 h | DurationSeconds > 1 h → błąd |
| STS · GetSessionToken / GetFederationToken | 900 s – 129 600 s (36 h); domyślnie 43 200 s (12 h); root: maks. 1 h | Sesja z MFA dla IAM usera |
| IAM · customer managed policy | maks. 6 144 znaki (bez białych znaków) | „Polityka za duża” |
| IAM · inline policies (suma na tożsamość) | user 2 048, grupa 5 120, rola 10 240 znaków | Rozmiar polityk |
| IAM · managed policies na rolę / użytkownika / grupę | 20 (maks. 25) / 10 (maks. 20) / 10 | Za dużo dołączonych polityk |
| IAM · trust policy roli | 2 048 znaków (do 8 192) | Długie listy principali |
| IAM · session policy | maks. 2 048 znaków, do 10 managed policy ARN | Zawężanie sesji |
| IAM · role w koncie | 1 000 (maks. 10 000) | Konta z wieloma rolami |
| IAM · ExternalId | 2–1 224 znaki | Rola dla third party |
| IAM · nazwa roli / nazwa sesji | 64 / 64 znaki | Walidacja nazw |
| EC2 · IMDSv2 token TTL | 1 s – 21 600 s (6 h) | X-aws-ec2-metadata-token-ttl-seconds |
| EC2 · HttpPutResponseHopLimit | 1–64 | Kontenery na EC2 z IMDSv2 — często 2 |
| EC2 · adres IMDS | 169.254.169.254 | Poświadczenia instance profile |
| SigV4 · ważność znacznika czasu żądania | zwykle 5 min | „Signature expired” — zegar maszyny |
| AWS CLI · ec2 wait instance-running | co 15 s, kod 255 po 40 nieudanych sprawdzeniach | Waitery w skryptach |
| AWS CLI · kody wyjścia | 0 OK, 1 błąd transferu S3, 2 parsowanie, 130 Ctrl+C, 252 składnia, 253 konfiguracja, 254 błąd usługi, 255 ogólny | Skrypty CI |
| S3 · ListObjects strona | do 1 000 obiektów | Paginacja |
| CloudShell · trwały storage | 1 GB na region; usuwany po 120 dniach bez sesji | Pliki w $HOME |
| CloudShell · bezczynność | sesja kończy się po 20–30 min | Długie zadania |
| Lambda w VPC · Hyperplane ENI | do 65 000 połączeń/portów na ENI | Skalowanie Lambdy w VPC |
| Lambda w VPC · bezczynność | 14 dni → ENI odzyskana, funkcja Inactive | Pierwsze wywołanie po długiej przerwie się nie udaje |
| Lambda w VPC · usunięcie ENI po odłączeniu | do 20 min | Usuwanie VPC/podsieci |
| VPC · reguły na security group | 60 in + 60 out | Duże listy CIDR |
| VPC · security groups na ENI | 5 (do 16) | Wiele SG na instancji |
| VPC · reguły na network ACL | 20 (do 40) w każdym kierunku | Blokowanie wielu IP |
| VPC · porty efemeryczne (NACL) | 1024–65535 | Odpowiedzi przy stateless NACL |
| VPC Flow Logs · opóźnienie dostarczenia | CloudWatch Logs ok. 5 min, S3 ok. 10 min | „Logi pojawiają się z opóźnieniem” |
| ALB · health check interval / timeout | 5–300 s (domyślnie 30) / 2–120 s (domyślnie 5); cel Lambda: 35 / 30 | Szybkość wykrywania awarii |
| ALB · healthy / unhealthy threshold | 2–10 (domyślnie 5) / 2–10 (domyślnie 2) | Jak szybko cel wypada i wraca |
| ALB · Matcher (success codes) | 200–499, domyślnie 200 | Health check zwracający 3xx/4xx |
| ALB · deregistration delay | 0–3600 s, domyślnie 300 s | Przerywane długie żądania przy wdrożeniu |
| ALB · slow start | 30–900 s, domyślnie 0 (wyłączony) | Rozgrzewka nowych celów |
| ALB · sticky cookie duration | 1 s – 7 dni, domyślnie 1 dzień | AWSALB / ciasteczko aplikacji |
| ALB · idle timeout | domyślnie 60 s | HTTP 504 przy długich żądaniach |
| ALB · połączenie z celem / SSL handshake | 10 s / 10 s | HTTP 504 |
| ALB · Lambda jako cel | request i response maks. 1 MB; 1 funkcja na target group | HTTP 502 przy dużych odpowiedziach |
| ALB · certyfikaty na LB | 25 (bez domyślnego) | SNI dla wielu domen |
| ALB · listenery / target groups / cele | 50 / 100 / 1 000 na LB; 5 target groups na akcję | Duże konfiguracje |
| ELB · cross-zone | ALB: zawsze włączony (wyłączalny per target group); NLB/GWLB: domyślnie wyłączony | Nierówny rozkład ruchu między AZ |
| GWLB · protokół | GENEVE, port 6081 | Appliance’y bezpieczeństwa |
| ASG · default cooldown | 300 s | Simple scaling |
| ASG · health check grace period | konsola 300 s; CLI/SDK 0 s | Instancje terminowane zaraz po starcie |
| ASG · lifecycle hook | domyślnie 1 h (heartbeat); maks. 48 h lub 100× heartbeat | Konfiguracja przed wejściem do ruchu |
| ASG · launch configurations | bez nowych typów instancji od 1.01.2023; nowe konta od 1.10.2024 nie mogą ich tworzyć | Starsze pytania — dziś launch template |
| Route 53 · weighted | wagi 0–255 | Podział ruchu procentowo |
| Route 53 · multivalue answer | do 8 zdrowych rekordów | Prosty rozkład DNS |
| Route 53 · health check | interwał 30 s lub 10 s (fast, płatny); zdrowy, gdy > 18% checkerów; TCP w 4 s; string w pierwszych 5 120 B | DNS failover |
| EC2 · user data | 16 KB (przed base64); domyślnie tylko pierwszy start, jako root | Bootstrap; „skrypt nie działa po restarcie” |
| EC2 · IMDS endpoint | 169.254.169.254 (IPv6: [fd00:ec2::254]) | Metadane, poświadczenia roli instancji |
| EC2 · IMDSv2 token TTL | maks. 21 600 s (6 h) | PUT /latest/api/token |
| EC2 · HttpPutResponseHopLimit | 1–64, domyślnie 1 | Kontenery na EC2 nie dostają tokenu IMDSv2 → ustaw 2 |
| EC2 · basic / detailed monitoring | 5 min (darmowe) / 1 min (płatne); status checks co 1 min | Rozdzielczość metryk CloudWatch |
| EC2 · Spot interruption notice | 2 minuty | Zadania odporne na przerwanie |
| EC2 · Savings Plans / RI | zobowiązanie 1 lub 3 lata | Stałe obciążenie, najtaniej |
| EBS · gp3 | bazowo 3 000 IOPS i 125 MiB/s; maks. 80 000 IOPS, 2 000 MiB/s, 64 TiB (do 09.2025: 16 000 IOPS, 1 000 MiB/s, 16 TiB) | Domyślny wolumen; stare pytania „>16 000 IOPS → io2” |
| EBS · gp2 | 3 IOPS/GiB (100–16 000), burst do 3 000 | IOPS rosną tylko z rozmiarem |
| EBS · io2 Block Express / io1 | do 256 000 / 64 000 IOPS | Najniższa, stała latencja |
| EBS · Multi-Attach | io1/io2, do 16 instancji Nitro, ta sama AZ | Wspólny dysk blokowy; wiele AZ → EFS |
| Beanstalk · wersje aplikacji | 1 000 na region (soft); lifecycle policy usuwa wg liczby lub wieku | „Nie można wdrożyć nowej wersji” |
| Beanstalk · aplikacje / środowiska | 75 / 200 na region (soft) | Limity konta |
| Beanstalk · Traffic splitting | NewVersionPercent domyślnie 10%, EvaluationTime domyślnie 5 min | Canary bez zmiany DNS |
| Beanstalk · deployment Timeout | domyślnie 600 s | Wdrożenie przerwane przez timeout |
| Beanstalk · Procfile / proxy | proxy na porcie 80 → proces web na 5000 (PORT) | Własna komenda startowa |
| Beanstalk worker · VisibilityTimeout | domyślnie 300 s (5 min) | Długie zadania w sqsd |
| Beanstalk worker · MaxRetries | 1–100, domyślnie 10 (potem DLQ) | Wadliwe wiadomości |
| Beanstalk worker · RetentionPeriod | domyślnie 345 600 s (4 dni) | Wiek wiadomości |
| Beanstalk · logi po nieudanym immutable | w S3 przez 1 godzinę | Diagnoza nieudanego wdrożenia |
| Lambda · pamięć | 128–10 240 MB (co 1 MB), domyślnie 128 MB; 1 769 MB = 1 vCPU | Funkcja ograniczona przez CPU → więcej pamięci |
| Lambda · timeout | 1–900 s (15 min), domyślnie 3 s | „Task timed out after 3.00 seconds”; dłużej → Step Functions/ECS |
| Lambda · INIT | 10 s (potem ponowienie z limitem = timeout funkcji) | Ciężka inicjalizacja |
| Lambda · payload sync | 6 MB żądanie i 6 MB odpowiedź | Większe dane: S3 + klucz |
| Lambda · payload async | 1 MB (do 10.2025: 256 KB) | S3/SNS/EventBridge → Lambda; stare pytania o 256 KB |
| Lambda · response streaming | 200 MB (pierwsze 6 MB bez limitu, potem 2 MBps); wcześniej 20 MB | Duże odpowiedzi HTTP, InvokeMode=RESPONSE_STREAM |
| Lambda · zmienne środowiskowe | 4 KB łącznie | Większa konfiguracja → Parameter Store/AppConfig |
| Lambda · warstwy | 5 na funkcję, rozpakowane do /opt, tylko ZIP | Wspólne zależności |
| Lambda · paczka ZIP | 50 MB spakowana (upload bezpośredni), 250 MB rozpakowana z warstwami | Za duże zależności → obraz kontenera |
| Lambda · obraz kontenera | 10 GB | ML, duże biblioteki |
| Lambda · /tmp (ephemeral storage) | 512–10 240 MB, domyślnie 512 MB | Pliki tymczasowe |
| Lambda · concurrency na konto/region | 1 000 (soft); zawsze zostaje 100 niezarezerwowanych | Throttling 429, reserved concurrency |
| Lambda · tempo skalowania | 1 000 środowisk co 10 s na funkcję (10 000 req/s co 10 s) | Nagłe skoki ruchu |
| Lambda · RPS sync | 10 × concurrency na sekundę; PC: 10 × PC na wersję/alias | Throttling przy bardzo krótkich wywołaniach |
| Lambda · storage kodu w regionie | 300 GB (dawniej 75 GB) | Dużo wersji → usuwaj stare |
| Lambda · resource-based policy | 20 KB | Wiele add-permission |
| Lambda · deskryptory plików / procesy | 1 024 / 1 024 | Wycieki połączeń |
| Lambda · --log-type Tail | ostatnie 4 KB logu (base64), tylko sync | Szybki podgląd logu z CLI |
| Lambda · SHUTDOWN | 0 ms bez rozszerzeń, 500 ms z wewnętrznym, 2 000 ms z zewnętrznym | Sprzątanie w rozszerzeniach |
| Lambda · rozliczanie INIT | od 1.08.2025 rozliczane zawsze (także ZIP) | Stare „cold start w ZIP za darmo” |
| Lambda · weighted alias | 2 opublikowane wersje (nie $LATEST) | Canary |
| Lambda · SnapStart | Java 11+, Python 3.12+, .NET 8+; bez PC, EFS, /tmp > 512 MB | Cold start Javy bez kosztu PC |
| Lambda async · ponowienia | 2 (MaximumRetryAttempts 0–2), po ~1 i ~2 min | „Retry = 5 w async” to dystraktor |
| Lambda async · wiek zdarzenia | MaximumEventAgeInSeconds 60 s–6 h (domyślnie 6 h) | Throttling: zdarzenie czeka do 6 h |
| Lambda async · DLQ atrybut ErrorMessage | do 1 KB | DLQ vs destinations |
| Lambda ESM · BatchSize | Kinesis/DDB: domyślnie 100, maks. 10 000; SQS: domyślnie 10, standard do 10 000, FIFO do 10 | Przepustowość konsumenta |
| Lambda ESM · MaximumBatchingWindowInSeconds | 0–300 s; domyślnie 0 (Kinesis/DDB/SQS), 500 ms (Kafka/MQ/DocDB); BatchSize > 10 → okno ≥ 1 s | Mniej wywołań, większe paczki |
| Lambda ESM · FilterCriteria | do 5 filtrów (10 po podniesieniu) | Mniej wywołań |
| Lambda ESM · MaximumRetryAttempts (strumienie) | -1 (nieskończenie, domyślnie) … 10 000 | Shard blokowany przez wadliwy rekord |
| Lambda ESM · MaximumRecordAgeInSeconds | -1 (domyślnie) … 604 800 (7 dni) | Pomijanie starych rekordów |
| Lambda ESM · ParallelizationFactor | 1–10 (Kinesis, DDB Streams) | Konsument nie nadąża za shardem |
| Lambda ESM · TumblingWindowInSeconds | 0–900 s, state do 1 MB na shard | Agregacje w oknach |
| Lambda ESM SQS · MaximumConcurrency | 2–1 000 | Ochrona bazy downstream |
| Lambda ESM SQS · visibility timeout | ≥ 6 × timeout funkcji (+ okno batchowania) | Duplikaty wiadomości |
| Lambda ESM SQS · maxReceiveCount DLQ | zalecane ≥ 5 | DLQ na kolejce, nie na funkcji |
| Lambda ESM SQS · skalowanie | start od 5 paczek, +300 wywołań/min, domyślnie do 1 250 | Szybkość opróżniania kolejki |
| Lambda · recursive loop detection | przerwanie po ~16 wywołaniach | S3 → Lambda → ten sam bucket |
| Lambda · Amazon Linux 2 | koniec wsparcia 30.06.2026 | Wycofywane runtime'y |
| ECR · token logowania | 12 h (get-login-password) | docker login w CI/CD |
| ECR · lifecycle policy | wykonanie do 24 h; niższy priorytet = ważniejsza reguła | Czyszczenie starych obrazów |
| ECS · rolling update (REPLICA) | minimumHealthyPercent 100%, maximumPercent 200% | Wdrożenie bez utraty pojemności |
| ECS · serwis DAEMON | minimumHealthyPercent 0%, maximumPercent 100% | Jeden task na instancję |
| Fargate · rozmiar taska | od 0,25 vCPU / 512 MiB | Najmniejszy task |
| Fargate · ephemeral storage | min. 20 GiB, do 200 GiB (platforma 1.4.0+) | Duże pliki tymczasowe |
| Fargate Spot · przerwanie | ostrzeżenie 2 minuty | Batch, CI |
| ECS · zarezerwowane porty instancji | 22, 2375, 2376, 51678–51680; ephemeral Dockera 49153–65535 | Dynamic port mapping |
| DynamoDB · RCU | 1 strongly consistent / 2 eventually consistent odczyty/s elementu do 4 KB; transactional = 2 RCU / 4 KB | Każde pytanie z obliczaniem RCU |
| DynamoDB · WCU | 1 zapis/s elementu do 1 KB; transactional = 2 WCU / 1 KB | Obliczanie WCU |
| DynamoDB · zaokrąglanie rozmiaru | odczyt w górę do 4 KB, zapis w górę do 1 KB (1 KB = 1024 B) | Rachunek pojemności; Query/Scan sumują rozmiary przed zaokrągleniem |
| DynamoDB · rozmiar elementu | max 400 KB (z nazwami atrybutów) | Duże dane → S3 + wskaźnik |
| DynamoDB · długość klucza | partition key 1–2048 B, sort key 1–1024 B | Projekt kluczy |
| DynamoDB · zagnieżdżenie atrybutów | do 32 poziomów | Dokumenty JSON |
| DynamoDB · partycja | max 3 000 RCU i 1 000 WCU | Gorące klucze, throttling mimo zapasu w tabeli |
| DynamoDB · burst capacity | do 300 s niewykorzystanej pojemności | Krótkie skoki ruchu w provisioned |
| DynamoDB · on-demand, nowa tabela | do 4 000 zapisów/s i 12 000 odczytów/s; natychmiast do 2× poprzedniego szczytu | Skoki ruchu w on-demand, wzrost > 2× w 30 min |
| DynamoDB · zmiana trybu | provisioned → on-demand do 4× w 24 h (okno kroczące); on-demand → provisioned w dowolnym momencie | Pytania o przełączanie trybu (stare testy: raz na 24 h) |
| DynamoDB · zmniejszenia pojemności | 4 na początku doby UTC + 1 na godzinę (do 27/dobę) | Ręczne skalowanie w dół |
| DynamoDB · auto scaling | target utilization 20–90%; reakcja po 2 kolejnych minutach przekroczenia | Konfiguracja auto scalingu |
| DynamoDB · limity przepustowości | 40 000 RCU/WCU na tabelę, 80 000 na konto (provisioned), domyślnie, do podniesienia | Duże obciążenia |
| DynamoDB · tabele | 2 500 na region (domyślnie) | Architektury wielu tabel |
| DynamoDB · Query/Scan | 1 MB na wywołanie (przed filtrem); dalej LastEvaluatedKey | Stronicowanie, brakujące wyniki |
| DynamoDB · parallel scan TotalSegments | 1 – 1 000 000 | Szybki Scan dużej tabeli |
| DynamoDB · BatchGetItem | do 100 elementów, 16 MB | UnprocessedKeys |
| DynamoDB · BatchWriteItem | do 25 Put/Delete, 16 MB; bez Update | UnprocessedItems, brak atomowości |
| DynamoDB · transakcje | do 100 unikalnych elementów, 4 MB, jedno konto i region (stare testy: 25 elementów) | TransactWriteItems / TransactGetItems |
| DynamoDB · ClientRequestToken | ważny 10 minut | Idempotencja transakcji |
| DynamoDB · LSI | max 5 na tabelę; tylko przy CreateTable; 10 GB na wartość partition key | LSI vs GSI |
| DynamoDB · GSI | domyślnie 20 na tabelę; tylko eventual | LSI vs GSI |
| DynamoDB · atrybuty INCLUDE w indeksach | łącznie max 100 we wszystkich indeksach tabeli | Projekcje |
| DynamoDB · GSI multi-attribute keys | do 4 atrybutów w partition key i do 4 w sort key | Klucze złożone bez sklejania stringów |
| DynamoDB Streams · retencja | 24 godziny | Streams vs Kinesis Data Streams (do 1 roku) |
| DynamoDB Streams · czytelnicy shardu | do 2 równocześnie (tabela nie-globalna) | Wielu konsumentów strumienia |
| DynamoDB · TTL | Number, sekundy epoch; usuwanie zwykle w ciągu kilku dni (stare testy: 48 h); bez WCU; ignorowane, jeśli > 5 lat w przeszłości | Wygasanie danych |
| DAX · TTL item cache | domyślnie 5 minut | Nieaktualność danych w DAX |
| DynamoDB · PITR | okres 1–35 dni (domyślnie 35), dokładność do sekundy, odtworzenie do nowej tabeli | Odzyskiwanie po błędzie |
| DynamoDB · eksport do S3 | wymaga PITR; bez zużycia RCU; DynamoDB JSON / Ion | Analityka bez wpływu na tabelę |
| DynamoDB · import z S3 | CSV, DynamoDB JSON, Ion; do nowej tabeli; bez zużycia WCU | Masowe ładowanie danych |
| S3 · pojedynczy PUT | do 5 GB | Kiedy multipart jest wymagany |
| S3 · multipart | części 5 MiB–5 GiB (ostatnia mniejsza), 1–10 000 części; zalecany od ok. 100 MB | Duże uploady |
| S3 · maksymalny obiekt | 48,8 TiB (ok. 50 TB); stare testy: 5 TB | Bardzo duże obiekty |
| S3 · upload w konsoli | do 160 GB | Ręczny upload |
| S3 · wydajność na prefiks | ≥ 3 500 PUT/COPY/POST/DELETE i 5 500 GET/HEAD na sekundę | 503 Slow Down |
| S3 · presigned URL | IAM user + SigV4: do 7 dni; rola/STS: do wygaśnięcia sesji; konsola: 1 min–12 h; CLI domyślnie 3600 s, max 604 800 s | Czasowy dostęp do obiektu |
| S3 · min. okres przechowywania | Standard-IA i One Zone-IA 30 dni; Glacier Instant i Flexible 90 dni; Deep Archive 180 dni | Koszt wczesnego usunięcia/przeniesienia |
| S3 · min. rozliczany rozmiar | 128 KB (Standard-IA, One Zone-IA, Glacier Instant Retrieval) | Małe obiekty w klasach IA |
| S3 · lifecycle małe obiekty | < 128 KB domyślnie nie są przenoszone (od 09.2024) | Reguły transition |
| S3 · Glacier Flexible Retrieval | Expedited 1–5 min, Standard 3–5 h, Bulk 5–12 h | Czas przywracania archiwum |
| S3 · Glacier Deep Archive | Standard do 12 h, Bulk do 48 h | Czas przywracania archiwum |
| S3 · Replication Time Control | 99,9% obiektów w ciągu 15 minut (SLA) | Przewidywalny czas replikacji |
| S3 · trwałość | 99,999999999% (11 dziewiątek) dla wszystkich obecnych klas (poza przestarzałym RRS: 99,99%) | Porównanie klas |
| S3 · dostępność (projekt) | Standard 99,99%; Standard-IA 99,9%; One Zone-IA 99,5% | Porównanie klas |
| S3 · SSE-S3 domyślnie | od 5 stycznia 2023 dla wszystkich nowych obiektów | Szyfrowanie w spoczynku |
| S3 · SSE-C domyślnie zablokowane | od kwietnia 2026 dla nowych zasobników i istniejących w kontach bez obiektów SSE-C (odblokowanie: BlockedEncryptionTypes = NONE w PutBucketEncryption) | Pytania o SSE-C |
| S3 · Bucket Keys | do 99% mniej kosztów żądań KMS | SSE-KMS przy dużym ruchu |
| KMS · operacje kryptograficzne (symetryczne) | 10 000 / 20 000 / 100 000 żądań/s (wspólne, zależnie od regionu) | Throttling SSE-KMS |
| RDS · failover Multi-AZ | zwykle 60–120 s, zmiana DNS | Wysoka dostępność |
| RDS · read replicas | do 15 na instancję źródłową (quota) | Skalowanie odczytów |
| RDS · automated backups | retencja 0–35 dni (0 = wyłączone); domyślnie 7 dni (konsola) / 1 dzień (API/CLI) | Przywracanie do punktu w czasie |
| Aurora · repliki | do 15 Aurora Replicas; lag zwykle znacznie < 100 ms | Skalowanie odczytów, failover |
| Aurora · wolumen | kopie w 3 AZ; do 256 TiB (nowsze wersje) | Trwałość Aurory |
| Aurora Serverless · pojemność | 0–256 ACU, krok 0,5 ACU; 1 ACU ≈ 2 GiB RAM; 0 ACU = auto-pause | Zmienny ruch, dev/test |
| RDS · token IAM DB auth | ważny 15 minut | Uwierzytelnianie bez haseł |
| RDS Proxy · sekrety | do 200 sekretów Secrets Manager na proxy | Wielu użytkowników bazy przez proxy |
| RDS · rotacja hasła zarządzanego przez RDS | domyślnie co 7 dni (Secrets Manager) | Rotacja poświadczeń |
| Athena · rozliczenie | za przeskanowane bajty, w górę do 1 MB, min. 10 MB na zapytanie | Koszt zapytań, partycjonowanie |
| SQS · visibility timeout | domyślnie 30 s; 0 s – 12 h | Podwójne przetwarzanie, ChangeMessageVisibility |
| SQS · retencja wiadomości | domyślnie 4 dni; 60 s – 14 dni | Konsument wyłączony dłużej niż kilka dni |
| SQS · rozmiar wiadomości | 1 MiB (od 08.2025; w starszych testach 256 KB); większe przez Extended Client + S3 do 2 GB | Duże ładunki |
| SQS · long polling | WaitTimeSeconds 0–20 s (0 = short polling, domyślnie) | Puste odpowiedzi, koszt |
| SQS · delay queue / message timer | 0–15 min (domyślnie 0); FIFO tylko delay kolejki | Opóźnienie dostarczenia |
| SQS · batch | 10 wiadomości na wywołanie; łącznie ≤ 1 MiB; ReceiveMessage MaxNumberOfMessages 1–10 | Koszt i przepustowość |
| SQS · atrybuty wiadomości | do 10 na wiadomość | Metadane, filtrowanie SNS → SQS |
| SQS · FIFO przepustowość | 300 wywołań/s na akcję; 3 000 wiadomości/s z batchem; więcej w high throughput mode | Wybór FIFO vs standard |
| SQS · FIFO deduplikacja | okno 5 minut; content-based = SHA-256 z body | Exactly-once processing |
| SQS · in-flight | standard ok. 120 000; FIFO 120 000 (dawniej 20 000) | Błąd OverLimit |
| SQS · PurgeQueue | do 60 s; ponowne wywołanie → PurgeQueueInProgress | Czyszczenie kolejki |
| SQS · KMS data key reuse | 60 s – 24 h, domyślnie 300 s | Koszt i throttling KMS |
| SQS + Lambda · visibility timeout | ≥ 6 × timeout funkcji (zalecenie) | Event source mapping |
| SNS · rozmiar wiadomości | domyślnie 256 KiB; do 1 MiB przez MaximumMessageSize (≤ 100 subskrypcji SQS/Lambda/Firehose) | Duże ładunki, Extended Client |
| SNS · tematy / subskrypcje | standard 100 000 tematów, 12,5 mln subskrypcji na temat; FIFO 1 000 tematów, 100 subskrypcji | Skala fan-outu |
| SNS · filter policy | max 5 kluczy, ≤ 150 kombinacji wartości, 200 polityk na temat; zmiana do 15 min | Projekt filtrów |
| SNS · ponowienia | SQS/Lambda: 100 015 prób w 23 dni; e-mail/SMS/push: 50 prób w 6 h; HTTP/S: własna polityka, max 3 600 s | Utrata wiadomości, DLQ subskrypcji |
| SNS · FIFO deduplikacja | okno 5 minut | FIFO topic |
| SNS · PublishBatch | do 10 wiadomości | Batching |
| EventBridge · PutEvents | do 10 wpisów, łącznie < 1 MB (dawniej 256 KB na zdarzenie) | Duże zdarzenia → S3 + link |
| EventBridge · targety na regułę | 5 (niepodnoszalne) | Fan-out z reguły |
| EventBridge · retry | domyślnie 24 h i 185 prób; MaximumRetryAttempts 0–185, MaximumEventAgeInSeconds 60–86 400 | DLQ (tylko SQS standard) |
| EventBridge · input transformer | do 100 zmiennych w InputPathsMap | Transformacja bez Lambdy |
| EventBridge · archive / replay | retencja domyślnie bez limitu; do 10 równoległych replayów; replay tylko na szynę źródłową | Ponowne przetworzenie |
| EventBridge · szyny / wzorzec | 100 szyn na region; wzorzec do 2 048 znaków | Rzadko |
| EventBridge · API destination | do 300 wywołań/s na każdy API destination (domyślny limit, można podnieść; InvocationRateLimitPerSecond ustawiasz na destination) | Throttling webhooków |
| SQS · delay vs EventBridge Scheduler | SQS max 15 min; Scheduler: one-time, cron, rate, strefy czasowe | Planowanie zadań |
| Kinesis · shard zapis | 1 MB/s lub 1 000 rekordów/s | PTEE, liczba shardów |
| Kinesis · shard odczyt | 2 MB/s (współdzielone), 5 GetRecords/s, do 10 MB / 10 000 rekordów na wywołanie | Wielu konsumentów → EFO |
| Kinesis · enhanced fan-out | 2 MB/s na shard na konsumenta, ok. 70 ms; do 20 konsumentów na strumień (do 50 w trybie On-demand Advantage) | Niskie opóźnienie, wielu czytelników |
| Kinesis · retencja | domyślnie 24 h; do 8 760 h (365 dni) | Replay |
| Kinesis · rekord | domyślnie 1 MiB; do 10 MiB po UpdateMaxRecordSize (od 10.2025; w testach 1 MB) | Duże rekordy |
| Kinesis · PutRecords | do 500 rekordów, do 10 MiB na żądanie (dawniej 5 MiB); bez gwarancji kolejności | Batching, częściowe porażki |
| Kinesis · partition key | do 256 znaków; MD5 → 128-bitowy hash | Rozkład na shardy |
| Kinesis · on-demand | start 4 MB/s zapisu, 8 MB/s odczytu; zmiana trybu 2× na 24 h | Nieprzewidywalny ruch |
| Kinesis + Lambda · ParallelizationFactor | 1–10 (domyślnie 1) | Przyspieszenie konsumenta |
| Firehose · rekord / batch | rekord do 1 000 KiB; PutRecordBatch do 500 rekordów | Direct PUT |
| Firehose · przechowanie przy awarii celu | do 24 h (Direct PUT) | Niedostępny cel |
| Step Functions · czas wykonania | Standard do 1 roku; Express do 5 min | Wybór typu |
| Step Functions · historia | Standard: 90 dni w API, max 25 000 zdarzeń; Express: tylko CloudWatch Logs | Audyt, debug |
| Step Functions · payload | 256 KiB na wejście/wyjście stanu | Duże dane → S3 |
| Step Functions · Retry domyślnie | IntervalSeconds 1, MaxAttempts 3, BackoffRate 2.0 | Obliczanie odstępów |
| Step Functions · Map | Inline do 40 równolegle; Distributed do 10 000 wykonań-dzieci | Przetwarzanie zbiorów |
| Step Functions · sync Express z konsoli | 60 s (pełne 5 min przez SDK/CLI) | StartSyncExecution |
| Step Functions · HTTP Task | timeout max 60 s | Wywołanie API HTTPS |
| AppSync · API key | ważny do 365 dni (można przedłużać) | Publiczne API |
| AppSync · cache TTL | max 3 600 s | Server-side caching |
| API Gateway · throttling konta | 10 000 RPS, burst 5 000 na konto i Region (w niektórych Regionach 2 500 / 1 250) | 429 Too Many Requests przy wielu API w jednym koncie |
| API Gateway · timeout integracji (REST) | 50 ms – 29 s (Regional/private: można podnieść powyżej 29 s); HTTP API: maks. 30 s | 504 przy wolnym backendzie |
| API Gateway · payload | 10 MB | Duże pliki → presigned URL S3 |
| API Gateway · mapping template | 300 KB | Rozbudowane VTL |
| API Gateway · cache | TTL domyślnie 300 s, maks. 3600 s, 0 = wyłączony; 0,5–237 GB; maks. odpowiedź 1 MB | Mniej wywołań backendu, unieważnianie Cache-Control: max-age=0 |
| API Gateway · cache wyniku authorizera | domyślnie 300 s, maks. 3600 s, 0 = wyłączony | Zmiana uprawnień nie działa od razu |
| API Gateway · stage variables | 100 na stage; klucz 64 znaki, wartość 512 znaków | Konfiguracja środowisk |
| API Gateway · canary | percentTraffic 0.0–100.0 | Stopniowe wdrożenie nowego deploymentu |
| API Gateway · usage plans | 300 na konto, 10 na API key, 10 000 API keys | Limity per klient |
| API Gateway · WebSocket | połączenie maks. 2 h, idle 10 min; ramka 32 KB, wiadomość 128 KB; 500 nowych połączeń/s | Czat, powiadomienia na żywo |
| CloudFront · default TTL bez cache policy | 24 h | Origin nie wysyła Cache-Control |
| CloudFront · invalidation | 1 000 ścieżek miesięcznie bez opłat; /* = 1 ścieżka | Częste wdrożenia → wersjonowane nazwy plików |
| CloudFront Functions | pamięć 2 MB, kod 10 KB, submilisekundowo, tylko viewer request/response | Proste przepisywanie nagłówków/URL |
| Lambda@Edge | do 30 s; 128 MB (viewer) / do 10 240 MB (origin); kod 50 MB; do 10 000 RPS na Region; tworzona w us-east-1 (starsze testy: viewer 5 s) | Sieć, body, origin request/response |
| Lambda@Edge · wygenerowana odpowiedź | 40 KB (viewer) / 1 MB (origin) | Odpowiedź generowana na krawędzi |
| CloudFront · limity konta | 20 custom cache policies; 100 CloudFront Functions; 100 skojarzeń L@E na dystrybucję | Duże organizacje |
| Cognito · ważność tokenów | ID i access: 5 min – 1 dzień (domyślnie 1 h); refresh: 60 min – 10 lat (domyślnie 30 dni) | „Użytkownik wylogowany po godzinie” |
| Cognito · Lambda trigger | synchroniczny, odpowiedź w 5 s | Wolny trigger blokuje logowanie |
| Cognito · sesja managed login | cookie sesji ważne 1 h | Ponowne logowanie w hosted UI |
| KMS · Encrypt / Decrypt payload | maks. 4 096 bajtów (4 KB) | Większe dane → GenerateDataKey (envelope) |
| KMS · rotacja automatyczna | domyślnie 365 dni, konfigurowalnie 90–2 560 dni; on-demand maks. 25 razy na klucz | Wymóg compliance „rotuj co rok” |
| KMS · AWS managed keys | rotacja co rok (starsze testy: co 3 lata) | Pytania o rotację kluczy aws/* |
| KMS · usunięcie klucza | okres oczekiwania 7–30 dni, domyślnie 30 | Wycofanie usunięcia: CancelKeyDeletion |
| KMS · kwota żądań kryptograficznych | 10 000 / 20 000 / 100 000 RPS zależnie od Regionu (wspólna); RSA 1 000; custom key store 1 800 | ThrottlingException → backoff, data key caching, S3 Bucket Keys |
| Secrets Manager · rozmiar sekretu | 65 536 bajtów (64 KB) | Duże certyfikaty/JSON |
| Secrets Manager · GetSecretValue | 10 000 żądań/s | Cache po stronie klienta / Lambda extension |
| Secrets Manager · rotacja | najczęściej co 4 h, okno rotacji ≥ 1 h | Harmonogram rate()/cron() |
| Secrets Manager · wersje | ~100 wersji, 20 staging labels na sekret | AWSCURRENT / AWSPENDING / AWSPREVIOUS |
| Parameter Store · standard | 10 000 parametrów, 4 KB, bez opłat, bez policies | „Najtańsza” konfiguracja |
| Parameter Store · advanced | 100 000 parametrów, 8 KB, policies (expiration), sharing, płatny; nie da się cofnąć do standard | Duże wartości, wygasanie parametrów |
| Parameter Store · wersje i hierarchia | 100 wersji; maks. 15 poziomów hierarchii | GetParametersByPath, labels |
| Lambda · zmienne środowiskowe | łącznie 4 KB | Duża konfiguracja → Parameter Store / AppConfig |
| Parameters and Secrets Lambda Extension | localhost:2773; AppConfig Agent: localhost:2772 | Cache konfiguracji w Lambdzie |
| CloudFormation · dynamic references | do 60 na szablon | {{resolve:…}} |
| ACM · publiczny certyfikat | ważny 198 dni; odnowienie 45 dni przed wygaśnięciem; bez opłat dla usług zintegrowanych | Managed renewal (DNS validation) |
| ACM · exportable public certificate | od 17.06.2025, płatny; starsze certyfikaty nieeksportowalne | TLS na EC2 / on-premises |
| ACM · import | klucz prywatny nieszyfrowany, ≤ 5 KB (5 120 B), PEM; brak managed renewal | Certyfikat od zewnętrznego CA |
| ACM · Region | CloudFront i edge-optimized API: us-east-1; ALB/Regional API: ten sam Region | „Certyfikat nie pojawia się na liście” |
| AWS Private CA · short-lived mode | certyfikaty maks. 7 dni; opłata miesięczna za każde CA | Wewnętrzne mTLS |
| EC2 · key pairs | RSA 2048 (Linux/Windows), ED25519 (tylko Linux); nazwa do 255 znaków ASCII | Klucze SSH, import-key-pair |
| WAF · rate-based rule | okno 60/120/300/600 s (domyślnie 300); limit od 10; 2 WCU bazowo | Limit żądań per IP |
| WAF · web ACL capacity | powyżej 1 500 WCU dodatkowa opłata | Duże zestawy reguł |
| WAF · Block | domyślnie HTTP 403 Forbidden | „Klienci dostają 403 po włączeniu WAF” |
| CloudWatch Logs · data protection | 1 polityka na log group (+ polityka konta); do 10 custom data identifiers, regex ≤ 200 znaków | Maskowanie PII w logach |
| CloudFront · field-level encryption | do 10 pól w żądaniu POST | Dane kart widzi tylko jeden serwis |
| STS · session tags | maks. 50 tagów; klucz ≤ 128 znaków, wartość ≤ 256 znaków | ABAC, izolacja tenantów |
CloudFormation · szablon w --template-body | max 51 200 bajtów; z S3 (--template-url) max 1 MB | Większy szablon → S3; deploy wymaga wtedy --s3-bucket |
| CloudFormation · limity szablonu | 500 zasobów, 200 parametrów, 200 outputów, 200 mappings; Description max 1 024 bajty | W starszych testach: 200 zasobów / 60 parametrów / 60 outputów; rozwiązanie to nested stacks |
| CloudFormation · wymagana sekcja | tylko Resources; AWSTemplateFormatVersion jedyna wartość „2010-09-09” | Pytania o „wymagane sekcje” |
| CloudFormation · stosy, nazwy, parametry | 2 000 stosów na konto i Region (podnoszalny); nazwa stosu 128 znaków; wartość parametru 4 096 bajtów; 1 000 stack sets na konto administratora | Rzadko; kontekst skalowania |
| CloudFormation · dynamic references | max 60 w szablonie; nie działają w AWS::CloudFormation::Init ani UserData | Sekrety w szablonie |
| CloudFormation · rollback triggers | do 5 alarmów CloudWatch; monitorowanie 0–180 min (domyślnie 0) | Automatyczny rollback po alarmie |
| CloudFormation · CreationPolicy | Timeout ISO 8601, domyślnie PT5M, max 12 h; dane cfn-signal max 4 096 bajtów | Instalacja w UserData trwa dłużej niż 5 min → zwiększ Timeout |
| CloudFormation · cfn-hup | interwał domyślnie 15 min | Reakcja na zmiany metadanych na żywej instancji |
| CloudFormation · DeletionPolicy | domyślnie Delete; domyślnie Snapshot dla AWS::RDS::DBCluster i DBInstance bez DBClusterIdentifier | S3 i DynamoDB: Retain (Snapshot niewspierany) |
| CloudFormation · Hooks | max 100 hooków na konto i Region | Rzadko |
| CloudFormation · capabilities | CAPABILITY_IAM, CAPABILITY_NAMED_IAM, CAPABILITY_AUTO_EXPAND | Błąd InsufficientCapabilities |
| CloudFormation · Fn::ImportValue | tylko to samo konto i Region | Wiele kont/Regionów → StackSets lub Fn::GetStackOutput |
| CloudFormation · statusy po błędzie | UPDATE_ROLLBACK_COMPLETE; nieudane utworzenie → ROLLBACK_COMPLETE (tylko usunąć); UPDATE_ROLLBACK_FAILED → continue-update-rollback | Co zrobić ze stosem po błędzie |
| AWS Infrastructure Composer · koniec samodzielnej konsoli | 7 grudnia 2026 (według dokumentacji) | Wcześniej „Application Composer” |
| SAM · transform | Transform: AWS::Serverless-2016-10-31 | Brak linii → CloudFormation nie zna typów AWS::Serverless::* |
| SAM · porty lokalne | sam local start-api 3000; sam local start-lambda 3001 | Testy lokalne w Dockerze |
| SAM · DeploymentPreference.Type | Canary10Percent5Minutes / 10 / 15 / 30 Minutes; Linear10PercentEvery1Minute / 2 / 3 / 10 Minutes; AllAtOnce | Canary = 2 kroki, Linear = wiele równych kroków |
| SAM · konfiguracja CLI | samconfig.toml, domyślne środowisko default, --config-env | Wiele środowisk bez powtarzania flag |
| SAM · Globals | wartości proste zastępowane, mapy scalane, listy dokładane | Nadpisywanie ustawień w zasobie |
| CDK · poziomy konstruktów | L1 (Cfn*, 1:1, bez domyślnych), L2 (domyślne + grant*), L3 (wzorce) | Który poziom ma sensowne domyślne wartości |
| CDK · bootstrap | raz na środowisko (konto + Region); stos CDKToolkit (bucket S3, ECR, role IAM) | Błąd o brakującym bucketcie/roli przy cdk deploy |
| CodeBuild · timeout buildu | 5–2 160 min (36 h), domyślnie 60 min | Długie buildy |
| CodeBuild · timeout w kolejce | 5–480 min | Rzadko |
| CodeBuild · privileged mode | domyślnie false | Budowanie obrazów Docker; „Cannot connect to the Docker daemon” |
| CodeBuild · buildspec | version 0.2 (zalecana; 0.1 wspierana); fazy install → pre_build → build → post_build; on-failure ABORT / CONTINUE / RETRY (RETRY-count 0–100) | Faza UPLOAD_ARTIFACTS próbowana zawsze |
| CodeBuild · VPC | do internetu potrzebny NAT gateway (internet gateway nie wystarczy) | Build w VPC musi pobrać paczki |
| CodePipeline · liczba etapów | 2–50 etapów | Rzadko |
| CodePipeline · manual approval | 7 dni bez decyzji = akcja nieudana | Powiadomienie przez SNS; codepipeline:PutApprovalResult |
| CodePipeline · timeouty akcji | CloudFormation 3 dni, CodeDeploy 5 dni, CodeBuild 36 h, manual approval 7 dni | Rzadko |
| CodePipeline · V1 vs V2 | V2: triggery z filtrami (tagi, gałęzie, PR, ścieżki), zmienne pipeline'u, QUEUED/PARALLEL; domyślny tryb SUPERSEDED | Trigger na Git tag → V2 |
| CodeArtifact · token autoryzacji | domyślnie 12 h; --duration-seconds 900–43 200; 0 = do końca sesji roli | aws codeartifact login odnawia token |
| CodeArtifact · upstreamy i external connection | do 10 upstreamów; 1 external connection na repozytorium | Upstream = inne repozytorium CodeArtifact, nie publiczny rejestr |
| CodeCommit · dostępność | lipiec 2024 „de-emphasize”; 24 listopada 2025 powrót do pełnej dostępności (GA) | W starszych testach: „nie przyjmuje nowych klientów” |
| CodeDeploy · timeout hooka (skrypt EC2) | domyślnie i maksymalnie 3 600 s na zdarzenie | Hook „wisi” i pada po godzinie |
| CodeDeploy · domyślna konfiguracja EC2 | CodeDeployDefault.OneAtATime; HalfAtATime (9 instancji: 4 naraz, sukces przy ≥ 5); AllAtOnce | Liczenie instancji i sukcesu wdrożenia |
| CodeDeploy · konfiguracje Lambda/ECS | Lambda: Canary10Percent5/10/15/30Minutes, Linear10PercentEvery1/2/3/10Minute(s), AllAtOnce; ECS: Canary10Percent5/15Minutes, Linear10PercentEvery1/3Minutes, AllAtOnce | Nazwy z prefiksem CodeDeployDefault.Lambda… / ECS… |
| CodeDeploy · hooki Lambda i ECS | Lambda: BeforeAllowTraffic, AfterAllowTraffic; ECS: BeforeInstall, AfterInstall, AfterAllowTestTraffic, BeforeAllowTraffic, AfterAllowTraffic | ValidateService tylko EC2 |
| CodeDeploy · automatyczny rollback | do 50 alarmów CloudWatch na deployment group; rollback = nowe wdrożenie z nowym deployment ID | „Cofnięcie” to nowa rewizja, nie Ctrl+Z |
| CodeDeploy · maks. czas wdrożenia | in-place EC2 12 h; blue/green EC2 109 h; Lambda 50 h (48 h między pierwszym a ostatnim przesunięciem ruchu) | Rzadko |
| CodeDeploy · limity zasobów | do 10 grup ASG w deployment group; 1 000 deployment groups na aplikację; 50 własnych konfiguracji na konto; jedno wdrożenie naraz na grupę | Rzadko |
| CodeDeploy · agent | domyślnie 5 ostatnich rewizji (:max_revisions:) | Logi: /var/log/aws/codedeploy-agent/codedeploy-agent.log |
| Lambda · test events (konsola) | prywatne do 10 na funkcję; shareable w rejestrze schematów lambda-testevent-schemas | Zespół ma używać wspólnych zdarzeń → shareable |
| Step Functions · TestState API | inspectionLevel: INFO, DEBUG, TRACE; z mockiem rola IAM opcjonalna | Step Functions Local nieobsługiwany |
| EventBridge · archive + replay | po utworzeniu archiwum odczekać ok. 10 minut przed replay (według rozdziału) | Ponowne przetworzenie zdarzeń |
| CloudShell · pamięć trwała | 1 GB na Region (bez opłat); dane w nieużywanym Regionie usuwane po 120 dniach | Terminal w przeglądarce |
| Amazon Q Developer · koniec wsparcia wtyczek IDE | 30 kwietnia 2027; następca Kiro | /dev /test /doc to dawne nazwy — dziś opisywane jako capabilities, nie polecenia czatu |
| CloudWatch · retencja metryk | <60 s: 3 h; 1 min: 15 dni; 5 min: 63 dni; 1 h: 455 dni (15 mies.) | „ile czasu mam dane 1-minutowe”; metryk nie da się usunąć |
| CloudWatch · StorageResolution | 1 (high-res) lub 60 (domyślnie); high-res tylko metryki własne | metryki sekundowe, alarmy 10/30 s |
| CloudWatch · alarm high-resolution | okres 10 s lub 30 s (droższy) albo wielokrotność 60 s | szybka reakcja na metryce high-res |
| CloudWatch · PutMetricData | do 1000 metryk, 1 MB (gzip), 30 wymiarów na metrykę, 150 wartości w Values/Counts | batchowanie metryk własnych |
| CloudWatch · znacznik czasu PutMetricData | do 2 tygodni wstecz, do 2 h w przód | dosyłanie zaległych danych |
| CloudWatch · PutMetricData TPS | 500 żądań/s na Region (podnoszalne) | throttling przy metryce w każdej iteracji |
| CloudWatch · EMF | DimensionSet maks. 30 kluczy; Timestamp w ms; wystarczy logs:PutLogEvents | metryki z Lambdy bez PutMetricData |
| Powertools Metrics | do 100 metryk w jednym obiekcie EMF | flush na końcu wywołania |
| EC2 · monitoring | basic: 5 min (status checks 1 min), za darmo; detailed: 1 min, płatny | szybsze skalowanie/alarm |
| CloudWatch · okno ewaluacji alarmu | Period × EvaluationPeriods ≤ 1 dzień (okres < 1 h) lub ≤ 7 dni (okres ≥ 1 h) | długie okna alarmu |
| CloudWatch · TreatMissingData | domyślnie missing; AWS/DynamoDB domyślnie ignore | fałszywe alarmy na rzadkich metrykach |
| CloudWatch · akcje alarmu | przy zmianie stanu; wyjątek: akcje Auto Scaling powtarzają się, dopóki alarm trwa w ALARM | „dlaczego nie ma drugiego maila” |
| CloudWatch Synthetics · canaries | 500 na Region (domyślnie, podnoszalne) | monitoring wielu endpointów |
| CloudWatch Logs · retencja | domyślnie bez wygasania; 1 dzień – 3653 dni (stałe wartości) | koszty, wymogi audytu |
| CloudWatch Logs · rozmiar zdarzenia | 1 024 KB (dawniej 256 KB); batch PutLogEvents 1 MB | duże stack trace'y |
| CloudWatch Logs · PutLogEvents | 5000 TPS na Region (podnoszalne) | throttling przy masowym logowaniu |
| CloudWatch Logs · filtry na log group | 100 metric filters, 5 subscription filters (dawniej 1, potem 2) | kilka odbiorców strumienia logów |
| CloudWatch Logs · metric filter | do 3 wymiarów; nie działa wstecz; podgląd 50 linii | alarm na treści logów |
| CloudWatch Logs · eksport do S3 | dane do 12 h opóźnienia; timeout zadania 24 h; 1 aktywne zadanie na konto | „nie real-time” |
| CloudWatch Logs Insights | zapytanie maks. 60 min; wyniki 7 dni | długie zapytania po dużych zbiorach |
| CloudWatch Logs · Live Tail | 15 równoczesnych sesji (podnoszalne), 10 log groups na sesję; płatne za minutę | debugowanie na żywo |
| CloudWatch Logs · klasa Delivery | zdarzenia trzymane w CloudWatch 2 dni | logi Lambdy do S3/Firehose |
| Lambda · logowanie | domyślnie format Text, poziom aplikacji i systemu INFO; filtrowanie poziomów wymaga JSON | ograniczenie kosztów logów |
| CloudTrail · Event history | 90 dni management events per Region, bez opłat i konfiguracji | „kto usunął zasób” |
| CloudTrail → CloudWatch Logs | średnio ok. 5 min opóźnienia | alarmy na wywołaniach API |
| CloudTrail · integrity validation | pliki digest co godzinę, SHA-256 | dowód niezmienności logów |
| X-Ray · domyślny sampling | 1 żądanie/s (reservoir) + 5% pozostałych | „dlaczego nie widzę wszystkich żądań” |
| X-Ray · Lambda sampling | 1 żądanie/s + 5%, niekonfigurowalny | active tracing w Lambdzie |
| X-Ray · adnotacje | do 50 indeksowanych na trace; string/liczba/Boolean; klucz do 500 znaków (SDK Python) | filter expressions |
| X-Ray · segment document | do 64 kB | duże metadane → osobne subsegmenty |
| X-Ray · retencja | ślady i graf usług 30 dni | analiza historyczna |
| X-Ray · daemon | UDP 2000 (domyślnie 127.0.0.1:2000; sampling po TCP) | ECS sidecar, security group |
| X-Ray · sampling rule | Priority 1–9999; Reservoir na sekundę; Rate 0–100% (JSON: ułamek) | reguły per ścieżka/metoda |
| X-Ray SDK / daemon · wsparcie | maintenance mode od 25.02.2026 (tylko poprawki bezpieczeństwa) | nowe projekty → OpenTelemetry/ADOT |
| Transaction Search | 100% spanów jako logi; ślady do 10 000 spanów | pełna widoczność transakcji |
| API Gateway · timeout integracji | 50 ms – 29 s | 504 przy wolnym backendzie |
| ALB · Lambda | żądanie/odpowiedź > 1 MB → 413/502; połączenie z celem 10 s | 502/504 z ALB |
| Lambda · pamięć | 128 MB (domyślnie, minimum) – 10 240 MB; CPU proporcjonalnie | wolna lub OOM funkcja |
| Lambda · timeout | domyślnie 3 s, maks. 900 s | „Task timed out after 3.00 seconds” |
| Compute Optimizer · Lambda | analiza metryk z ostatnich 14 dni; wymaga opt-in | right-sizing pamięci |
| ECS · zatrzymane taski | widoczne w konsoli przez 1 h | stoppedReason |
| Elastic Beanstalk · logi | tail = ostatnie 100 linii; pliki w S3 usuwane po 15 min | diagnoza wdrożenia |
| CodeDeploy · instancja zakończona w trakcie | status może czekać do 1 h (między zdarzeniami: 5 min) | „wdrożenie wisi” |
| SQS + Lambda · visibility timeout | ≥ 6× timeout funkcji | wielokrotne przetwarzanie |
Egzamin próbny
Pytania w stylu egzaminu. Przy pytaniach wielokrotnego wyboru zaznacz wszystkie odpowiedzi i kliknij „Sprawdź”. Każde wyjaśnienie linkuje do rozdziału z pełną odpowiedzią.
Odpowiedź na pytanie z początku: bez dodatkowej konfiguracji błąd jednej wiadomości oznacza błąd całej
paczki — Lambda nie usuwa żadnej z 10 wiadomości, więc po upływie visibility timeout wszystkie wracają do kolejki
i są przetwarzane ponownie (także te 9 poprawnych). Naprawa: włącz w event source mapping
ReportBatchItemFailures i zwracaj z handlera batchItemFailures z identyfikatorem tylko
tej jednej wiadomości. Dodaj też kolejkę DLQ z maxReceiveCount, żeby „zatruta” wiadomość nie krążyła
w nieskończoność, i pisz konsumenta idempotentnie.
Następny krok: rozwiąż pełny egzamin próbny, a każde pytanie, przy którym się wahałeś, odszukaj tutaj wyszukiwarką. Powodzenia!