examhub .cc 用最有效率的方法,考取最有價值的認證
Vol. I
本篇導覽 約 34 分鐘

以 ECS 與 ECR 部署容器

6,800 字 · 約 34 分鐘閱讀

Container deployment is where a DVA-C02 developer earns their keep. Task statement 3.1 of the DVA-C02 exam guide — "prepare application artifacts to be deployed to AWS" — and task statement 3.2 — "test applications in development environments" — both pivot on container deployment skills. In this chapter you will learn container deployment on AWS at the depth a Developer Associate actually needs. That means a real Dockerfile walkthrough with multi-stage builds and non-root users, Amazon ECR push workflows with the AWS CLI credential helper, ECS task definitions wired up with secrets from Secrets Manager, ECS services with the deployment circuit breaker, AWS Fargate platform versions, EFS and FSx volume mounts for stateful workloads, AWS App Runner for zero-decision deploys, the AWS Copilot CLI for scaffolding, and ECS Exec for production debugging. Container deployment on DVA-C02 is a developer-centric topic, so we stay close to the code path throughout.

What Container Deployment Means on AWS

Container deployment on AWS is the end-to-end developer workflow of packaging application code into an OCI-compliant image, pushing that image to a registry, declaring a runtime contract (CPU, memory, networking, IAM, secrets, logs), and handing it to a managed service that runs the container reliably. The DVA-C02 exam tests container deployment across six concrete surfaces:

  • Dockerfile authoring — how you build images that are small, secure, and cache-friendly.
  • Amazon ECR — private and public registries, authentication, tag immutability, lifecycle policies, vulnerability scanning.
  • ECS task definitions — the JSON blueprint that maps Dockerfile output to a running task.
  • ECS services — long-running controllers that keep desired count, do rolling deploys, and integrate with load balancers.
  • Fargate launch type — serverless container compute with no EC2 host management.
  • Developer tooling — AWS Copilot CLI, ECS Exec, AWS App Runner, and deployment guardrails.

Container deployment on DVA-C02 sits right next to iac-sam-cloudformation (the sibling deployment topic) — CloudFormation and SAM often wrap the ECS task definition and service into repeatable stacks, while container deployment handles the image layer and runtime contract. Expect DVA-C02 scenarios to mix both: "developer wants to ship a new image version without downtime" is an ECS rolling deployment answer; "developer wants to declare the full stack in a template" leans on CloudFormation or CDK.

Why Container Deployment Is a Developer Topic, Not an Architect Topic

Where SAA-C03 asks "ECS vs EKS vs Lambda," DVA-C02 assumes you already picked containers and asks "now ship the code." That shift changes the depth. DVA-C02 container deployment expects you to know the exact docker CLI arguments for ECR login, the exact task definition fields for secrets injection, the exact behaviour of the ECS deployment circuit breaker when a new task fails health checks, and the exact IAM role split between task role and execution role. Container deployment on DVA-C02 is developer muscle memory rewritten as exam questions.

白話文解釋 Container Deployment

要把 container deployment 的流程在腦中釘住,最快的方法是用三組不同類別的類比,把 image、registry、runtime contract、deployment control loop 四個核心概念具象化。Container deployment 並不是一串零散的指令,而是一條有節拍的 pipeline。

類比一:快遞與物流體系 (Courier and Logistics System)

把 container deployment 類比成把包裹送到客戶手上的物流鏈:

  • Dockerfile = 打包規格書:寫清楚要用什麼紙箱(base image)、放什麼物品(dependencies)、怎麼疊(layer order)、外箱上要不要貼易碎標籤(healthcheck)。
  • docker build = 實際打包:依照規格書把包裹封好,封好之後包裹就是不可更動的 artifact(image)。
  • Amazon ECR = 集貨倉:所有準備要送的包裹先放在這裡,有門禁(authentication)、有條碼(tags)、有保全(image scanning)、有廢棄規則(lifecycle policy)。
  • ECS Task Definition = 送貨單:說明這個包裹由誰簽收、要在哪個地址(subnet / ENI)、用什麼車(CPU / memory)、跟哪個包裹一起送(sidecar)。
  • ECS Service = 快遞公司排班表:永遠保持 N 個貨車在路上送貨,有貨車壞了馬上補一輛,還會根據訂單量動態加車(auto scaling)。
  • AWS Fargate = 外包車隊:你不用買車、不用養司機,按分鐘結算。
  • AWS App Runner = 機場限時快遞:從取件到送達全自動,連送貨單都幫你填。
  • AWS Copilot CLI = 物流 App:一鍵幫你新增快遞業務、設定分店、自動串好集貨倉到車隊的整條鏈。

這條物流鏈就是 container deployment 在 DVA-C02 的骨架。每一段都有不同的 AWS 服務對應,把責任邊界畫清楚,考題就變成判斷題。

類比二:開書考試與參考書架 (Open-Book Exam and Reference Shelf)

用考試類比重新掃一次 container deployment,把 immutability 與 versioning 的直覺內建:

  • Image tag = 參考書版本號:tag v1.2.3 就是某個定版的書;immutable tag 代表一旦送去印刷就不能改內容。
  • Image digest (sha256) = 書的 ISBN:即使 tag 被覆蓋,只要 digest 相同,內容就一定一樣。考場抓書認 ISBN 最可靠。
  • ECR lifecycle policy = 書架定期清理:每一類書保留最新 N 本,其餘回收,避免書架爆炸。
  • Scan on push = 出版前審稿:書一進倉就掃一次有沒有 CVE,有問題會標記出來。
  • ECS task definition revision = 指定哪一版教材:老師每次改指定教材,都會發新的 revision 編號,舊 revision 還留著可回溯。

Container deployment 這種「版本化的不可變 artifact」思維,是 DVA-C02 的考題主軸;記住「tag 可變、digest 永不變」這條直覺就少踩一大半坑。

類比三:工具箱與工作台 (Toolbox and Workbench)

