Containers on AWS — ECS, ECR, Fargate & EKS

Amazon ECS and Amazon EKS are the two container orchestrators tested on DVA-C02; AWS Fargate is the serverless compute engine that runs tasks/pods on either one without you managing EC2 instances; Amazon ECR is the private image registry that feeds both. The exam mostly lives in ECS/Fargate territory — as a Developer, you write task definitions, wire IAM roles correctly, and reason about networking and deployment strategy far more often than you administer a Kubernetes control plane.

Compute — container orchestration Deploy — task/pod lifecycle Networking — awsvpc & service discovery
2
Launch types — EC2 & Fargate
2
Task IAM roles — role vs execution role
1
Networking mode Fargate requires — awsvpc
ip
ALB target type Fargate tasks must use

Launch Types at a Glance — Memorize This

FARGATENo servers to manage
EC2 LAUNCH TYPEYou manage the instances
EKS + FARGATEK8s pods, serverless compute
EKS + EC2K8s pods, self/managed nodes

What Problem Containers-on-AWS Actually Solve

The Core Mechanism — Orchestration, Registry, and Compute Are Three Separate Jobs
⚠️ The Recurring Exam Theme

Nearly every container question on DVA-C02 tests one of four things: (1) do you know the difference between the task role (permissions the running application code uses to call AWS APIs) and the task execution role (permissions the ECS agent uses to pull the image and write logs before your code even starts), (2) can you explain why Fargate tasks are forced into awsvpc networking mode and what that means for security groups and ALB target types, (3) can you pick ECS vs EKS vs Fargate vs EC2 launch type for a described scenario based on operational-overhead and portability signals, and (4) do you understand how a rolling vs blue/green deployment actually behaves during a release.

Core Components

ComponentWhat It Is
ClusterA logical grouping of tasks/services (ECS) or the managed Kubernetes control plane plus its nodes (EKS). Not itself compute — just a namespace/boundary.
Task DefinitionA JSON blueprint (ECS) describing one or more containers: image, CPU/memory, port mappings, environment variables, IAM roles, logging config, networking mode. Immutable once registered — updates create a new revision.
TaskA running instance of a task definition — one or more containers scheduled together on the same host/ENI.
ServiceMaintains a desired count of tasks, handles replacement of failed tasks, integrates with load balancers and Service Auto Scaling, and drives deployments (rolling/blue-green).
ECR RepositoryA versioned store for container images, private by default, integrated with IAM for push/pull authorization and with ECS/EKS for image pulls.
Pod (EKS)Kubernetes's smallest deployable unit — one or more containers sharing network/storage, the conceptual equivalent of an ECS task.

How It Actually Works — Request-to-Container Flow (ECS on Fargate)

1. Build & Push

Developer builds a Docker image locally or in CI, authenticates to ECR (aws ecr get-login-password), tags and pushes the image to an ECR repository.

2. Register Task Definition

A task definition references the ECR image URI, sets CPU/memory, declares the task role and task execution role, port mappings, and a log configuration (typically awslogs driver to CloudWatch Logs).

3. Create/Update Service

An ECS service on the Fargate launch type is created referencing the task definition, desired task count, subnets/security groups (awsvpc mode), and optionally an ALB target group (target type ip).

4. Scheduler Places Tasks

The ECS scheduler asks Fargate for the requested vCPU/memory capacity; Fargate provisions isolated compute per task (no visible EC2 instance), attaches an ENI in your VPC subnet for each task, and the execution role is used to pull the image from ECR and start the container(s).

5. Register with Load Balancer

Each task's private IP (not an instance ID) registers with the ALB target group as an ip-type target; health checks begin; traffic is routed once healthy.

6. Scale & Deploy

Service Auto Scaling (target tracking on CPU/memory/ALB request count) adjusts desired count; new deployments roll tasks per the configured deployment strategy (rolling by default, blue/green via CodeDeploy if configured).

Exam Domain Relevance

