AWS container workloads normally store images in ECR and run them through ECS, Fargate, or EKS.
ECS offers AWS-native orchestration; Fargate supplies serverless task capacity for ECS or EKS; EKS provides a managed Kubernetes control plane when Kubernetes APIs and ecosystem compatibility are required.
The image is only one release artifact. Task or pod definitions, runtime roles, secrets, networking, health checks, scaling, and logs determine whether the service operates safely.
Create small, reproducible images, run as a non-root user, pin important dependencies, and scan the final artifact. Push immutable version tags or digests to ECR instead of redeploying a mutable latest tag.
Use ECS when AWS-native task and service concepts meet the requirement. Add Fargate when avoiding host management is worth its pricing and constraints. Choose EKS when Kubernetes capability is an explicit need.
Give each task or service a runtime role distinct from the deployment role. Place tasks in suitable subnets, restrict security groups, and retrieve secrets from Secrets Manager or Parameter Store.
Rolling, blue-green, or canary deployment should be paired with readiness checks and rollback criteria. Centralize stdout and stderr, measure saturation, and drain connections before stopping old tasks.
Build from a reviewed base image pinned by digest or controlled version, install only runtime dependencies, and run the final stage as a non-root user when the application permits it. Multi-stage builds remove compilers and temporary files from the runtime image, reducing size and attack surface without changing the source build.
Tag images with a human-readable release and deploy by immutable digest so the same revision cannot silently point to different bytes. ECR scanning, signing or provenance, lifecycle rules, and cross-account repository policies belong to the release process. A clean scan does not prove the application is secure, and a later vulnerability requires an image rebuild and redeployment.
Never bake AWS credentials, private package tokens, certificates, or environment-specific configuration into layers. Build secrets need a mechanism that avoids persisted layers and logs. Generate a software bill of materials when required and keep the source commit, build job, image digest, and deployed revision traceable.
An ECS task definition versions container images, commands, CPU and memory, ports, environment, secrets, logging, volumes, task role, and execution role. A task is one running copy; a service maintains desired task count, integrates with load balancing, and replaces unhealthy or stopped tasks. Run-to-completion jobs may use standalone or scheduled tasks instead.
The task execution role lets the ECS agent perform operations such as pulling images and sending logs. The task role is delivered to application containers for their AWS API calls. Keep them separate so image pull permission does not become business-data permission and application code cannot administer its own deployment.
Use container dependencies and health checks only where startup ordering is truly required. Essential container exit can stop the task, so sidecars need clear failure semantics. Store task definitions in infrastructure code and verify the registered revision rather than making untracked console edits.
Fargate supplies managed task or pod compute from requested CPU, memory, storage, architecture, and platform settings. It removes host provisioning and cluster packing from the team, but workload sizing, startup time, quotas, networking, and price remain. Select a supported size from measured demand and leave enough headroom for runtime and sidecars.
ECS on EC2 gives control of instance families, AMIs, accelerators, daemon workloads, storage, and packing. It also makes the team responsible for capacity providers, patching, draining, scaling, and unused host capacity. Capacity-provider strategy can combine purchase models and scaling behavior without hard-coding every service to one cluster type.
Compare Fargate and EC2 using steady utilization, burst shape, operational staffing, special hardware, isolation, start latency, and failure handling. Test an unavailable capacity type and a host drain. Serverless capacity reduces one operations layer; it does not remove application availability design.
Amazon EKS manages the Kubernetes control plane, while the customer still owns cluster access, worker capacity, add-ons, network policy, workload security, upgrades, observability, and Kubernetes objects. Managed node groups reduce node lifecycle work; Fargate can run selected pods without customer-managed nodes under its supported constraints.
Choose EKS when Kubernetes APIs, ecosystem tooling, portability requirements, or existing operating skill provide concrete value. Kubernetes introduces controllers, namespaces, service accounts, admission, scheduling, storage, and version lifecycle that a simple container deployment may not need. ECS is often the smaller operating model for AWS-native teams.
Plan control-plane endpoint access, identity mapping or access entries, pod IAM, CNI address capacity, add-on compatibility, and supported version upgrades before production. Test node loss and upgrade in a representative environment. A managed control plane does not make an unmaintained workload cluster safe.
In common ECS `awsvpc` networking, each task receives a network interface and security-group context. Plan subnet address capacity, load balancer targets, service discovery, outbound endpoints, and cross-zone behavior. Keep only the intended load balancer public; application tasks normally remain in private subnets.
Inject secrets from Secrets Manager or Parameter Store through the platform or retrieve them at runtime with the task role. Environment injection can expose values to process inspection and does not automatically refresh a rotated secret in an already running task. Design rotation together with task replacement or runtime retrieval.
Use read-only filesystems, dropped Linux capabilities, non-root users, resource limits, and separate tenants according to the threat model. Container isolation is not an authorization boundary for AWS APIs; IAM roles and resource policies still decide data access. Restrict metadata and credential endpoints from unintended containers.
A rolling deployment replaces tasks within minimum and maximum healthy bounds; blue-green creates a separate revision and shifts traffic; canary exposes a small portion first. Choose from capacity, startup, state compatibility, and rollback needs. Readiness should verify the process can serve traffic without making a shared dependency outage terminate the whole fleet.
Scale on demand signals such as request load, queue backlog, concurrency, or latency rather than CPU alone when CPU does not represent work. Bound maximum capacity by downstream database, API, subnet, and budget limits. Drain load-balancer connections and stop work gracefully within the platform termination window.
Centralize stdout and stderr, emit structured release and request identifiers, collect task-stop reasons, and monitor deployment failures, healthy targets, saturation, throttling, and backlog. Exercise a bad image, failing health check, unavailable secret, capacity shortage, and rollback. Verify that the old revision remains compatible with data and configuration.
Record platform and orchestrator version support, because image compatibility alone does not prove that task definitions, add-ons, drivers, or deployment controls remain supported.
Container tutorials should show how images move into a running service, not just how a registry is created.
aws ecs update-service \
--cluster app-prod \
--service orders-api \
--force-new-deployment
aws ecs describe-services \
--cluster app-prod \
--services orders-api \
--query "services[0].deployments"
A new task definition passes startup but its readiness endpoint fails under real dependencies.
Constraints: The service keeps at least 100% desired healthy capacity and circuit-breaker rollback is enabled.
Decision: Deploy immutably, route traffic only after target health passes, and let the failed steady state restore the previous task definition.
Verification: The prior revision serves all requests, failed tasks retain logs, and deployment events explain the rollback.
Failure test: Return HTTP 500 from readiness and verify traffic never reaches the bad task.
Expected evidence: The prior revision serves all requests, failed tasks retain logs, and deployment events explain the rollback.
Explore 500+ free tutorials across 20+ languages and frameworks.