把 container deployment 的開發者工具鏈類比成工具箱:

  • docker CLI = 手工螺絲起子:直接、原始、什麼都能做,但沒有自動化。
  • AWS CLI + ECR credential helper = 電動起子:幫你自動處理 registry 驗證這個重複動作。
  • AWS Copilot CLI = 瑞士刀:一支刀搞定 VPC、cluster、service、pipeline,適合新專案的第一哩路。
  • AWS SAM / CDK / CloudFormation = 工作台總成:把所有工具與物件固定在模板裡,整套搬來搬去。
  • ECS Exec = 維修檢視鏡:貨車(task)已經在路上跑了,你要看車內狀況,從遠端打一條 SSM session 進去 debug。
  • App Runner = 一鍵壓縮機:丟進原料(source 或 image)就出成品,沒有工具要選。

三個類比交疊之後,container deployment 就不再是零散指令,而是 image → registry → runtime contract → deployment → observability 這條有節奏的開發者工作流。

Dockerfile Best Practices for AWS Container Deployment

A DVA-C02 candidate must be able to read and write Dockerfiles fluently. AWS does not invent its own Dockerfile syntax; the same OCI-compliant Dockerfile runs on ECS, EKS, Fargate, App Runner, Lambda container images, and local Docker. The container deployment quality you ship is therefore set at the Dockerfile layer.

Principle 1 — Multi-Stage Builds for Small, Secure Images

A multi-stage build uses one stage to compile or install dependencies and a second (smaller) stage to produce the final runtime image. Only the output artifacts are copied forward, so build tools, compilers, and dev dependencies never ship to production.

# Stage 1 — build
FROM public.ecr.aws/docker/library/node:20 AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Stage 2 — runtime
FROM public.ecr.aws/docker/library/node:20-slim
WORKDIR /app
COPY --from=build /app/dist ./dist
COPY --from=build /app/node_modules ./node_modules
USER node
EXPOSE 8080
CMD ["node", "dist/server.js"]

Multi-stage builds routinely cut image size by 60–80 percent and reduce the attack surface proportionally. On DVA-C02, any scenario that pairs "reduce image size" with a Dockerfile is answered by multi-stage.

Principle 2 — Pick a Minimal Base Image

Base image choice drives image size, cold start time (Fargate provision pulls the image), and CVE count. Preference order on AWS container deployment:

  • Language-specific slim images (node:20-slim, python:3.12-slim) — usually Debian slim, well-maintained.
  • Alpine images — smaller but use musl libc; occasional compatibility surprises with native modules.
  • Distroless (gcr.io/distroless/...) — only runtime plus your binary, no shell; great for Go and Java, harder to debug without ECS Exec.
  • Amazon Linux 2023 base (public.ecr.aws/amazonlinux/amazonlinux:2023) — AWS-maintained, aligned with Lambda and EC2 base AMIs.

Avoid full ubuntu or debian base images in production unless you have a concrete reason. Container deployment scenarios that hint "minimize image size" are really asking you to multi-stage into a slim, Alpine, or distroless runtime.

Principle 3 — Order Layers for Cache Efficiency

Docker caches each layer by its instruction and input hash. The rule: put instructions that change rarely before instructions that change often. Standard order:

  1. FROM base image.
  2. Install system packages (apt-get install, apk add).
  3. Copy dependency manifest (package.json, requirements.txt, go.mod).
  4. Install dependencies.
  5. Copy application source code.
  6. Build / compile if needed.
  7. CMD or ENTRYPOINT.

If you COPY . . before RUN pip install -r requirements.txt, every source change busts the dependency-install cache. Dockerfile layer ordering is a recurring DVA-C02 exam hint.

Principle 4 — Never Run as Root in Production

Containers escape is rarer with Fargate's Firecracker isolation, but defense-in-depth still demands a non-root user. Either use a language runtime image that ships a non-root user (the official node image has a node user) or create one:

RUN addgroup -S app && adduser -S app -G app
USER app

If the application must bind to port 80, either run a reverse proxy or use port remapping in the task definition (container port 8080 maps to host/target port 80 via the load balancer).

Principle 5 — One Process, Declarative Entrypoint

A container runs one process (plus its children). Avoid supervisord or init wrappers; those belong in sidecars with dedicated task definition container entries. Use the exec form of CMD and ENTRYPOINT:

CMD ["node", "dist/server.js"]

The shell form (CMD node dist/server.js) wraps the command in /bin/sh -c, which breaks signal handling — SIGTERM from ECS during task shutdown never reaches your Node process, tasks time out, and rolling deployments stall.

Use the exec form of CMD or ENTRYPOINT in every Dockerfile that ships to ECS. The shell form wraps your process in /bin/sh, which does not forward SIGTERM, so ECS rolling deployments hit the stopTimeout (30 s default, up to 120 s) before the container gracefully exits. The fix is either exec form or an init like tini as PID 1. Reference: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html

Principle 6 — Add a HEALTHCHECK When ECS Native Health Check Is Not Enough

ECS reads health either from the task definition healthCheck field (Docker-level HEALTHCHECK) or from the load balancer target group. Prefer the load balancer target group for web workloads (it doubles as traffic routing), and use Dockerfile HEALTHCHECK only for non-HTTP workloads or local development.

HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
  CMD curl -fsS http://localhost:8080/healthz || exit 1

For a service behind an ALB, the ALB target group health check already controls traffic routing and ECS will deregister unhealthy tasks automatically. A separate Dockerfile HEALTHCHECK adds load and complexity with no new signal. Use Dockerfile HEALTHCHECK only for non-HTTP workloads or when the target group is not in play. Reference: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html

Amazon ECR Deep Dive for Container Deployment

Amazon ECR is the AWS container registry and the second station on the container deployment pipeline. DVA-C02 tests ECR in heavy detail because this is the hand-off point between developer laptop and AWS runtime.

Authenticating to ECR with the AWS CLI

ECR requires an auth token issued via aws ecr get-login-password. The canonical push workflow:

# 1. Authenticate docker with ECR (12-hour token)
aws ecr get-login-password --region us-east-1 \
  | docker login --username AWS --password-stdin \
  123456789012.dkr.ecr.us-east-1.amazonaws.com

# 2. Tag the local image with the full ECR URI
docker tag myapp:latest \
  123456789012.dkr.ecr.us-east-1.amazonaws.com/myapp:v1.2.3

