ECS Service Connect is surprisingly not a replacement for Cloud Map, but rather an enhancement for specific use cases within ECS.

Imagine you have two services running on ECS, frontend-service and backend-service. Before Service Connect, if frontend-service needed to talk to backend-service, you’d typically use Cloud Map. When backend-service registered itself with Cloud Map, it got a DNS name like my-backend-service.my-namespace.my-region.ecs.amazonaws.com. Your frontend-service would then resolve this DNS name to get the IP addresses and ports of the backend-service tasks. This works great for general service discovery across ECS or even other AWS services.

Here’s a minimal Cloud Map setup for backend-service:

aws servicediscovery create-private-dns-namespace \
  --name my-namespace \
  --vpc-id vpc-0123456789abcdef0 \
  --creator-request-id my-namespace-creation

aws servicediscovery register-instance \
  --service-id srv-abcdef1234567890 \
  --instance-id backend-task-1 \
  --attributes '{"AWS_INSTANCE_IPV4":"10.0.1.10", "AWS_INSTANCE_PORT":"8080"}' \
  --creator-request-id backend-instance-registration

Now, frontend-service can curl http://my-backend-service.my-namespace.my-region.ecs.amazonaws.com:8080.

ECS Service Connect simplifies this within ECS. Instead of relying on Cloud Map for every inter-service communication, Service Connect creates a dedicated, private DNS name for each service automatically. When you enable Service Connect for backend-service, it gets a DNS name like backend-service.default.svc.cluster.local (if you’re using the default namespace). Your frontend-service task, when configured to use Service Connect, can then directly resolve this name.

Here’s how you’d enable Service Connect for a task definition:

{
  "family": "frontend-service",
  "taskRoleArn": "arn:aws:iam::123456789012:role/ecsTaskRole",
  "executionRoleArn": "arn:aws:iam::123456789012:role/ecsExecutionRole",
  "networkMode": "awsvpc",
  "containerDefinitions": [
    {
      "name": "frontend",
      "image": "my-frontend-image",
      "portMappings": [
        {
          "containerPort": 3000,
          "hostPort": 3000,
          "protocol": "tcp"
        }
      ],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/frontend-service",
          "awslogs-region": "us-east-1"
        }
      }
    }
  ],
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "256",
  "memory": "512",
  "serviceConnectConfiguration": {
    "logDriver": "awslogs",
    "namespace": "dns-sd",
    "services": [
      {
        "portName": "frontend-port",
        "clientAlias": {
          "port": 80,
          "dnsName": "frontend.my-domain.com"
        },
        "discoveryName": "frontend-service"
      }
    ]
  }
}

And for the backend service:

{
  "family": "backend-service",
  "taskRoleArn": "arn:aws:iam::123456789012:role/ecsTaskRole",
  "executionRoleArn": "arn:aws:iam::123456789012:role/ecsExecutionRole",
  "networkMode": "awsvpc",
  "containerDefinitions": [
    {
      "name": "backend",
      "image": "my-backend-image",
      "portMappings": [
        {
          "containerPort": 8080,
          "hostPort": 8080,
          "protocol": "tcp"
        }
      ],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/backend-service",
          "awslogs-region": "us-east-1"
        }
      }
    }
  ],
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "256",
  "memory": "512",
  "serviceConnectConfiguration": {
    "logDriver": "awslogs",
    "namespace": "dns-sd",
    "services": [
      {
        "portName": "backend-port",
        "discoveryName": "backend-service"
      }
    ]
  }
}

The frontend-service can then call backend-service using curl http://backend-service.default.svc.cluster.local:8080. This DNS name is managed by ECS and automatically points to healthy backend-service tasks.

The key difference is that Service Connect is deeply integrated into ECS and provides a more streamlined experience for within-ECS communication. It handles the registration and discovery of services automatically when you enable it on a service. Cloud Map, on the other hand, is a more general-purpose AWS service discovery tool that can be used for a wider range of scenarios, including discovery between ECS services, EC2 instances, and even Lambda functions. You can even use Cloud Map to discover services that are not running on ECS.

When you enable Service Connect on an ECS service, a new ServiceConnectConfig object is added to your service definition. This object contains the namespace (e.g., dns-sd or a custom Cloud Map namespace), and a list of services. Each service in this list defines a portName that corresponds to a portMapping in your container definition, and an optional clientAlias which provides a custom DNS name and port for clients to connect to. The discoveryName is the name that other services will use to discover this service.

The magic happens when ECS creates a dedicated network endpoint for each service that has Service Connect enabled. This endpoint is managed by ECS and is responsible for routing traffic to the healthy tasks of that service. When another service tries to resolve the discoveryName (e.g., backend-service.default.svc.cluster.local), ECS’s internal DNS resolver intercepts this request and returns the IP addresses and ports of the healthy backend tasks. This bypasses the need for manual Cloud Map registration for basic ECS-to-ECS communication.

If you’re already using Cloud Map for complex cross-service discovery, or for discovering services outside of ECS, you don’t necessarily need to migrate to Service Connect. Service Connect is best suited for simplifying the service discovery aspect of intra-ECS communication by automating much of the setup. It also provides features like traffic routing and load balancing at the service level, which can be simpler to manage than configuring those separately with Cloud Map and a load balancer.

One subtle but powerful aspect of Service Connect is its ability to manage health checks and provide weighted routing per service. When you configure a service with Service Connect, ECS implicitly handles routing traffic only to healthy tasks. Beyond that, you can configure weighted routing between different versions or configurations of the same service directly within the Service Connect configuration of the client service, allowing for sophisticated canary deployments or A/B testing without needing to manage separate Cloud Map namespaces or load balancers for each variant.

The next thing you’ll likely encounter is how to integrate Service Connect with external services or how to manage configurations for a large number of services.

Want structured learning?

Take the full Ecs course →