Deploy Containers on Amazon ECS with Fargate

Khimananda Oli 8 min read Database
Deploy Containers on Amazon ECS with Fargate

By Khimananda Oli | Last reviewed: August 2026

Running containerized applications without managing underlying servers is the primary reason teams choose to deploy containers on Amazon ECS with Fargate. This serverless compute engine removes the operational overhead of patching and scaling EC2 instances, letting you focus entirely on application logic and delivery. However, abstracting the infrastructure introduces new challenges in networking, IAM permissions, and cost management that differ significantly from traditional Kubernetes or EC2-based deployments.

How do you architect a secure network for Fargate tasks?

Network architecture is where most Fargate deployments fail silently. Unlike EC2 instances where you might tolerate public IPs during development, Fargate tasks should almost never have direct internet exposure. A common mistake I see in audits is placing Fargate tasks in public subnets "for simplicity," which bypasses NAT gateway logging and exposes ephemeral ENIs directly to the internet.

VPC (10.0.0.0/16)Public Subnet AALBNAT GWPrivate Subnet BFargate Task 1Fargate Task 2Security Group: Allow 443 from ALB onlyRoute Table: 0.0.0.0/0 → NAT GatewayNo Public IPs Assigned to Tasks
Recommended VPC topology when you deploy containers on Amazon ECS with Fargate: tasks run in private subnets with outbound access via NAT Gateway and inbound traffic through an ALB.

The correct pattern places your Fargate tasks in private subnets with a route to a NAT Gateway (or VPC endpoints for AWS services like ECR and S3 to avoid NAT data charges). Inbound traffic flows exclusively through an Application Load Balancer in public subnets. This architecture ensures all egress traffic is logged at the NAT level and tasks cannot be accidentally exposed. For teams implementing VPC networking fundamentals, this separation is non-negotiable for SOC 2 compliance.

Configuring Security Groups Correctly

Your Fargate task security group should allow inbound traffic only from the ALB security group on the specific container port (e.g., 8080), not from 0.0.0.0/0. Outbound rules should permit HTTPS (443) to required destinations. Avoid overly permissive egress rules; scope them to known API endpoints or VPC endpoint prefixes when possible.

What does a production-ready Fargate task definition look like?

A task definition is the blueprint for your container. Many tutorials show minimal JSON, but production definitions require explicit resource bounds, health checks, logging configuration, and IAM role references. Below is a validated task definition snippet for a Node.js API that passes security audits:

{
  "family": "api-production",
  "networkMode": "awsvpc",
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "512",
  "memory": "1024",
  "executionRoleArn": "arn:aws:iam::123456789012:role/api-task-execution-role",
  "taskRoleArn": "arn:aws:iam::123456789012:role/api-task-role",
  "containerDefinitions": [
    {
      "name": "api",
      "image": "123456789012.dkr.ecr.us-east-1.amazonaws.com/api:v2.4.1",
      "portMappings": [
        {
          "containerPort": 8080,
          "protocol": "tcp"
        }
      ],
      "healthCheck": {
        "command": ["CMD-SHELL", "curl -f http://localhost:8080/health || exit 1"],
        "interval": 30,
        "timeout": 5,
        "retries": 3,
        "startPeriod": 60
      },
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/api-production",
          "awslogs-region": "us-east-1",
          "awslogs-stream-prefix": "api"
        }
      },
      "environment": [
        { "name": "NODE_ENV", "value": "production" }
      ]
    }
  ]
}

Key points often missed: always pin image tags to immutable digests or semantic versions (never latest), define explicit health checks with a startPeriod to accommodate slow-starting apps, and separate executionRoleArn (used by ECS agent to pull images/write logs) from taskRoleArn (used by your application code to access AWS APIs). This separation enforces least privilege and simplifies audit trails. If you're new to containerization, review Docker fundamentals before optimizing task definitions.

Managing Secrets Securely

Never embed secrets in environment variables or task definitions. Use AWS Secrets Manager or Systems Manager Parameter Store and reference them in the secrets block of your container definition. The execution role needs secretsmanager:GetSecretValue permission scoped to specific secret ARNs. This approach keeps sensitive values out of CloudFormation/Terraform state files and ECS API responses.