# 3. Push
docker push 123456789012.dkr.ecr.us-east-1.amazonaws.com/myapp:v1.2.3

The auth token is valid for 12 hours. For CI/CD pipelines, the same get-login-password command works because it pulls IAM credentials from the environment.

A common developer ergonomics upgrade is the Amazon ECR Docker Credential Helper. Install it, add {"credsStore": "ecr-login"} to ~/.docker/config.json, and docker push transparently uses your AWS credentials — no explicit login step. DVA-C02 questions on CI/CD push flows often contrast the two approaches.

Every ECR private repository URI follows the pattern <account-id>.dkr.ecr.<region>.amazonaws.com/<repository-name>:<tag>. Account ID and Region are implicit in the URI; always include both when tagging or pulling. The ECR Public Gallery uses the different host public.ecr.aws/<alias>/<name>:<tag> and is globally distributed. Reference: https://docs.aws.amazon.com/AmazonECR/latest/userguide/Registries.html

Immutable Tags and Digest-Pinned Deployments

ECR supports two tag mutability modes per repository:

  • MUTABLE (default) — the same tag can be overwritten with a new image. Convenient for latest tags but dangerous for production reproducibility.
  • IMMUTABLE — a tag, once assigned, cannot be overwritten or deleted. Any re-push with the same tag fails.

For production container deployment, set tag mutability to IMMUTABLE and deploy by digest (repo@sha256:...) or by versioned tag (v1.2.3). Immutable tags plus digest pinning in task definitions is the DVA-C02 answer to "guarantee the exact image running in production."

Scan on Push and Enhanced Scanning

ECR offers two vulnerability scanning modes:

  • Basic scanning — free, scans image on push against the Clair CVE database. One-shot, results available in minutes.
  • Enhanced scanning — powered by Amazon Inspector, continuously re-scans images for new CVEs even after push, covers OS and language-package vulnerabilities, costs per image per month.

Enable scan on push per repository. For production workloads, Enhanced scanning is the answer when the requirement mentions "continuous scanning" or "alerts on newly discovered CVEs."

ECR Lifecycle Policies

ECR lifecycle policies delete untagged or old images automatically, which is essential because ECR storage is billed per GB-month. A typical policy:

{
  "rules": [
    {
      "rulePriority": 1,
      "description": "Keep last 20 tagged images",
      "selection": {
        "tagStatus": "tagged",
        "tagPrefixList": ["v"],
        "countType": "imageCountMoreThan",
        "countNumber": 20
      },
      "action": { "type": "expire" }
    },
    {
      "rulePriority": 2,
      "description": "Expire untagged images older than 7 days",
      "selection": {
        "tagStatus": "untagged",
        "countType": "sinceImagePushed",
        "countUnit": "days",
        "countNumber": 7
      },
      "action": { "type": "expire" }
    }
  ]
}

Lifecycle rules apply asynchronously — deletions typically happen within 24 hours. DVA-C02 scenarios on "reduce ECR storage cost" are almost always answered with lifecycle policy.

Cross-Account Image Pulls

A common DVA-C02 setup has dev, staging, and prod accounts under AWS Organizations. You build images in the dev account and pull them from staging and prod. Cross-account access is enabled via an ECR repository policy (resource-based policy) that grants ecr:BatchGetImage and ecr:GetDownloadUrlForLayer to the other account's principals. The task execution role in the pulling account also needs ecr:GetAuthorizationToken against its own account.

{
  "Version": "2012-10-17",
  "Statement": [{
    "Sid": "AllowPullFromProd",
    "Effect": "Allow",
    "Principal": { "AWS": "arn:aws:iam::444455556666:root" },
    "Action": [
      "ecr:BatchGetImage",
      "ecr:GetDownloadUrlForLayer"
    ]
  }]
}

Amazon ECR Public Gallery hosts publicly accessible images under public.ecr.aws/. AWS publishes base images there (Amazon Linux, Lambda runtimes, EKS distro), and third parties can publish too. Anonymous pulls work without authentication; authenticated pulls via aws ecr-public get-login-password raise rate limits. For container deployment, pulling public base images from public.ecr.aws in your Dockerfile avoids Docker Hub rate-limiting (100 pulls per 6 hours for anonymous users).

Authenticate with aws ecr get-login-password --region <r> | docker login --username AWS --password-stdin <account>.dkr.ecr.<r>.amazonaws.com, tag with docker tag local:tag <account>.dkr.ecr.<r>.amazonaws.com/<repo>:<tag>, and push with docker push <account>.dkr.ecr.<r>.amazonaws.com/<repo>:<tag>. The auth token lasts 12 hours. This three-step sequence is the most-asked ECR hands-on procedure on DVA-C02. Reference: https://docs.aws.amazon.com/AmazonECR/latest/userguide/registry_auth.html

ECS Task Definition — The Runtime Contract

The ECS task definition is the JSON (or YAML via SAM / CloudFormation) blueprint that tells ECS how to run your container. DVA-C02 expects field-level familiarity — below is what you need.

Task-Level Fields

  • family — logical name; task definitions are versioned by family:revision.
  • requiresCompatibilities["FARGATE"] or ["EC2"] or both.
  • networkModeawsvpc (mandatory for Fargate), bridge, host, or none (EC2 only).
  • cpu and memory — total for the task. Fargate has fixed supported combinations (0.25 vCPU with 0.5–2 GB, up to 16 vCPU with 30–120 GB). EC2 is flexible.
  • executionRoleArn — IAM role Fargate / ECS assumes to pull ECR, fetch Secrets Manager values, write to CloudWatch Logs on your behalf. Required when using ECR private, secrets, or awslogs.
  • taskRoleArn — IAM role your application code assumes inside the container to call AWS APIs (read S3, write DynamoDB). This is the "application" role.
  • volumes — bind mounts, Docker volumes, EFS volumes, FSx volumes.

Container-Level Fields