DVA-C02 DomainWhere Containers Show Up
Domain 1: Development with AWS ServicesWriting/updating task definitions, using the ECS/ECR/EKS SDKs and CLI, structuring container-based application code, environment variable and secrets injection
Domain 2: SecurityTask role vs execution role, least-privilege IAM for containers, security groups per task (awsvpc), ECR repository policies and image scanning
Domain 3: DeploymentECS deployment strategies (rolling, blue/green via CodeDeploy), CodePipeline/CodeBuild integration for container CI/CD, ECR lifecycle policies
Domain 4: Troubleshooting & OptimizationDiagnosing task placement/scheduling failures, reading CloudWatch Container Insights and task stopped-reason codes, right-sizing CPU/memory, choosing EC2 vs Fargate for cost/operational tradeoffs

Containers are one of the most heavily-weighted topic clusters on DVA-C02 — expect several scenario questions built directly around ECS task definitions and IAM roles.

Decision Tree — Which Compute/Orchestrator Do I Pick?

Requirement

I need to run a containerized application in AWS

Orchestrator Question

Do I need Kubernetes-specific tooling, existing K8s manifests, or multi-cloud/on-prem portability?

No → Amazon ECS Yes → Amazon EKS
Compute Question

Do I want to manage/patch/scale the underlying EC2 instances myself?

No → AWS Fargate Yes → EC2 launch type / self-managed or managed node groups
Image Source

Amazon ECR (private, IAM-integrated) — or a public/third-party registry if the workload allows it

Networking

Fargate always uses awsvpc mode — each task gets its own ENI and security group. EC2 launch type can use awsvpc, bridge, or host.

Exposure & Scaling

ALB (target type ip for Fargate) for HTTP(S), Cloud Map for internal service discovery, Service Auto Scaling with target tracking for elasticity

Final Summary

Must Memorize
  • Task role = app's AWS permissions; Task execution role = ECS agent's permissions (pull image, write logs, fetch secrets)
  • Fargate requires awsvpc networking mode — one ENI + one security group per task
  • ALB target type must be ip for Fargate tasks (not instance)
  • ECS vs EKS vs Fargate vs EC2 launch type are on two independent axes
  • Task definitions are immutable — updates create new revisions
Must Understand
  • Rolling vs blue/green deployment behavior and when each is appropriate
  • Service Auto Scaling target tracking metrics (CPU, memory, ALB request count per target)
  • Cloud Map service discovery for internal, non-ALB-fronted service-to-service calls
  • ECR lifecycle policies for automated image cleanup
  • When EKS is justified (existing K8s investment/portability) vs when it's operational overkill
Can De-prioritize
  • Deep Kubernetes administration (kubectl internals, CRDs, operators) — DVA-C02 tests EKS at a conceptual/comparison level, not administrator depth
  • Exact per-vCPU/GB Fargate pricing figures
  • Console click-path specifics

Exam appearance probability: HIGH

Components & Configuration Deep Dive

The settings and concepts most likely to show up as the crux of a scenario question.

