Containers are where a lot of DVA-C02 candidates quietly lose points. Serverless (Lambda) gets all the study time, but the exam also expects you to deploy and run containerized applications — and that means Amazon ECS, Amazon ECR, and AWS Fargate. The questions are rarely about Kubernetes-style internals; they’re about the developer’s concerns: where does my image live, which IAM role pulls it, which role does my running code assume, and how do I ship a new version without downtime.
This guide takes a practitioner’s view of containers on AWS for the AWS Certified Developer Associate (DVA-C02) exam. We’ll build up the ECS object model, compare the two launch types, untangle the task role vs task execution role distinction that trips up almost everyone, and walk through ECR, networking, logging, secrets, and deployments — with the exam traps called out as we go.
The ECS Object Model
Amazon ECS (Elastic Container Service) is AWS’s own container orchestrator. Four terms carry most of the exam weight, so get them straight before anything else:
| Term | What it is |
|---|---|
| Task definition | The blueprint — a JSON document describing one or more containers: image, CPU/memory, ports, env vars, IAM roles, log config, volumes. Immutable and versioned (my-app:7). |
| Task | A running instance of a task definition — one or more containers scheduled together, like a Pod. Tasks are ephemeral. |
| Service | A controller that keeps a desired number of tasks running, replaces failed ones, and (optionally) registers them behind a load balancer. |
| Cluster | A logical grouping of tasks/services and, for the EC2 launch type, the container instances they run on. |
The mental model: you register a task definition (version N), a service runs the desired count of tasks from it inside a cluster. To ship a change, you register a new revision of the task definition and update the service to point at it. Task definitions are never edited in place — every change produces a new revision, and that immutability is what makes rollbacks trivial (point the service back at the previous revision).
Container definitions worth remembering
Inside a task definition, each container has fields the exam likes to probe:
essential— if an essential container stops, ECS stops the whole task. Non-essential sidecars can exit without killing the task.cpu/memory/memoryReservation— hard limit vs soft (reservation) limit. On Fargate, task-level CPU/memory must come from the allowed combinations.portMappings— which container ports are exposed.dependsOn— ordering between containers in the same task (e.g. wait for a config sidecar to beHEALTHYfirst).
Launch Types: Fargate vs EC2
ECS gives you two ways to run tasks, and choosing between them is a guaranteed exam theme.
| Fargate | EC2 | |
|---|---|---|
| Who manages servers | AWS (serverless) | You (you run and patch the EC2 container instances) |
| Pricing | Per task vCPU + memory per second | Per EC2 instance (whether tasks fill it or not) |
| Patching / AMI | None — AWS handles it | Your responsibility (ECS-optimized AMI) |
| Best for | Bursty, variable, or ops-light workloads | Steady high utilization, GPU/special instances, cost tuning at scale |
| Daemon workloads | Not for DAEMON scheduling | Supports DAEMON (one task per instance) |
Exam signal words: “no infrastructure to manage,” “least operational overhead,” “don’t want to patch instances” → Fargate. “Maximize cost efficiency at steady high utilization,” “need specific instance types / GPU,” or “run one task on every host” → EC2. Fargate is the modern default answer whenever the question emphasizes reducing operational burden.
There’s a third option you may see referenced — ECS Anywhere (EXTERNAL launch type) lets you run ECS-managed tasks on your own on-premises hardware. Recognize it; it’s rarely the crux of a question.
The Trap Everyone Trips On: Task Role vs Task Execution Role
This is the single highest-yield concept in the whole containers topic, and the wording is deliberately confusing. There are two IAM roles attached to a task, and they do completely different jobs.
| Role | Who uses it | What it’s for |
|---|---|---|
| Task execution role | The ECS agent / Fargate infrastructure | Pulling the image from ECR, sending logs to CloudWatch Logs, reading Secrets Manager / SSM Parameter Store values referenced in the task definition |
| Task role | Your application code inside the container | The permissions your app needs at runtime — e.g. read from S3, write to DynamoDB, publish to SQS |
Read that table twice. The execution role is about setting the task up (pulling images, wiring logs and secrets). The task role is about what your running code is allowed to do. They map to the two IAM roles like this in a task definition:
{
"family": "orders-api",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "512",
"memory": "1024",
"executionRoleArn": "arn:aws:iam::111122223333:role/ecsTaskExecutionRole",
"taskRoleArn": "arn:aws:iam::111122223333:role/orders-api-task-role",
"containerDefinitions": [
{
"name": "orders-api",
"image": "111122223333.dkr.ecr.us-east-1.amazonaws.com/orders-api:7",
"essential": true,
"portMappings": [{ "containerPort": 8080 }]
}
]
}
How the exam tests it:
- “Your container can’t pull its image from ECR” or “logs aren’t reaching CloudWatch” → task execution role is missing permissions.
- “Your application code gets AccessDenied writing to DynamoDB” → task role is missing permissions.
- “Image pull fails with an authorization error on a private ECR repo” → execution role again (it needs
ecr:GetAuthorizationToken,ecr:BatchGetImage,ecr:GetDownloadUrlForLayer).
Never hardcode credentials in the image or as environment variables. The task role delivers temporary credentials to your code automatically through the container credentials endpoint — the AWS SDK picks them up with no configuration, exactly as it would with an instance profile. (For the full credential-resolution story, see working with AWS services in code.)
Amazon ECR: Where Your Images Live
Amazon ECR (Elastic Container Registry) is AWS’s private Docker registry. As a developer you interact with it constantly, and the exam expects you to know the mechanics.
Authenticating and pushing — Docker doesn’t understand IAM, so you exchange an IAM identity for a Docker login token:
# Get a 12-hour auth token and log Docker into the registry
aws ecr get-login-password --region us-east-1 \
| docker login --username AWS --password-stdin \
111122223333.dkr.ecr.us-east-1.amazonaws.com
# Tag and push
docker build -t orders-api .
docker tag orders-api:latest \
111122223333.dkr.ecr.us-east-1.amazonaws.com/orders-api:7
docker push 111122223333.dkr.ecr.us-east-1.amazonaws.com/orders-api:7
That aws ecr get-login-password command is memorization-worthy — it replaced the old aws ecr get-login and shows up verbatim in questions.
Other ECR features the exam rewards you for knowing:
- Image scanning — ECR can scan images for CVEs. Basic scanning (on push or manual) uses the open-source Clair database; enhanced scanning is powered by Amazon Inspector for deeper, continuous OS-and-language-package findings.
- Lifecycle policies — rules that automatically expire old images (e.g. “keep only the last 10 tagged images” or “delete untagged images older than 14 days”) so a repo doesn’t grow forever and rack up storage cost.
- Immutable tags — turn on tag immutability so a tag like
:7can’t be overwritten, guaranteeing that a given tag always refers to the same image (great for reproducible deployments). - Cross-account / cross-Region — control access with a repository policy (resource-based), and use cross-Region / cross-account replication to put images near where tasks run.
- Pull through cache — cache images from public upstream registries in your private ECR, reducing external dependencies.
Networking: awsvpc and the Rest
The task definition’s networkMode determines how containers get network access. For the DVA-C02, the one to know cold is awsvpc.
| Network mode | Behavior | Notes |
|---|---|---|
awsvpc | Each task gets its own ENI and a private IP in your VPC | Required for Fargate; cleanest security-group story (SG per task) |
bridge | Docker’s virtual bridge network (EC2 only) | Uses dynamic host ports; needs dynamic port mapping on the load balancer |
host | Container binds directly to the host’s network (EC2 only) | Fast, but port conflicts limit density |
none | No external connectivity |
With awsvpc, because each task has its own ENI and IP, you attach security groups at the task level — a much simpler model than juggling host ports. A Fargate task in a private subnet still needs a route to the internet (a NAT gateway, or VPC endpoints) to pull an image from ECR or reach CloudWatch — a classic “why does my task fail to start in a private subnet?” question. VPC interface endpoints for ECR (ecr.api, ecr.dkr), S3 (gateway endpoint, since ECR layers live in S3), CloudWatch Logs, and Secrets Manager let a private task run with no NAT gateway at all.
Logging and Observability
Containers are opaque unless you wire up logging. In the task definition, the awslogs log driver streams container stdout/stderr straight to CloudWatch Logs:
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/orders-api",
"awslogs-region": "us-east-1",
"awslogs-stream-prefix": "orders"
}
}
Remember: the task execution role needs logs:CreateLogStream and logs:PutLogEvents for this to work. For higher-volume or multi-destination log routing (CloudWatch, Kinesis Data Firehose, S3, third parties), ECS supports FireLens (a Fluent Bit/Fluentd sidecar). For metrics and tracing, Container Insights gives you cluster/service/task-level CloudWatch metrics, and the X-Ray daemon or the ADOT collector runs as a sidecar for distributed tracing — the same troubleshooting toolkit covered in the DVA-C02 monitoring & optimization guide.
Injecting Configuration and Secrets
Two ways to get configuration into a container, and the exam cares about the difference:
environment— plaintext key/value pairs baked into the task definition. Fine for non-sensitive config; never for secrets (they’re visible in the task definition and console).secrets— references to Secrets Manager secrets or SSM Parameter Store parameters. ECS resolves them at task launch and injects them as environment variables, so the sensitive value never appears in the task definition.
"secrets": [
{ "name": "DB_PASSWORD",
"valueFrom": "arn:aws:secretsmanager:us-east-1:111122223333:secret:prod/db-Ab12Cd" }
]
The permission to fetch those secrets belongs to the task execution role, not the task role — because the resolution happens as part of starting the task, before your code runs. This is one of the most common role mix-ups, so tie it back to the table above.
Deploying New Versions
ECS services support two deployment controllers, and both appear on the exam.
- Rolling update (ECS controller) — the default. ECS incrementally replaces old tasks with new ones, governed by
minimumHealthyPercentandmaximumPercent. For example,minimumHealthyPercent: 100andmaximumPercent: 200keeps full capacity while spinning up the new revision (like “rolling with additional batch” in Elastic Beanstalk). ECS also supports deployment circuit breaker, which automatically rolls back a failed deployment. - Blue/green (CodeDeploy controller) — CodeDeploy stands up a replacement task set, optionally validates it on a test listener, then shifts production traffic (all-at-once, canary, or linear). This is the container-native blue/green pattern, and the appspec + Lambda lifecycle hooks are covered in depth in the DVA-C02 CI/CD guide — that post is your reference for the pipeline, while this one covers the runtime.
To scale the number of tasks with demand, attach Service Auto Scaling — target tracking on CPU, memory, or ALB request count per target, or step scaling on custom CloudWatch alarms. Don’t confuse it with EC2 Auto Scaling: Service Auto Scaling changes the task count; for the EC2 launch type, capacity providers (with managed scaling) adjust the underlying instance count.
ECS Exec: Debugging a Running Task
When you need a shell inside a running container to debug, ECS Exec opens an interactive session without SSH or exposing ports:
aws ecs execute-command --cluster prod \
--task <task-id> --container orders-api \
--interactive --command "/bin/sh"
It requires ECS Exec to be enabled on the service and the task role to allow the SSM messages actions. Recognize it as the modern, auditable alternative to SSHing into a box.
ECS vs Lambda vs Beanstalk: Picking the Compute
The exam loves “which service should this team use” questions. A quick decision guide:
| Choose | When |
|---|---|
| Lambda | Event-driven, short-lived, spiky; want zero server management and per-ms billing (Lambda deep dive) |
| ECS on Fargate | Long-running containers, custom runtimes, >15-min work, want serverless containers |
| ECS on EC2 | Steady high utilization, special instances/GPU, or fine-grained cost control |
| Elastic Beanstalk | Want a guided PaaS that provisions the whole stack from your code |
Common Exam Traps
- Task execution role ≠ task role. Execution role pulls images, ships logs, and reads secrets; task role is what your code can do. This distinction is the most tested idea in the topic.
- Secrets are fetched by the execution role, at launch — not the task role.
- Fargate requires
awsvpcnetwork mode. - A Fargate task in a private subnet needs NAT or VPC endpoints to reach ECR/CloudWatch/Secrets Manager, or it won’t start.
aws ecr get-login-password | docker loginis the current auth command (not the deprecatedaws ecr get-login).- Task definitions are immutable and versioned — you deploy by registering a new revision and updating the service.
- Service Auto Scaling scales tasks; capacity providers scale EC2 instances. Different layers.
- Blue/green on ECS is CodeDeploy, and its keyword is the test listener.
Practice Containers Before Exam Day
Container questions reward candidates who can instantly say “that’s an execution-role problem” or “Fargate needs a NAT gateway there.” The AWS Certified Developer Associate (DVA-C02) Mock Exam Bundle includes eight full-length exams — 520+ questions across all four DVA-C02 domains — with ECS/ECR/Fargate scenarios and explanations that reinforce why each answer is right. Pair it with the DVA-C02 study plan to sequence containers alongside the rest of the deployment domain, and review the exam topics breakdown to see how much weight deployment carries. Because task roles are just IAM roles, a quick pass over the DVA-C02 security guide will cement how permissions flow to your running code.
Frequently Asked Questions
What is the difference between the ECS task role and the task execution role?
The task execution role is used by the ECS agent / Fargate to set up the task — pulling the image from ECR, sending container logs to CloudWatch, and fetching Secrets Manager / Parameter Store values referenced in the task definition. The task role provides the IAM permissions your application code uses at runtime (e.g. reading S3 or writing DynamoDB). Image-pull and log failures are execution-role problems; AccessDenied errors from your own code are task-role problems.
When should I choose Fargate over the EC2 launch type?
Choose Fargate when the priority is minimal operational overhead — no servers to provision, patch, or scale, and per-task billing. Choose EC2 when you need specific instance types (GPU, high memory), want to maximize cost efficiency at steady high utilization, or need DAEMON scheduling (one task per host). “Least operational overhead” almost always points to Fargate.
How does a container authenticate to Amazon ECR?
You exchange your IAM identity for a Docker credential with aws ecr get-login-password --region <region> | docker login --username AWS --password-stdin <account>.dkr.ecr.<region>.amazonaws.com. The token is valid for 12 hours. For a running task, the task execution role must allow ecr:GetAuthorizationToken, ecr:BatchGetImage, and ecr:GetDownloadUrlForLayer so ECS can pull the image.
Why won’t my Fargate task start in a private subnet?
Fargate uses awsvpc networking, so each task needs a network path to pull its image and reach AWS APIs. In a private subnet with no route out, the pull fails. Add a NAT gateway, or create VPC interface endpoints for ECR (ecr.api, ecr.dkr), CloudWatch Logs, and Secrets Manager plus the S3 gateway endpoint (ECR layers live in S3) so the task can start without NAT.
How do I pass secrets to an ECS container securely?
Use the secrets block in the container definition to reference a Secrets Manager secret or SSM Parameter Store parameter by ARN; ECS injects it as an environment variable at launch. Grant the task execution role permission to read the secret. Never put sensitive values in the plaintext environment block.
How does ECS deploy a new version without downtime?
Register a new task definition revision, then update the service. The default rolling update replaces tasks gradually within minimumHealthyPercent/maximumPercent bounds, with an optional deployment circuit breaker for automatic rollback. For validated cutovers, use the CodeDeploy blue/green controller, which shifts traffic (canary/linear/all-at-once) after testing the new task set on a test listener.
Does ECS scale automatically?
Yes — Service Auto Scaling adjusts the number of running tasks using target tracking (CPU, memory, or ALB request count per target) or step scaling. Separately, for the EC2 launch type, capacity providers with managed scaling adjust the number of underlying EC2 instances. Fargate has no instances to scale, so you only manage task count.