Each entry in the task definition's containerDefinitions array is one container in the task:

  • name — identifier used by dependsOn and service load balancer.
  • image — full ECR URI with tag or digest.
  • essential — if true (default for the first container), the task stops if this container stops; non-essential containers can fail without taking down the task (common for sidecars).
  • cpu, memory, memoryReservation — container-level resource limits; must fit inside task-level totals.
  • portMappingscontainerPort and protocol. On Fargate (awsvpc mode), the hostPort must equal containerPort. On EC2 bridge mode, hostPort: 0 means dynamic port mapping (the ALB target group registers the actual host port).
  • environment — plain-text env vars as {"name": "LOG_LEVEL", "value": "info"}.
  • secrets — env vars sourced from Secrets Manager or SSM Parameter Store via valueFrom, resolved at container start, not baked into the task definition.
  • healthCheck — Docker-level healthcheck command, interval, timeout, retries, startPeriod.
  • dependsOn — declares this container starts or stops based on another container's state (e.g., wait for a migration sidecar to exit SUCCESS before the app container starts).
  • logConfiguration — log driver (awslogs, awsfirelens, splunk, syslog) with driver-specific options.

Network Modes

ECS supports four networkMode values; the choice drives isolation, performance, and port behaviour.

  • awsvpc — each task gets its own ENI with a primary private IPv4 and optional IPv6. Mandatory for Fargate. Provides VPC-level security group attachment per task. No port conflict within a host because each task has its own ENI. Recommended for most workloads.
  • bridge — Docker's default virtual network on the host. Supports dynamic port mapping. EC2 launch type only. Useful for dense packing many small tasks on one host.
  • host — container shares the host's network namespace. No network isolation; port conflicts if two tasks use the same port. EC2 only. Highest network performance.
  • none — no external networking; rarely used.

Fargate tasks must use awsvpc. For EC2-launched tasks, awsvpc is still usually the right choice because it gives each task its own security group, eliminates port conflicts, and enables PrivateLink / VPC endpoint usage. Use bridge only for high-density EC2 scenarios with tight cost constraints. Reference: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-networking.html

Secrets via valueFrom

Never bake secrets into Dockerfiles or environment variables in the task definition JSON. Use the secrets array to pull values from AWS Secrets Manager or SSM Parameter Store at container start.

"secrets": [
  {
    "name": "DB_PASSWORD",
    "valueFrom": "arn:aws:secretsmanager:us-east-1:123456789012:secret:prod/db-AbCdEf:password::"
  },
  {
    "name": "API_KEY",
    "valueFrom": "arn:aws:ssm:us-east-1:123456789012:parameter/prod/api-key"
  }
]

The task execution role needs secretsmanager:GetSecretValue or ssm:GetParameters (plus kms:Decrypt if the secret is encrypted with a customer-managed KMS key). The secret is injected as an environment variable inside the container; from the application's perspective it looks identical to a plain environment entry. Secrets Manager supports specifying a JSON key with secret-arn:json-key:: so one secret can back many env vars.

Health Check and Dependency Ordering

dependsOn enables multi-container tasks with ordered lifecycle. Example — a database migration sidecar that must complete before the main app starts:

"containerDefinitions": [
  {
    "name": "migrate",
    "image": "...migrator:v1",
    "essential": false,
    "dependsOn": []
  },
  {
    "name": "app",
    "image": "...app:v1",
    "essential": true,
    "dependsOn": [
      { "containerName": "migrate", "condition": "SUCCESS" }
    ]
  }
]

Supported conditions: START, COMPLETE, SUCCESS, HEALTHY. SUCCESS means the depended-on container exited with code 0. HEALTHY requires the container's Docker HEALTHCHECK to pass.

Log Configuration — awslogs and Firelens

The awslogs driver is the default for ECS container logs. Configure log group, stream prefix, and region:

"logConfiguration": {
  "logDriver": "awslogs",
  "options": {
    "awslogs-group": "/ecs/myapp",
    "awslogs-region": "us-east-1",
    "awslogs-stream-prefix": "app",
    "awslogs-create-group": "true"
  }
}

For more complex log routing — multi-destination, filtering, parsing — use AWS FireLens, which runs Fluent Bit (or Fluentd) as a sidecar and forwards logs to CloudWatch Logs, Amazon OpenSearch Service, Amazon Kinesis Data Firehose, Amazon S3, or third parties like Datadog and Splunk.

{
  "name": "log_router",
  "image": "public.ecr.aws/aws-observability/aws-for-fluent-bit:stable",
  "essential": true,
  "firelensConfiguration": { "type": "fluentbit" }
}

Then the app container's logConfiguration uses awsfirelens as the driver, and FireLens routes based on Fluent Bit configuration.

ECS Service — Keeping Tasks Running and Deploying Safely

The ECS service is the long-running controller that keeps a desired number of task instances running, integrates with a load balancer, handles rolling or blue/green deployments, and drives Service Auto Scaling. DVA-C02 tests service configuration and deployment behaviour heavily.

Service Building Blocks

  • desiredCount — how many tasks to run.
  • launchTypeFARGATE, EC2, or EXTERNAL (for ECS Anywhere on customer-managed hosts).
  • deploymentControllerECS, CODE_DEPLOY, or EXTERNAL.
  • loadBalancers — target group ARN, container name, container port. The service registers / deregisters task ENIs on scale and deployment events.
  • serviceRegistries — AWS Cloud Map for service discovery by DNS.
  • networkConfiguration — subnets and security groups for awsvpc tasks.
  • deploymentConfiguration — controls rolling behaviour (min/max healthy percent, circuit breaker).

Deployment Controllers

Three deployment controller types drive how new task-definition revisions replace old ones.

  • ECS controller (rolling update) — default. ECS starts new tasks, waits for health, drains and stops old tasks. Configurable via minimumHealthyPercent (default 100) and maximumPercent (default 200). The simplest and most common.
  • CODE_DEPLOY controller (blue/green) — AWS CodeDeploy spins up the new task set on a second target group, runs hooks, shifts ALB listener rules from blue to green all at once or in canary / linear percentages, and can roll back on CloudWatch alarm. Required for true blue/green with explicit validation windows.
  • EXTERNAL controller — you or a third-party tool (Spinnaker, Argo Rollouts via EKS is similar but this is ECS) drive task sets via the ECS API. Rare.

Deployment Circuit Breaker