1.1 Task Definitions Foundational
FormatJSON document, versioned as revisions (family:revision, e.g. my-app:7)
Key fieldsContainer image URI, CPU/memory (task-level and/or container-level), port mappings, environment variables, secrets, log configuration, network mode, task role ARN, execution role ARN
1.2 Task Role vs Task Execution Role Classic exam trap
Task RoleIAM role your application code assumes at runtime to call AWS APIs (e.g. read from S3, write to DynamoDB)
Task Execution RoleIAM role the ECS agent/Fargate infrastructure assumes before your container even starts — to pull the image from ECR, write logs to CloudWatch, and fetch secrets/parameters referenced in the task definition
1.3 Networking — awsvpc Mode Classic exam trap
PurposeGives each task its own elastic network interface (ENI), private IP, and security group(s) — full VPC-native networking per task
FargateMandatory — Fargate tasks have no other networking mode option
EC2 launch typeOptional — can also use bridge (Docker's default NAT'd networking, shared with the host) or host (container uses the host's own network namespace directly)
1.4 Load Balancing — ALB Target Type Classic exam trap
Fargate tasksTarget type must be ip — targets are registered by task private IP, not by EC2 instance ID
EC2 launch type (bridge mode)Target type instance, using dynamic host port mapping, is also valid
1.5 Service Discovery — AWS Cloud Map Medium-high
PurposeDNS- and API-based service discovery for internal service-to-service calls that don't need a load balancer in front
HowECS Service Connect or Service Discovery integration automatically registers/deregisters task IPs in a Cloud Map namespace as tasks start/stop
1.6 Service Auto Scaling Medium-high
PurposeAdjusts a service's desired task count based on demand
MechanismApplication Auto Scaling target tracking (e.g. keep average CPU at 50%), step scaling, or scheduled scaling
1.7 Deployment Strategies High exam relevance
Rolling (default)ECS incrementally replaces old tasks with new ones, controlled by minimumHealthyPercent and maximumPercent deployment configuration
Blue/Green (via CodeDeploy)A second, parallel task set is fully launched and validated before traffic is shifted (all-at-once or linear/canary), with automatic rollback on CloudWatch alarm
1.8 Amazon ECR — Repositories & Image Lifecycle High exam relevance
RepositoryPrivate by default; access controlled via IAM + optional repository policy
Authenticationaws ecr get-login-password piped to docker login — issues a short-lived (12-hour) auth token
Image scanningBasic scanning (on push, OS-package CVEs) or enhanced scanning (continuous, powered by Amazon Inspector, covers OS + language-level packages)
Lifecycle policiesRule-based automatic expiration of old/untagged images (e.g. "keep only the last 10 tagged images" or "expire untagged images after 14 days")
1.9 Amazon EKS — Conceptual Overview Medium (conceptual depth expected)
Control planeFully managed by AWS — API server, etcd, scheduler run across multiple AZs, patched/upgraded by AWS
Data plane optionsSelf-managed EC2 node groups, EKS managed node groups (AWS handles provisioning/lifecycle of the nodes), or Fargate profiles (per-pod serverless compute, no nodes at all)
NetworkingAmazon VPC CNI plugin — pods get real VPC IP addresses, similar in spirit to ECS awsvpc mode

AWS Exam Thinking

Requirement → Keywords → Expected Answer → why every distractor fails.

Run containers with zero server management
no EC2 to manageleast operational overheadserverless containers
Expected Answer

Amazon ECS (or EKS) on AWS Fargate

DistractorWhy it's wrong
ECS/EKS on EC2 launch typeRequires you to provision, patch, and scale the underlying instances
EC2 Auto Scaling Group running Docker directlyNo orchestration, and still full instance management overhead
AWS LambdaViable for short-lived/event-driven workloads, but not for long-running services or workloads needing full container runtime control described in most container scenarios
A task can't pull its image or write logs to CloudWatch
image pull failureno log stream createdagent-level permission
Expected Answer

Fix the Task Execution Role's IAM permissions (ecr:GetDownloadUrlForLayer, logs:CreateLogStream, etc.)

DistractorWhy it's wrong
Task RoleGoverns the app's own AWS API calls at runtime, not image pulls/log delivery, which happen before the app starts
ECR repository policyCould also matter for cross-account access, but the default single-account symptom is almost always an execution-role gap
Security groupControls network reachability, not the identity/authorization used to call ECR or CloudWatch Logs APIs
Application code gets AccessDenied calling S3/DynamoDB from inside a container
app-level API callruntime permission
Expected Answer

Add the missing permission to the Task Role

DistractorWhy it's wrong
Task Execution RoleOnly used by the ECS agent/infrastructure before your code runs — never assumed by your application
Instance profile role (EC2 launch type)Legacy pattern predating per-task IAM roles; would over-grant permissions to every task on that instance
Resource-based policy on the S3 bucket onlyNecessary in cross-account cases but not sufficient on its own if the task role itself lacks the action
Fargate task must be reachable behind an Application Load Balancer
FargateALB target group
Expected Answer

Create the target group with target type "ip"

DistractorWhy it's wrong
Target type "instance"Requires an EC2 instance ID — Fargate tasks have no backing EC2 instance to register
Target type "lambda"For Lambda function targets, unrelated to ECS tasks
Classic Load BalancerLegacy load balancer type, not the modern recommended choice and doesn't resolve the target-type issue
Zero-downtime deployment with automatic rollback if errors spike
automatic rollbackcanary/linear traffic shiftminimize risk
Expected Answer

ECS blue/green deployment via AWS CodeDeploy

DistractorWhy it's wrong
ECS rolling deploymentNo traffic-shifting control and no automatic rollback tied to CloudWatch alarms
Manually swap task definition revisionsFully manual, slow, and error-prone rollback
Route 53 weighted routing between two clustersPossible DIY approach, but far higher operational overhead than the native CodeDeploy integration
Internal service-to-service calls without exposing a public endpoint
internal DNS namemicroservicesno ALB needed
Expected Answer

AWS Cloud Map (ECS Service Discovery / Service Connect)

DistractorWhy it's wrong
Internal ALBWorks but is higher overhead/cost than DNS-based discovery for simple internal calls, and isn't the most direct native answer
Hardcoded IP addressesBreaks immediately on task replacement — IPs are ephemeral per task
Route 53 public hosted zonePublicly exposes the service unnecessarily
ECR storage cost growing from accumulated old images
stale imagesautomatic cleanup
Expected Answer

Configure an ECR lifecycle policy

DistractorWhy it's wrong
Custom Lambda function on a scheduleReinvents a feature ECR already provides natively — more operational overhead than necessary
Manually delete images periodicallyDoesn't scale, error-prone, not automated
Switch to a public registryUnrelated to lifecycle management and changes the security posture unnecessarily
Existing team already runs Kubernetes on-prem and wants workload portability
existing Kubernetes toolingportabilityHelm charts
Expected Answer

Amazon EKS

DistractorWhy it's wrong
Amazon ECSAWS-proprietary API — existing Kubernetes manifests, Helm charts, and operational tooling wouldn't carry over directly
AWS Fargate (standalone)Fargate is a compute engine, not an orchestrator — it still needs ECS or EKS on top
Elastic Beanstalk with Docker platformSimplifies deployment but doesn't provide Kubernetes-native tooling/portability

Integrations & Architecture Example

Related Services

Amazon ECR
WhatPrivate image registry every ECS/EKS task or pod pulls its image from
WhyIAM-native auth, vulnerability scanning, lifecycle policies, cross-region/account replication
PatternCI build → docker push to ECR → task definition references the ECR image URI (often with an immutable digest or tag for reproducibility)
Elastic Load Balancing (ALB/NLB)
WhatRoutes external/internal traffic to running tasks
WhyALB for HTTP(S) with path/host routing; NLB for extreme throughput, static IPs, or non-HTTP protocols
PatternALB target group (type ip for Fargate) ↔ ECS service, health checks drive task replacement
Amazon CloudWatch (Logs, Metrics, Container Insights)
WhatLog delivery via the awslogs driver, CPU/memory metrics, Container Insights for cluster/service/task-level dashboards
WhyCentral observability without instrumenting your own log shipping
AWS X-Ray
WhatDistributed tracing across containerized microservices
WhyIdentify which downstream container/service is causing latency in a multi-service call chain
PatternX-Ray daemon runs as a sidecar container in the same task, or as a DaemonSet on EKS — see 05 — X-Ray Guide
AWS CodePipeline / CodeBuild / CodeDeploy
WhatEnd-to-end CI/CD: build the image, push to ECR, deploy to ECS with a rolling or blue/green strategy
WhyAutomates the build-push-deploy loop; CodeDeploy specifically drives ECS blue/green traffic shifting
PatternSee 02 — CI/CD Guide for the full pipeline mechanics
IAM
WhatTask role, task execution role, ECR repository policies, EKS IAM Roles for Service Accounts (IRSA)
WhyLeast-privilege access at the per-task (ECS) or per-pod-via-service-account (EKS) level, rather than broad instance-level permissions
AWS Secrets Manager / Systems Manager Parameter Store
WhatReferenced directly in a task definition's secrets field
WhyInjects sensitive values as environment variables at container start without baking them into the image or task definition JSON in plaintext — retrieval uses the task execution role
Amazon API Gateway
WhatOptionally fronts an ALB-backed ECS/Fargate service (VPC Link) to add API keys, usage plans, request validation, or Cognito authorization
WhyNeeded when the container service requires API-management features an ALB alone doesn't provide — see 06 — API Gateway Guide

End-to-End Architecture Example

Containerized Web Application with CI/CD and Observability

See 08 — Cross-Service Architectures Guide, Architecture 1, for the fully diagrammed version of this pattern.

Best Practices & Common Exam Traps

When to Use / When NOT to Use

Use ECS/Fargate when…
  • You want container orchestration without adopting Kubernetes's operational model
  • The team wants the lowest operational overhead — no servers, no control plane to manage
  • You're already AWS-native and don't need multi-cloud portability
  • Workloads are long-running services, batch jobs, or scheduled tasks that benefit from per-task IAM and networking isolation
Don't use ECS/Fargate when… (better alternative)
  • You need Kubernetes-native tooling/Helm/CRDs/multi-cloud portability → EKS
  • The workload is short-lived, event-driven, and doesn't need a persistent container runtime → AWS Lambda
  • You want the platform to also manage the underlying environment (OS patching visibility, built-in blue/green via CNAME swap) with less container-specific configuration → Elastic Beanstalk (see 04 — Elastic Beanstalk Guide)
  • Extremely spiky, unpredictable, cost-sensitive workloads where even Fargate's per-second billing is more than needed for tiny bursts → consider Lambda

Comparison — ECS vs EKS

DimensionAmazon ECSAmazon EKS
Orchestration modelAWS-proprietary, simpler API/CLIStandard Kubernetes API — kubectl, manifests, Helm
Operational overheadLower — no control plane to think about, tightly integrated with AWS servicesHigher — even though AWS manages the control plane, you still operate within Kubernetes concepts/add-ons
PortabilityAWS-onlyKubernetes is portable across clouds/on-prem — a major reason teams choose it
EcosystemSmaller, AWS-curatedMassive open-source Kubernetes ecosystem (Helm charts, operators, service meshes)
Compute optionsEC2 launch type or FargateSelf-managed EC2, EKS managed node groups, or Fargate profiles
Best fitTeams that want simplicity and are all-in on AWSTeams with existing Kubernetes investment, multi-cloud strategy, or needing the K8s ecosystem

Comparison — ECS vs Fargate

⚠️ These are not alternatives to each other

This is one of the most common phrasing traps: ECS is the orchestrator (what runs where, service management, deployments). Fargate is a compute engine (where the container actually executes). You always use ECS with either the EC2 launch type or Fargate — "ECS vs Fargate" as a real either/or choice is a category error, though exam questions sometimes phrase it loosely as shorthand for "ECS-on-EC2 vs ECS-on-Fargate."

DimensionECS (orchestrator, always present)Fargate (one of two compute options)
RoleDecides task placement, scaling, deployments, service healthProvides the actual compute a task runs on, serverlessly
You manageTask definitions, services, scaling policiesNothing at the instance/OS level
Alternative computeN/A — ECS always needs a launch typeThe alternative is the EC2 launch type, not "no ECS"

Comparison — Fargate vs EC2 Launch Type

DimensionAWS FargateEC2 Launch Type
Server managementNone — AWS manages the compute entirelyYou provision, patch, and scale the EC2 instances (or use Capacity Providers to automate some of this)
Billing granularityPer-task vCPU/memory-second actually consumedPer EC2 instance-hour, regardless of how tightly tasks are packed
Bin packing / densityNo control — one task gets its own isolated computeYou can pack multiple tasks onto one instance for higher density/lower cost at scale
Networking modeawsvpc onlyawsvpc, bridge, or host
Specialized hardwareLimited (no GPU support in standard Fargate, no custom AMIs)Full flexibility — GPU instances, custom AMIs, specific instance families
Best fitVariable/unpredictable load, teams wanting minimal ops burden, per-task isolation requirementsSteady, high, predictable load where instance-level bin packing meaningfully reduces cost, or workloads needing GPUs/custom AMIs

Common Exam Traps

MisconceptionReality
"The task role and task execution role are the same thing, or interchangeable"They serve completely different purposes: task role = app runtime permissions; execution role = agent-level permissions (image pull, logging, secrets fetch) used before the app starts
"Fargate tasks can use bridge networking mode like EC2 tasks"Fargate mandates awsvpc — there's no shared host to bridge onto
"An ALB target group for ECS is always type 'instance'"Only true for EC2 launch type with bridge/host networking; Fargate requires target type ip
"ECS and Fargate are two alternative orchestrators"Fargate isn't an orchestrator at all — it's a compute engine that ECS (or EKS) schedules tasks/pods onto
"EKS should be the default choice because Kubernetes is more powerful""More powerful" often means "more operational overhead" — if there's no existing Kubernetes requirement, ECS is usually the lower-overhead, exam-preferred answer
"Updating a task definition updates the running tasks in place"Task definitions are immutable; an update creates a new revision, and the service must be redeployed against it for running tasks to change
"ECR image scanning happens automatically on a schedule for every image"Basic scanning runs once on push unless you explicitly configure enhanced/continuous scanning (powered by Amazon Inspector)

Memory Anchors

Hands-On Lab — Build, Break, and Fix Containers on AWS

Three self-contained exercises using AWS CLI v2 in the eu-west-1 region. Exercise 1 builds the full path from a Docker image to a Fargate service behind an ALB. Exercise 2 deliberately breaks the task execution role to reproduce and diagnose a CannotPullContainerError — the hands-on version of the task-role-vs-execution-role trap covered in Components and Best Practices. Exercise 3 is a short EKS/Fargate comparison, kept brief since EKS is tested at the conceptual level on DVA-C02. Replace placeholder values (account ID, VPC/subnet/security-group IDs) with your own before running.

Exercise 1 — Docker Image → ECR → ECS Fargate Behind an ALB

⚠️ Why this exercise matters for the exam

This is the exact request-to-container flow described in the Overview tab's decision flow diagram. Running it once by hand makes the task-definition fields, awsvpc networking, and ip target-type requirement concrete instead of memorized facts.

  1. Create a private ECR repository with scan-on-push enabled.
    aws ecr create-repository \
      --repository-name demo-web-app \
      --region eu-west-1 \
      --image-scanning-configuration scanOnPush=true
    the command returns a repository object whose repositoryUri looks like 123456789012.dkr.ecr.eu-west-1.amazonaws.com/demo-web-app
  2. Build a minimal Docker image locally from a Dockerfile in the current directory (e.g. an nginx-based image serving a static page on port 80).
    docker build -t demo-web-app:v1 .
    docker images lists demo-web-app:v1
  3. Authenticate Docker to ECR, then tag and push the image (replace 123456789012 with your account ID).
    aws ecr get-login-password --region eu-west-1 \
      | docker login --username AWS --password-stdin 123456789012.dkr.ecr.eu-west-1.amazonaws.com
    
    docker tag demo-web-app:v1 123456789012.dkr.ecr.eu-west-1.amazonaws.com/demo-web-app:v1
    
    docker push 123456789012.dkr.ecr.eu-west-1.amazonaws.com/demo-web-app:v1
    the pushed digest appears when you run aws ecr describe-images --repository-name demo-web-app --region eu-west-1

    The get-login-password token is valid for 12 hours — this is the same mechanism CI/CD pipelines use, just invoked manually here.

  4. Create the task execution role — the identity the ECS agent (not your app) uses to pull the image and write logs.
    cat > ecs-trust-policy.json <<'EOF'
    {
      "Version": "2012-10-17",
      "Statement": [{
        "Effect": "Allow",
        "Principal": { "Service": "ecs-tasks.amazonaws.com" },
        "Action": "sts:AssumeRole"
      }]
    }
    EOF
    
    aws iam create-role \
      --role-name demoWebAppExecutionRole \
      --assume-role-policy-document file://ecs-trust-policy.json
    
    aws iam attach-role-policy \
      --role-name demoWebAppExecutionRole \
      --policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
    aws iam list-attached-role-policies --role-name demoWebAppExecutionRole shows AmazonECSTaskExecutionRolePolicy attached
  5. Register a Fargate-compatible task definition referencing the pushed image and the execution role.
    cat > task-def.json <<'EOF'
    {
      "family": "demo-web-app",
      "networkMode": "awsvpc",
      "requiresCompatibilities": ["FARGATE"],
      "cpu": "256",
      "memory": "512",
      "executionRoleArn": "arn:aws:iam::123456789012:role/demoWebAppExecutionRole",
      "containerDefinitions": [{
        "name": "demo-web-app",
        "image": "123456789012.dkr.ecr.eu-west-1.amazonaws.com/demo-web-app:v1",
        "portMappings": [{ "containerPort": 80, "protocol": "tcp" }],
        "essential": true,
        "logConfiguration": {
          "logDriver": "awslogs",
          "options": {
            "awslogs-group": "/ecs/demo-web-app",
            "awslogs-region": "eu-west-1",
            "awslogs-stream-prefix": "demo"
          }
        }
      }]
    }
    EOF
    
    aws ecs register-task-definition \
      --cli-input-json file://task-def.json \
      --region eu-west-1
    response includes "taskDefinitionArn": ".../demo-web-app:1"
  6. Create the ECS cluster and an ALB target group of type ip in your VPC (replace the vpc-id).
    aws ecs create-cluster --cluster-name demo-cluster --region eu-west-1
    
    aws elbv2 create-target-group \
      --name demo-web-app-tg \
      --protocol HTTP --port 80 \
      --vpc-id vpc-0123456789abcdef0 \
      --target-type ip \
      --health-check-path / \
      --region eu-west-1
    target group ARN is returned; note it for the next steps — target type ip is the only valid option because Fargate tasks have no backing EC2 instance
  7. Create the ALB, a listener forwarding to the target group, then create the ECS service (replace subnet/security-group IDs and the target-group/execution-role ARNs).
    aws elbv2 create-load-balancer \
      --name demo-web-app-alb \
      --subnets subnet-aaa111 subnet-bbb222 \
      --security-groups sg-alb0001 \
      --scheme internet-facing --type application \
      --region eu-west-1
    
    aws elbv2 create-listener \
      --load-balancer-arn arn:aws:elasticloadbalancing:eu-west-1:123456789012:loadbalancer/app/demo-web-app-alb/abc123 \
      --protocol HTTP --port 80 \
      --default-actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:eu-west-1:123456789012:targetgroup/demo-web-app-tg/def456 \
      --region eu-west-1
    
    aws ecs create-service \
      --cluster demo-cluster \
      --service-name demo-web-app-svc \
      --task-definition demo-web-app:1 \
      --desired-count 2 \
      --launch-type FARGATE \
      --network-configuration "awsvpcConfiguration={subnets=[subnet-aaa111,subnet-bbb222],securityGroups=[sg-tasks0001],assignPublicIp=DISABLED}" \
      --load-balancers "targetGroupArn=arn:aws:elasticloadbalancing:eu-west-1:123456789012:targetgroup/demo-web-app-tg/def456,containerName=demo-web-app,containerPort=80" \
      --region eu-west-1
    aws ecs describe-services --cluster demo-cluster --services demo-web-app-svc --region eu-west-1 shows runningCount reach desiredCount, and aws elbv2 describe-target-health shows both targets healthy
  8. Verify end to end by hitting the ALB's public DNS name.
    curl -I http://$(aws elbv2 describe-load-balancers \
      --names demo-web-app-alb --region eu-west-1 \
      --query "LoadBalancers[0].DNSName" --output text)
    HTTP/1.1 200 OK from your container, served through the ALB → target group (ip) → Fargate task path