How do you configure auto-scaling and service deployment?

Fargate services scale based on CloudWatch metrics or custom metrics via Application Auto Scaling. The default CPU/memory targets are rarely sufficient for real workloads. In practice, I configure scaling on request count per target (for ALB-backed services) or SQS queue depth (for workers), as these correlate better with actual user experience than aggregate CPU utilization.

ECS Service Auto-Scaling FlowCloudWatch Metric(RequestCount/Target)Scaling Policy(Target Tracking)ECS Service(Desired Count: 2→5)Scale-Out Conditions• RequestCountPerTarget > 1000 for 3 mins• CPUUtilization > 75% for 5 mins (fallback)• Max Capacity: 20 tasks | Min: 2 tasksScale-In Protection• Cooldown: 300s | Stabilization: 60s
Auto-scaling workflow when you deploy containers on Amazon ECS with Fargate: metric-driven policies adjust task count with cooldown periods to prevent flapping.

Configure scale-in protection with adequate cooldowns (300 seconds minimum) to avoid thrashing during transient spikes. Set minimum capacity to at least 2 tasks across multiple AZs for high availability. For cost-sensitive workloads, mix On-Demand and Fargate Spot capacity using a capacity provider strategy; Spot tasks can be interrupted with a 2-minute warning, so only use them for stateless, retry-tolerant services. Teams adopting Infrastructure as Code with Terraform should encode these scaling policies declaratively to ensure consistency across environments.

Deployment Strategies

Use rolling updates with a minimum healthy percentage of 100% and maximum of 200% to ensure zero-downtime deployments. For critical services, implement blue/green deployments using CodeDeploy with ECS; this allows validation of the new version before shifting traffic and provides instant rollback capability. Always test deployment configurations in staging first—misconfigured health checks are the #1 cause of failed Fargate deployments.

When should you choose Fargate over EC2 or EKS?

Fargate isn't universally optimal. Understanding its trade-offs prevents costly architectural mistakes. Below is a decision matrix based on real production scenarios I've encountered across Nepal-based startups and global enterprises:

CriteriaFargateEC2 Launch TypeEKS (Kubernetes)
Operational OverheadMinimal (serverless)High (patching, scaling)Very High (cluster mgmt)
Cost at Low Scale (<10 vCPU)LowestModerate (reserved helps)Highest (control plane + nodes)
Cost at High Scale (>100 vCPU)HighestLowest (compute optimized)Moderate (node efficiency)
Startup Time~10-30 secondsMinutes (if scaling nodes)Seconds (warm nodes)
Custom Kernel/System ConfigNot supportedFull controlFull control
GPU SupportLimited (Fargate GPU)Full instance choiceFull instance choice
Best ForMicroservices, batch, variable loadSteady-state, legacy appsComplex orchestration, multi-team

Choose Fargate when operational simplicity outweighs raw cost efficiency, when workload patterns are spiky or unpredictable, or when your team lacks dedicated platform engineering resources. Choose EC2 for steady-state workloads with predictable resource needs where reserved instances yield significant savings. Choose EKS only when you need Kubernetes-specific features (custom operators, service mesh, multi-cluster federation) and have the expertise to manage it. For many Nepal-based teams with limited DevOps headcount, Fargate offers the best balance of production readiness and maintainability.

Compute Platform Decision MatrixStart: New WorkloadNeed custom kernel/GPU/metal?YesNoEC2 Launch TypeK8s features needed?YesNoEKSFargate ✓
Decision flowchart to determine whether to deploy containers on Amazon ECS with Fargate, EC2, or EKS based on technical requirements and team capacity.

How do you optimize Fargate costs without sacrificing reliability?