The ECS deployment circuit breaker automatically stops and optionally rolls back a failed rolling deployment. When enabled, ECS tracks failed task launches and, if too many new tasks fail to reach a healthy state, marks the deployment as FAILED and optionally redeploys the previous task-definition revision.

Enable circuit breaker in the service's deploymentConfiguration:

"deploymentConfiguration": {
  "deploymentCircuitBreaker": {
    "enable": true,
    "rollback": true
  },
  "minimumHealthyPercent": 100,
  "maximumPercent": 200
}

Without the circuit breaker, a bad new task definition can cause ECS to keep launching failing tasks indefinitely, costing money and potentially breaking traffic shape. DVA-C02 questions on "safe rolling deployments" are almost always answered by the deployment circuit breaker with rollback enabled.

A DVA-C02 trap offers "enable deployment circuit breaker" as the answer in a CodeDeploy blue/green scenario. The circuit breaker only applies when deploymentController is ECS. For CodeDeploy blue/green, rollback is controlled by CloudWatch alarms in the deployment group and the CodeDeploy hooks lifecycle. Reference: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/deployment-type-ecs.html

Service Auto Scaling

ECS services scale horizontally via Application Auto Scaling. Three policy types:

  • Target tracking — "keep CPU at 60 percent" or "keep ALBRequestCountPerTarget at 500." Easiest and recommended.
  • Step scaling — CloudWatch alarm thresholds trigger step-sized count changes.
  • Scheduled scaling — cron-based min/max bounds.

Target tracking on ALBRequestCountPerTarget is the canonical DVA-C02 answer for "scale the service based on traffic." Target tracking on ECSServiceAverageCPUUtilization is the fallback when ALB is not in play. Auto scaling adjusts the service's desiredCount between minCapacity and maxCapacity.

Load Balancer Integration

The service registers each task's ENI + containerPort with a target group at start and deregisters at stop. For awsvpc + Fargate, the target group's target type must be ip (not instance). The deregistration delay (connection draining) on the target group defines how long the load balancer keeps sending existing connections to a stopping task — 30 seconds by default, raise to the max of your application's request duration.

AWS Fargate Launch Type — Serverless Container Runtime

AWS Fargate is the serverless launch type for ECS and EKS. DVA-C02 treats Fargate as "how you avoid managing EC2" — the developer's default choice for new container deployment.

Fargate vs EC2 Launch Type from a Developer Perspective

  • No EC2 instances to patch, size, or auto-scale. No container instance concept.
  • Per-second billing for vCPU and memory reserved by the task.
  • Task-level Firecracker microVM isolation.
  • Fixed supported CPU / memory combinations.
  • 20–60 second provision time per new task.
  • Platform version (see below) controls capability support.

For DVA-C02, Fargate is the answer whenever the scenario says "minimize operational overhead," "no EC2 to manage," or "the developer wants to focus on code."

Fargate Platform Versions

Fargate platform version is the Fargate runtime release (analogous to an OS kernel for your tasks). Versions add capabilities — larger /tmp, new CPU architectures, new volume types.

  • LATEST — current recommended version.
  • Pinned version (e.g., 1.4.0) — stable until explicitly updated.

A key DVA-C02 detail: some capabilities (EFS volume mounts, 20 GB ephemeral storage by default, ARM Graviton support) require specific platform versions. If a task definition references a capability not supported on the pinned platform version, task launch fails. Always pin explicitly in production to avoid surprise upgrades.

Fargate Ephemeral Storage

Each Fargate task has ephemeral storage for writable container layers and /tmp. Default 20 GB on platform version 1.4.0+, configurable up to 200 GB per task via ephemeralStorage.sizeInGiB. Ephemeral storage is encrypted with an AWS-managed key and is destroyed when the task stops. For persistent state, use EFS or FSx volumes.

Fargate platform version 1.4.0+ gives 20 GB default ephemeral storage (configurable up to 200 GB), supports EFS volume mounts, runs on x86 or Graviton ARM64, uses Firecracker microVMs for task isolation, and provisions new tasks in 20–60 seconds. Fargate Spot offers up to 70 percent discount for interruptible tasks. Reference: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/platform_versions.html

Stateful Fargate — EFS and FSx Mounts

Fargate ephemeral storage is destroyed on task stop, which is fine for stateless web apps. For stateful workloads — shared uploads, session state, CMS file storage — mount an external filesystem.

EFS Volumes in Fargate Tasks

Amazon EFS provides an NFS filesystem that multiple Fargate tasks mount concurrently. Requirements:

  • Task network mode must be awsvpc (always true on Fargate).
  • Task security group must allow NFS (TCP 2049) to the EFS mount targets.
  • Task execution role needs elasticfilesystem:ClientMount and elasticfilesystem:ClientWrite (or use an EFS access point with IAM).
  • Fargate platform version 1.4.0 or later.

Define the volume at task level and mount it in the container:

"volumes": [
  {
    "name": "shared-data",
    "efsVolumeConfiguration": {
      "fileSystemId": "fs-abc123",
      "rootDirectory": "/",
      "transitEncryption": "ENABLED",
      "authorizationConfig": {
        "accessPointId": "fsap-xyz",
        "iam": "ENABLED"
      }
    }
  }
],
"containerDefinitions": [
  {
    "name": "app",
    "mountPoints": [
      { "sourceVolume": "shared-data", "containerPath": "/data" }
    ]
  }
]

EFS access points give per-application POSIX user/group and directory isolation, which is the recommended pattern for multi-tenant shared filesystems.

FSx for Windows and FSx for Lustre

For Windows container workloads, FSx for Windows File Server provides SMB shares — ECS on EC2 Windows supports this; Fargate Windows support is newer and platform-version-dependent. FSx for Lustre is the high-performance parallel filesystem for HPC and ML workloads, mountable on ECS on EC2 (and EKS Fargate has limited support). DVA-C02 rarely dives deep into FSx; remember EFS for general-purpose shared state on Fargate.

AWS App Runner — Fully Managed Container Deployment

AWS App Runner is the simplest container deployment path on AWS and the developer-friendly option for stateless web applications. App Runner takes a container image from ECR or source code from GitHub and runs it as a public HTTPS endpoint with automatic scaling and TLS.