Exercise 2 — Break the Task Execution Role, Reproduce CannotPullContainerError, Fix It

⚠️ Why this exercise matters for the exam

The Components tab flags task role vs task execution role as a classic exam trap. Deliberately breaking it here turns "the execution role pulls the image" from a memorized sentence into something you've watched fail and repaired — the symptom (CannotPullContainerError, tasks stuck cycling PROVISIONING→STOPPED) is a very common Domain 4 troubleshooting scenario.

  1. Detach the ECR/logs policy from the execution role used in Exercise 1, simulating a misconfiguration.
    aws iam detach-role-policy \
      --role-name demoWebAppExecutionRole \
      --policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
    aws iam list-attached-role-policies --role-name demoWebAppExecutionRole now returns an empty AttachedPolicies list
  2. Force a new deployment so ECS launches fresh tasks under the now-crippled role.
    aws ecs update-service \
      --cluster demo-cluster \
      --service demo-web-app-svc \
      --force-new-deployment \
      --region eu-west-1
    the service's deployment stays stuck below desiredCount; new tasks appear briefly then disappear from RUNNING status
  3. List the stopped tasks and inspect the stop reason.
    aws ecs list-tasks \
      --cluster demo-cluster \
      --desired-status STOPPED \
      --region eu-west-1
    
    aws ecs describe-tasks \
      --cluster demo-cluster \
      --tasks <task-arn-from-previous-command> \
      --region eu-west-1 \
      --query "tasks[0].{stoppedReason:stoppedReason,container:containers[0].reason}"
    stoppedReason contains something like CannotPullContainerError: ... 403: Forbidden or a ResourceInitializationError — the image pull failed before your application code ever ran
  4. Diagnose using the same rule taught in the Components tab: if the failure happens before the container starts (image pull, log stream creation), it's the execution role, not the task role. Confirm by checking that no task role permission is involved in this failure path at all — the trust policy and role are the same one referenced as executionRoleArn in task-def.json. you can point at the exact task-definition field (executionRoleArn) responsible, not taskRoleArn
  5. Fix it by reattaching the policy, then force another deployment.
    aws iam attach-role-policy \
      --role-name demoWebAppExecutionRole \
      --policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
    
    aws ecs update-service \
      --cluster demo-cluster \
      --service demo-web-app-svc \
      --force-new-deployment \
      --region eu-west-1
    within a few minutes, runningCount returns to desiredCount and aws elbv2 describe-target-health shows targets healthy again

