AWS ECS
containers
task definitions
cloud computing
microservices

Linking containers between task definitions in AWS ECS?

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

In ECS, container communication depends on where containers run and which network mode you choose. Many teams ask about linking containers across task definitions, but classic Docker links are limited and mostly legacy behavior. The practical modern pattern is service discovery and load balancing between tasks, while containers inside the same task communicate locally.

Task-Level Versus Service-Level Communication

A task definition describes one task shape. A running task can include multiple containers. Communication rules differ:

  • Same task: containers can reach each other via localhost in awsvpc mode.
  • Different tasks: use ECS service discovery, Cloud Map DNS, or an internal load balancer.

You cannot directly use old container links to connect arbitrary containers in different task definitions.

The links field historically worked with Docker bridge networking and EC2 launch type. It is not supported in Fargate and is discouraged for new architectures.

Example of legacy-style definition:

json
1{
2  "containerDefinitions": [
3    {
4      "name": "app",
5      "image": "example/app:latest",
6      "links": ["redis"]
7    },
8    {
9      "name": "redis",
10      "image": "redis:7"
11    }
12  ],
13  "networkMode": "bridge"
14}

For modern ECS deployments, avoid designing new systems around this field.

For sidecar patterns, keep containers in one task and use localhost ports.

json
1{
2  "family": "api-with-sidecar",
3  "networkMode": "awsvpc",
4  "containerDefinitions": [
5    {
6      "name": "api",
7      "image": "123456789012.dkr.ecr.us-east-1.amazonaws.com/api:latest",
8      "portMappings": [{ "containerPort": 8080, "protocol": "tcp" }],
9      "environment": [{ "name": "LOG_ENDPOINT", "value": "http://127.0.0.1:9000" }]
10    },
11    {
12      "name": "log-agent",
13      "image": "public.ecr.aws/aws-observability/aws-for-fluent-bit:stable",
14      "portMappings": [{ "containerPort": 9000, "protocol": "tcp" }]
15    }
16  ]
17}

This works well for app plus proxy, app plus telemetry agent, and app plus local cache patterns.

If services run in separate task definitions, expose one as ECS service and call it by service DNS name.

Steps:

  1. Create ECS service for provider task.
  2. Enable service discovery or attach internal load balancer.
  3. Configure consumer service with provider DNS endpoint.

Example environment variable in consumer task:

json
1{
2  "name": "USER_SERVICE_URL",
3  "value": "http://user-service.internal.local:8080"
4}

Use Cloud Map names if you want direct DNS-based discovery without app-level endpoint registry.

Service Discovery with Cloud Map

ECS can register service instances into AWS Cloud Map automatically.

Key benefits:

  • Dynamic endpoint updates when tasks scale.
  • No hardcoded task IPs.
  • Clean namespace model for multi-service systems.

This is the ECS-native way to connect microservices across task definitions.

Security and Networking Controls

Cross-task communication should always be controlled by security groups and subnet routing. In awsvpc mode each task gets its own ENI, so treat each task like a network host.

Checklist:

  • Allow inbound port only from required security groups.
  • Keep services private unless internet exposure is needed.
  • Use TLS between services where sensitive data flows.

Networking controls replace assumptions that links once handled implicitly.

If you inherit old bridge-mode links:

  1. Move to awsvpc networking.
  2. Replace links with localhost sidecar calls for same-task dependencies.
  3. Replace cross-task links with Cloud Map or load balancer DNS.
  4. Validate health checks and retry behavior.

This migration improves portability to Fargate and aligns with current ECS best practices.

Common Pitfalls

  • Expecting links to work in Fargate. Fix by using service discovery or same-task localhost communication.
  • Trying to link containers across unrelated task definitions. Fix by connecting services through DNS and load balancing.
  • Hardcoding task IP addresses. Fix by using ECS service endpoints or Cloud Map names.
  • Ignoring security-group paths between tasks. Fix by allowing only required source groups and ports.
  • Mixing legacy bridge assumptions with awsvpc networking. Fix by redesigning communication patterns for ENI-based tasks.

Summary

  • Container links are legacy and not the right solution for modern ECS architectures.
  • Inside one task, containers should communicate via localhost.
  • Across task definitions, use ECS service discovery or internal load balancers.
  • Secure traffic with security groups and explicit network policy.
  • Migrating off link-based designs improves reliability and Fargate compatibility.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.