App Runner Sources

  • ECR image — App Runner pulls a specific image URI. Auto-deploy optionally re-deploys when a new image is pushed to the same tag.
  • Source repository — connect a GitHub repo; App Runner builds the image using a managed buildpack (Python, Node.js, Java, etc.) or a Dockerfile in the repo, then deploys. Push to the main branch triggers an auto-deploy.

App Runner Capabilities

  • Auto HTTPS with AWS Certificate Manager (managed cert for the <id>.<region>.awsapprunner.com domain) or custom domain.
  • Auto scaling concurrency — you set max concurrent requests per instance (default 100) and min/max instance count; App Runner scales between them.
  • VPC connector for reaching RDS, ElastiCache, or internal services (otherwise App Runner runs outside your VPC).
  • Per-second billing for vCPU and memory, plus a small per-request fee.
  • Rolling deployments with health checks on a configurable HTTP path.
  • Observability plugin (AWS App Runner observability) surfaces request and runtime metrics in CloudWatch and X-Ray without extra instrumentation.

When App Runner Beats ECS for DVA-C02

  • The application is a stateless HTTP API or web app.
  • The team wants zero infrastructure decisions (no VPC setup, no load balancer, no target group).
  • Deployment from Git push is a hard requirement.
  • Traffic is low-to-medium; scale-to-near-zero saves cost.

App Runner is not a fit for non-HTTP workloads, multi-container sidecar patterns, or workloads needing fine-grained networking. For DVA-C02, App Runner is the right answer when the scenario reads "developer wants to deploy a stateless API with no infrastructure setup" — if sidecars, custom networking, or long-lived connections appear, shift to ECS on Fargate.

Enable App Runner auto-deploy on an ECR repository. Every docker push to the tracked tag triggers App Runner to pull the new image and roll it out with health checks. No CodePipeline, no CodeDeploy, no GitHub Actions deploy step needed. For DVA-C02 scenarios asking for the shortest path from commit to production on AWS, this combo is hard to beat. Reference: https://docs.aws.amazon.com/apprunner/latest/dg/manage-automatic.html

AWS Copilot CLI — Scaffolding Container Deployment Stacks

The AWS Copilot CLI is an open-source command-line tool that scaffolds and deploys containerized applications on ECS, Fargate, and App Runner. Copilot writes CloudFormation under the hood; you interact with high-level concepts (application, environment, service, job, pipeline) rather than raw task definitions.

Copilot Core Workflow

# One-time per application
copilot app init my-store

# Per environment (dev, staging, prod)
copilot env init --name prod --profile prod-account --default-config

# Per service
copilot svc init --name api --svc-type "Load Balanced Web Service" \
  --dockerfile ./api/Dockerfile

# Deploy
copilot svc deploy --name api --env prod

Copilot picks sensible defaults (ALB for web services, ECS on Fargate, CloudWatch Logs, per-env isolation), generates a copilot/ directory with manifest YAML that you commit to Git, and creates VPC, cluster, task definition, service, load balancer, and IAM roles in CloudFormation.

Copilot service types (pick one per svc init):

  • Request-Driven Web Service — backed by App Runner.
  • Load Balanced Web Service — ECS on Fargate behind public ALB.
  • Backend Service — ECS on Fargate with internal service discovery (Cloud Map).
  • Worker Service — ECS on Fargate consuming SQS.
  • Static Site — S3 + CloudFront.

Copilot also scaffolds pipelines (copilot pipeline init) that chain CodeCommit / GitHub → CodeBuild → ECS deploy per environment.

For DVA-C02, Copilot is the answer when the scenario reads "developer wants to spin up a new containerized service with minimal manual configuration" or "generate a CloudFormation-backed ECS stack without authoring the template by hand."

ECS Exec — Shell Into Running Tasks

ECS Exec lets developers run interactive commands (including a shell) inside a running ECS task without SSH, bastions, or host access. ECS Exec uses AWS Systems Manager Session Manager under the hood.

Prerequisites

  • Task role must include the SSM permissions (ssmmessages:CreateControlChannel, ssmmessages:CreateDataChannel, ssmmessages:OpenControlChannel, ssmmessages:OpenDataChannel).
  • The container image must include the SSM agent — AWS injects it automatically at task start via a bind-mounted binary, so images generally do not need to bundle it.
  • Task definition must have enableExecuteCommand: true on the service (or you must pass --enable-execute-command when running a one-off task).
  • Fargate platform version 1.4.0 or later.

Using ECS Exec

aws ecs execute-command \
  --cluster prod \
  --task <task-id> \
  --container app \
  --interactive \
  --command "/bin/sh"

Session logs can be audited to CloudWatch Logs or S3 via the cluster's executeCommandConfiguration. DVA-C02 scenarios on "debug a running task without rebuilding the image" are ECS Exec answers. The trap alternative — "SSH to the Fargate host" — is impossible because Fargate gives you no host access.

A common misconfiguration: developers grant SSM permissions to the task execution role and ECS Exec fails. The SSM permissions must be on the task role because the SSM agent inside the container uses the task role's credentials. Also ensure the service was created (or updated) with --enable-execute-command — enabling it on an existing service requires a new deployment. Reference: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-exec.html

Container Image Signing and Deployment Guardrails

Production container deployment demands supply-chain integrity. AWS provides several guardrails around container images.

AWS Signer for Container Images

AWS Signer with Notation (the open-source signing standard from the Notary Project) signs container images stored in ECR. The signature is stored alongside the image in ECR. At deployment time, a verification policy — evaluated by a verifier like Kyverno on EKS or a custom Lambda for ECS — checks the signature against a trusted identity before allowing the image to run.

For ECS, signature verification is not enforced natively at launch time (as of the DVA-C02 exam window); enforcement typically runs at the CI/CD gate before UpdateService is called, or via an admission controller on EKS. Keep this detail in mind: DVA-C02 may ask about the existence and purpose of image signing, not necessarily its enforcement at runtime.