Exercise 3 — EKS + Fargate Comparison (Brief)

⚠️ Why this exercise matters for the exam

DVA-C02 tests EKS mostly at the "know when to choose it and that Fargate can back it" level, not administrator depth — so this exercise stays short. The point is to see that the same image from Exercise 1, on the same account and region, ends up behind kubectl/Kubernetes manifests instead of ECS's own API, with no EC2 nodes to manage either way.

  1. Create an EKS cluster with a default Fargate profile using eksctl.
    eksctl create cluster \
      --name demo-eks \
      --region eu-west-1 \
      --fargate
    cluster creation completes (10-15 minutes) and kubectl get nodes shows no visible EC2 nodes — pods run on AWS-managed Fargate compute instead
  2. Add a Fargate profile scoped to a dedicated application namespace.
    eksctl create fargateprofile \
      --cluster demo-eks \
      --region eu-west-1 \
      --name demo-web-app-profile \
      --namespace demo-web-app
    eksctl get fargateprofile --cluster demo-eks --region eu-west-1 lists the new profile
  3. Deploy the same ECR image as a Kubernetes Deployment into that namespace.
    kubectl create namespace demo-web-app
    
    cat > deployment.yaml <<'EOF'
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: demo-web-app
      namespace: demo-web-app
    spec:
      replicas: 2
      selector:
        matchLabels: { app: demo-web-app }
      template:
        metadata:
          labels: { app: demo-web-app }
        spec:
          containers:
          - name: demo-web-app
            image: 123456789012.dkr.ecr.eu-west-1.amazonaws.com/demo-web-app:v1
            ports:
            - containerPort: 80
    EOF
    
    kubectl apply -f deployment.yaml
    kubectl get pods -n demo-web-app shows 2 pods in Running state, each scheduled onto Fargate (no node name resembling an EC2 instance)

    Notice what stayed identical to Exercise 1: the ECR image URI and region. What changed: the API surface (Kubernetes manifests + kubectl instead of task definitions + aws ecs), and per-pod IAM would use IRSA rather than a task execution role.

Flashcards — 22 Cards

Click card to flip. Mark right or wrong to track score.

Click to reveal answer
1 / 22
Mark:   Score: 0/0

Practice Quiz — 12 Questions

DVA-C02 scenario style, Easy → Specialty. Select an answer to reveal the explanation.

out of 12 correct