Fargate pricing is straightforward (vCPU + memory per second), but bills escalate quickly without discipline. Right-sizing is paramount: use CloudWatch Container Insights or AWS Compute Optimizer to identify over-provisioned tasks. Most applications run fine at 0.5 vCPU / 1 GB initially; start small and scale up based on metrics, not guesses.

  • Use Fargate Spot aggressively: For dev/staging environments, batch processing, and fault-tolerant microservices, Spot reduces costs by 50-70%. Configure capacity provider strategies to prefer Spot with On-Demand fallback.
  • Leverage Savings Plans: Compute Savings Plans apply to Fargate usage automatically. Commit to 1-year terms for ~20% discount if baseline usage is predictable.
  • Optimize container images: Smaller images reduce pull times and storage costs. Use multi-stage builds and distroless bases. Review multi-stage build techniques to cut image sizes by 60-80%.
  • Implement scheduled scaling: Scale down non-production services outside business hours. A cron-based Lambda adjusting desired count saves ~65% on dev environments.
  • Monitor orphaned resources: Stopped tasks, unused ECR images, and detached EBS volumes (from previous EC2 migrations) accumulate silently. Run weekly cost anomaly detection reviews.

In Nepal, where cloud budgets are often constrained and billed in NPR, these optimizations directly impact runway. One Kathmandu-based SaaS client reduced their monthly Fargate bill from $1,200 to $480 through right-sizing and Spot adoption alone—without any application changes.

Next Steps for Production Readiness

To successfully deploy containers on Amazon ECS with Fargate, begin with a minimal viable service in a properly segmented VPC, validate networking and IAM boundaries, then layer in auto-scaling and cost controls. Automate everything via Terraform or CloudFormation; manual console clicks create drift and audit failures. Integrate observability early—CloudWatch Logs, X-Ray tracing, and Container Insights are not optional extras but prerequisites for reliable operations.

If your team needs hands-on guidance architecting Fargate deployments, preparing for SOC 2 audits, or optimizing existing container workloads, reach out to discuss your specific requirements. I help teams build infrastructure that's secure, observable, and audit-ready from day one—not as an afterthought.

Frequently Asked Questions

Fargate removes server management entirely. You pay only for vCPU and memory used by running tasks, eliminating EC2 instance provisioning, patching, and cluster capacity planning overhead.

Specify valid cpu and memory combinations in your task definition JSON. Fargate supports fixed pairs like 0.5 vCPU with 1GB RAM up to 16 vCPU with 120GB RAM as of 2026.

No. Fargate tasks are ephemeral and lack persistent block storage. Use Amazon EFS for shared filesystems or S3 for object storage if state must survive task restarts.

Fargate costs more per vCPU-hour than reserved EC2 but eliminates idle capacity waste. It is cheaper for spiky or unpredictable workloads where EC2 instances sit underutilized.

Yes. Fargate supports GPU-accelerated tasks using NVIDIA A10G GPUs. Specify gpu in the task definition resourceRequirements and select compatible instance families during deployment.

Fargate requires awsvpc network mode. Each task gets its own elastic network interface and private IP, enabling security group enforcement at the task level rather than host level.

Register a task definition with aws ecs register-task-definition, then run aws ecs create-service specifying launchType FARGATE, network configuration, and desired count for production deployments.

Common causes include insufficient IAM permissions, invalid security group rules blocking ECR access, or misconfigured subnet routing. Check CloudWatch Events and ECS service events for specific failure reasons.

Yes. Fargate supports Windows Server 2019 and 2022 containers. Specify platformFamily WINDOWS_SERVER_2022_CORE or similar in the task definition runtimePlatform field.

Use Fargate Spot for fault-tolerant workloads at up to 70% discount. Combine with right-sizing task definitions and auto-scaling based on actual CPU/memory utilization metrics.

Yes. Place tasks in private subnets and configure VPC endpoints for ECR, S3, Secrets Manager, and CloudWatch Logs to avoid NAT gateway costs and public exposure.

Use awslogs driver to stream stdout/stderr directly to CloudWatch Logs. Configure logGroup, region, and streamPrefix in the task definition logConfiguration block for centralized observability.

Reference AWS Secrets Manager or Systems Manager Parameter Store ARNs in container definitions. Fargate injects values securely at runtime without embedding credentials in images or environment variables.

Yes. Use ECS RunTask API or AWS Batch with Fargate compute environments. Tasks scale instantly without pre-provisioned capacity, ideal for sporadic ETL or data processing workloads.

Fargate tasks can run indefinitely with no hard time limit. However, implement graceful shutdown handlers for SIGTERM signals since AWS may reclaim Spot capacity or perform maintenance.