ECR Replication and Pull-Through Cache

  • ECR replication copies images across Regions or accounts automatically, which reduces pull latency for multi-Region deployments.
  • ECR pull-through cache mirrors images from upstream registries (Docker Hub, Quay, Kubernetes registry, Microsoft Container Registry) into your ECR, reducing rate-limit exposure and giving you scannable images.

Deployment Guardrail Patterns

  • Deployment circuit breaker with rollback (covered above) — catches failed rolling deploys.
  • CodeDeploy blue/green with CloudWatch alarms — automated rollback on metric thresholds.
  • Task definition revisions — roll back by pointing the service at the previous revision via UpdateService.
  • Immutable image tags — ensures the service's image URI cannot be silently mutated.
  • Image scan on push + Enhanced scanning — block deploys of CVE-laden images at the CI/CD gate.

Common DVA-C02 Traps in Container Deployment

Trap 1 — Confusing Task Role with Execution Role

Task execution role = ECS agent permissions (pull ECR, fetch secrets, write logs). Task role = application permissions (read S3, write DynamoDB). DVA-C02 mixes these and the wrong role is almost always the distractor.

Trap 2 — Missing secretsmanager:GetSecretValue on the Execution Role

When a task definition uses secrets.valueFrom and the container fails to start with "ResourceInitializationError," the fix is adding secretsmanager:GetSecretValue (plus kms:Decrypt for CMK-encrypted secrets) to the execution role.

Trap 3 — Dockerfile Shell Form Breaking SIGTERM

CMD node server.js wraps the process in /bin/sh -c, which swallows SIGTERM. Rolling deployments hit stopTimeout and tasks SIGKILL. Fix: exec form CMD ["node", "server.js"] or use tini as init.

Trap 4 — awsvpc Task Without ENI Capacity on EC2 Hosts

When running awsvpc tasks on EC2 launch type, each task needs its own ENI. EC2 instances have per-type ENI limits. Task placement fails with "InsufficientNetworkInterfaces." Enable ENI trunking on supported instance types to raise the limit or switch to Fargate.

Trap 5 — Mutable Tags Breaking Reproducibility

A latest tag that gets re-pushed breaks the mental model of "same task definition = same code." For production, set ECR repos to IMMUTABLE and pin by version tag or digest.

Trap 6 — Deployment Circuit Breaker Not Enabled

Without the circuit breaker, a bad rollout keeps launching failing tasks indefinitely. Always enable circuit breaker with rollback: true on ECS controller services.

Trap 7 — App Runner Chosen for Non-HTTP Workloads

App Runner is HTTP-only. DVA-C02 scenarios with WebSocket-heavy, gRPC streaming, or long-polling workloads should not default to App Runner; ECS on Fargate behind NLB is the correct answer.

Developers sometimes write application state to /tmp or /var/lib/app on Fargate, expecting it to survive restarts. Fargate ephemeral storage is destroyed on task stop. The fix is an EFS volume mount for shared state, RDS / DynamoDB for application state, or S3 for blob storage. Never assume local disk persistence on any serverless container runtime. Reference: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/fargate-task-storage.html

Key Numbers to Memorize for Container Deployment

  • ECR auth token — valid for 12 hours.
  • ECR image scan on push — free basic scan per image; Enhanced scanning billed per image per month.
  • Fargate platform version 1.4.0+ — 20 GB default ephemeral storage (up to 200 GB), EFS mount support.
  • Fargate CPU/memory combos — 0.25 vCPU (0.5–2 GB) up to 16 vCPU (30–120 GB).
  • Fargate Spot discount — up to 70 percent.
  • ECS control plane — free.
  • Deployment circuit breaker — default thresholds are 10 failed task launches or 200 percent of desired count, whichever is lower.
  • Target group deregistration delay — 30 seconds default, up to 3600 seconds.
  • awsvpc network mode — mandatory on Fargate, one ENI per task.
  • ECS task stopTimeout — 30 seconds default, up to 120 seconds (Linux).
  • ECS Exec — requires Fargate platform version 1.4.0+, SSM permissions on task role, enableExecuteCommand: true.

FAQ — Container Deployment on AWS

Q1. What is the difference between the ECS task execution role and the ECS task role, and when does each apply?

The ECS task execution role is assumed by the ECS agent (on EC2) or the Fargate infrastructure to perform actions on your behalf before and around task launch: pulling the container image from private ECR, fetching secrets from Secrets Manager or SSM Parameter Store for injection as environment variables, and writing container stdout/stderr to CloudWatch Logs via the awslogs driver. The ECS task role is assumed by your application code running inside the container and grants AWS API permissions your code calls at runtime — reading from an S3 bucket, writing to DynamoDB, publishing to SNS. Every container deployment on ECS needs an execution role if you use ECR private, Secrets Manager, or awslogs, and a task role if your application code calls AWS APIs. Confusing the two is the single most-tested trap on DVA-C02 container deployment scenarios.

Q2. How do I push a container image to Amazon ECR from my developer laptop?

Authenticate docker with ECR using the AWS CLI: aws ecr get-login-password --region <region> | docker login --username AWS --password-stdin <account-id>.dkr.ecr.<region>.amazonaws.com. The returned token is valid for 12 hours. Tag the local image with the full ECR URI: docker tag myapp:latest <account-id>.dkr.ecr.<region>.amazonaws.com/myapp:v1.2.3. Push: docker push <account-id>.dkr.ecr.<region>.amazonaws.com/myapp:v1.2.3. For a smoother developer experience, install the Amazon ECR Docker Credential Helper so docker push auto-authenticates using your AWS credentials with no explicit login step.

Q3. How does the ECS deployment circuit breaker protect a rolling deployment, and when should I enable rollback?

The ECS deployment circuit breaker monitors a rolling deployment for failed task launches. When the failure threshold is hit (default 10 failures or 200 percent of desired count, whichever is lower), ECS marks the deployment FAILED and stops launching new tasks. If you set rollback: true in the deployment configuration, ECS also redeploys the previous task-definition revision automatically. Enable the circuit breaker with rollback for every production ECS service using the default ECS deployment controller — it is free, has no downside, and prevents a broken new revision from cascading into a full outage. The circuit breaker does not apply to the CodeDeploy blue/green controller; for CodeDeploy, configure CloudWatch alarms on the deployment group to trigger automatic rollback.

