ECR and container images
After this you can answer: Where do the images come from, and how does a task know which one to run?
Picture it
Section titled “Picture it”flowchart TB CD["CD publish job"] -->|"push, tag = git SHA"| ECR[("ECR: api, web, worker")] SSM["SSM /minitickets/dev/image-tag"] --> TD["task definition<br/>image = repo:SHA"] ECR -->|"pull at task start"| TASK["ECS task"] TD --> TASK ECR -->|"pull"| LAMBDA["worker and tickets Lambdas"]How it works
Section titled “How it works”- CD builds once, for ARM64, and pushes
minitickets-dev-api:<sha>,-web:<sha>and-worker:<sha>. - Tags are immutable. Pushing a different image under an existing tag fails. A SHA always means the same bytes.
- The deploy writes the tag to the SSM parameter
/minitickets/dev/image-tag. Pulumi reads it and puts it into each task definition. - ECS pulls the image with the task execution role when a task starts. Lambda pulls the worker image when the function is created or updated.
In MiniTickets
Section titled “In MiniTickets”The three repositories come from one list, imageServices, in
infra/src/names.ts → imageServices, and are made in
infra/src/registry.ts → createRegistry.
scanOnPushruns a basic vulnerability scan on every image.- A lifecycle policy keeps the newest 10 images tagged
deployed-*, the newest 30 other tagged images, and deletes untagged ones after 1 day. - The worker repository has a repository policy that lets the Lambda service pull it, only for
functions named
minitickets-dev-*.
The images must be ARM64, because the tasks run on ARM (Graviton), which is cheaper.
| From → to | What happens | What allows it |
|---|---|---|
| API ECS service → ECR repositoriesonly when computeEnabled = true | ECS pulls the api image when a task starts |
|
| Web ECS service → ECR repositoriesonly when entryEnabled = true | ECS pulls the web image when a task starts |
|
| Worker Lambda → ECR repositoriesonly when computeEnabled = true | the Lambda service pulls the worker image when the function is created or updated |
|
| Tickets Lambda → ECR repositoriesonly when computeEnabled = true | the Lambda service pulls the same worker image for the tickets function |
|
| CD publish job → ECR repositories | docker push api, web and worker :<git sha> |
|
| CD deploy job → ECR repositories | checks the tag exists and adds the tag deployed-<sha> |
|
See it in AWS
Section titled “See it in AWS”ECR → Private registry → Repositories → minitickets-dev-api → Images: tags, pushed at, scan
status.
aws ecr describe-images --repository-name minitickets-dev-api
Break it
Section titled “Break it”| Symptom | Cause | Where to look |
|---|---|---|
| Deploy fails at “Check the image exists in ECR” | The publish job did not push that tag | Publish job log; ECR images |
Tasks stop at once: exec format error | Image built for x86_64, task runs ARM64 | Image manifest; runtimePlatform |
| CannotPullContainerError, no log stream | Execution role lacks the managed policy | IAM → execution role |
Say it in an interview
Section titled “Say it in an interview”Follow-ups
Section titled “Follow-ups”Why immutable tags instead of latest?
With latest, two tasks started a minute apart could run different code, and a rollback would not
know what “before” was. A SHA tag makes every running task traceable to one commit.
What is the deployed- tag for?
After a successful deploy, CD adds a deployed-<sha> tag. The lifecycle policy keeps the newest
10 of those, so a rollback target is never deleted by the cleanup of other images.
What if the scan finds something?
ECR’s basic scan reports findings; it does not block a push. The blocking scan runs earlier, in CI, with Trivy: it fails the build on fixable critical findings.
Advanced: The worker repository policy
Lambda pulls container images with the Lambda service principal, so the worker repository needs a
resource policy, LambdaPullWorkerImage, with an aws:SourceArn condition naming our function
ARNs. Without it, creating or updating the worker Lambda fails with an access error on the image.
Checkpoint
Section titled “Checkpoint”Answer these without scrolling up. If one feels hard, reread that section.
- What is an image tag in MiniTickets, and why can it never change?
- Where does the running tag come from?
- Which role pulls the image for an ECS task?
- Why must the images be ARM64?
- What does the lifecycle policy keep, and why?
Redraw it from memory: CD pushing to ECR, the SSM tag feeding the task definition, ECS and Lambda pulling
Try this: on the map, select ECR repositories and find who may pull from them in the Permissions tab
Read this book online: https://book.theversehub.in/