Q4. How do I inject secrets from AWS Secrets Manager into an ECS container without baking them into the image?

Define the secret once in AWS Secrets Manager or SSM Parameter Store. In the ECS task definition, use the secrets array on the container definition, not the environment array: {"name": "DB_PASSWORD", "valueFrom": "arn:aws:secretsmanager:<region>:<account>:secret:<secret-name>-<suffix>:password::"}. The valueFrom ARN can point to a whole secret or a specific JSON key (append :json-key:: to the ARN). Grant the task execution role secretsmanager:GetSecretValue for the secret ARN (plus kms:Decrypt on the customer-managed KMS key if the secret is encrypted with one). At task start, ECS resolves each secret and injects it into the container as an environment variable. The application sees it as a normal env var; the secret value never appears in the task definition JSON.

Q5. What are the core Dockerfile best practices for producing a production-ready image for ECS or Fargate?

The core Dockerfile best practices for AWS container deployment are: use a multi-stage build so compiler toolchains and dev dependencies never ship to production; pick a minimal base image (slim, Alpine, or distroless, ideally from ECR Public Gallery to avoid Docker Hub rate limits); order layers from least-frequently-changed to most-frequently-changed so the dependency-install layer caches; install dependencies before copying source; run as a non-root user by creating one or using the base image's built-in non-root user; use the exec form of CMD (CMD ["node", "server.js"]) so SIGTERM reaches your process during rolling deployments; add a HEALTHCHECK only when the ALB target group health check is not sufficient; and set explicit EXPOSE and WORKDIR. Following these eight habits produces an image that is small, fast to pull, signal-safe, cache-friendly, and secure — which translates directly into DVA-C02 exam points.

Q6. When should I pick AWS App Runner over ECS on Fargate for a new service?

Pick AWS App Runner when the workload is a stateless HTTP web app or API, the team wants zero infrastructure to manage (no VPC, load balancer, target group, or auto scaling policy to configure), deployment from a Git push or ECR push should trigger an automatic rollout, and the traffic profile allows scale-to-near-zero for cost savings. App Runner handles the load balancer, managed TLS certificate, auto scaling based on concurrent requests per instance, rolling deployments with health checks, and a built-in VPC connector for reaching private resources. Pick ECS on Fargate when you need multi-container tasks with sidecars (FireLens log router, Envoy proxy, migration init containers), non-HTTP protocols, WebSocket or gRPC streaming at scale, fine-grained networking (multiple security groups, multiple subnets, PrivateLink endpoints), or deployment strategies beyond rolling (CodeDeploy blue/green with canary or linear). For a fresh stateless API, App Runner is almost always the right first pick; outgrow it later if complexity demands.

Q7. How do I debug a production ECS task without SSH or bastion hosts?

Use ECS Exec, which gives you an interactive shell inside a running task via AWS Systems Manager Session Manager. Prerequisites: the task role includes the four SSM messages permissions (ssmmessages:CreateControlChannel, CreateDataChannel, OpenControlChannel, OpenDataChannel); the service is created or updated with enableExecuteCommand: true; Fargate platform version is 1.4.0 or later. Then run aws ecs execute-command --cluster <cluster> --task <task-id> --container <name> --interactive --command "/bin/sh". Session logs can be routed to CloudWatch Logs or S3 via the cluster's executeCommandConfiguration for auditability. ECS Exec is the DVA-C02 answer for any "debug a running container without rebuilding the image" scenario. The common misconfiguration is putting the SSM permissions on the execution role instead of the task role — the SSM agent inside the container uses the task role's credentials.

Summary — Container Deployment at a Glance

  • Container deployment on AWS is the developer pipeline of Dockerfile → ECR → ECS task definition → ECS service → Fargate runtime, with App Runner and Copilot as accelerators and ECS Exec as the debug tool.
  • Dockerfile best practices: multi-stage builds, minimal base image, cache-friendly layer order, non-root user, exec form CMD, explicit HEALTHCHECK only when needed.
  • Amazon ECR: 12-hour auth token via aws ecr get-login-password, immutable tag mutability for production, scan on push (basic free, Enhanced for continuous scanning), lifecycle policies to control storage cost, cross-account pulls via repository policy, ECR Public Gallery for rate-limit-free base images.
  • ECS task definitions: awsvpc network mode on Fargate, CPU/memory at both task and container level, secrets via valueFrom resolved at start, dependsOn for ordering, awslogs or FireLens for logs, task role vs execution role as the canonical trap.
  • ECS services: desiredCount, deployment controllers (ECS rolling, CodeDeploy blue/green, External), deployment circuit breaker with rollback, Service Auto Scaling via target tracking on ALBRequestCountPerTarget.
  • Fargate: no EC2 management, platform versions (pin 1.4.0+ for EFS and larger ephemeral storage), per-second billing, Fargate Spot for up to 70 percent discount on interruptible workloads.
  • Stateful Fargate: EFS volume mounts via efsVolumeConfiguration, access points for POSIX isolation, task security group must allow NFS 2049; FSx for Windows/Lustre for specialty needs.
  • App Runner: HTTP-only, zero infrastructure decisions, auto-deploy from ECR or GitHub, VPC connector for private resources, observability plugin for CloudWatch and X-Ray.
  • AWS Copilot CLI: scaffolds ECS on Fargate or App Runner applications with CloudFormation under the hood, service types include Load Balanced Web Service, Backend Service, Worker Service, Request-Driven Web Service.
  • ECS Exec: interactive shell into running tasks via SSM Session Manager; SSM permissions go on the task role, not the execution role; enable per-service and at Fargate platform version 1.4.0+.
  • Image signing via AWS Signer + Notation; deployment guardrails include circuit breaker rollback, immutable tags, scan-on-push gates, CodeDeploy alarms.

Master container deployment at this depth and task statements 3.1 and 3.2 of DVA-C02 become pattern recognition. The same developer muscle memory — Dockerfile, ECR, task definition, service, Fargate, App Runner, Copilot, ECS Exec — carries into day-one production work the morning after you pass the exam.

官方資料來源