skip to content

ECS supports several network modes, and Fargate requires awsvpc. What does the awsvpc network mode give each task, and how does it change things compared with the bridge network mode on the EC2 launch type?

level: middleimportance: should knowfreq 56%

answer

  1. one interface per task
  2. security groups stop being host-wide
  3. no host port juggling
  4. target group type must match the mode
  5. interfaces are a finite per-instance resource

basics

~20 s

awsvpc gives every ECS task its own elastic network interface with a private VPC IP and its own security groups, so tasks get first-class VPC identity, no host port mapping, and register in load balancer target groups by IP address.

solid answer

~50 s

With `awsvpc`, ECS attaches a dedicated ENI to each task, so the task has a private IP in one of your subnets and its own security group list — the same network posture as an EC2 instance. Containers in the task share that namespace and talk to each other over `localhost`. Because nothing is multiplexed onto a host, there are no port collisions and no dynamic host-port mapping: the container port is the port, and the ALB target group must use target type `ip` rather than `instance`. With `bridge` on the EC2 launch type, tasks share the instance's ENI and its security group, ECS assigns ephemeral host ports when you leave `hostPort` at 0, and the target group registers instance-and-port pairs. The tradeoff on EC2 is density: each `awsvpc` task consumes an ENI slot on the instance, which is capped by instance type unless you enable the `awsvpcTrunking` account setting. Fargate offers no choice — `awsvpc` is the only mode.

go deeper

for a junior

Know that with awsvpc each ECS task gets its own private IP and its own security groups, and that Fargate always uses this mode.

for a middle

Explain how awsvpc removes host port mapping, why the target group must be type ip, and how containers within a task share one network namespace and reach each other over localhost.

for a senior

Bring the operational consequences: ENI limits and trunking on EC2, subnet IP exhaustion, per-task security group design, and flow-log attribution when investigating an incident.

for a principal

Own the VPC-level plan — subnet sizing and CIDR strategy for a cluster that will scale, whether per-task security groups or a service mesh expresses your segmentation, and what that costs in address space.

## What awsvpc allocates When a task launches with `networkMode: awsvpc`, ECS creates an elastic network interface, attaches it to the task, and places it in a subnet you named in the `awsvpcConfiguration` of the service or `RunTask` call: ```json { "awsvpcConfiguration": { "subnets": ["subnet-0a1b", "subnet-2c3d"], "securityGroups": ["sg-0api"], "assignPublicIp": "DISABLED" } } ``` The task now has: - **Its own private IP** inside your VPC CIDR, routable like any other VPC resource. - **Its own security groups**, evaluated independently of anything else running on the same host. - **Its own network namespace**, shared by every container in the task. Two containers in one task reach each other at `localhost:<port>` and cannot both bind the same port. - **VPC flow log records** attributable to that task's ENI rather than to a shared host interface. That last point plus per-task security groups is the real prize: you can write a rule that says "only the payments task may reach the payments database", which under `bridge` you cannot express at all, because every task on the instance shares the instance's security group. ## bridge and host on the EC2 launch type `bridge` uses the Docker bridge network on the container instance. Containers get a host-internal address, and the `portMappings` entry maps `containerPort` to a `hostPort`. Set `hostPort: 0` and ECS picks an ephemeral port from the instance's range, which is what makes it possible to run several copies of the same container on one instance — and what forces the load balancer to register instance-plus-port targets that ECS keeps in sync. `host` skips the bridge and binds the container directly to the instance's network interface. It is the fastest path and the least flexible: one task per port per instance, and the container sees the host's addresses. `awsvpc` is available on both launch types, but it is *required* on Fargate — there are no shared hosts you own to bridge onto. ## Consequences for load balancing This is the part interviewers probe. Under `awsvpc`, the ECS service registers **task IP addresses** into the target group, so the target group must have been created with target type `ip`. Under `bridge` with dynamic ports, ECS registers **instance ID and host port** pairs, so the target group is target type `instance`. Creating the target group with the wrong type is a very common first-deployment failure: the service creation call is rejected, or targets never register and the ALB reports no healthy hosts. Security groups also move. With `awsvpc`, the rule you write is "the task's security group allows 8080 from the ALB's security group". With `bridge`, the rule is on the *instance* security group and must cover the whole ephemeral port range, which is a far coarser grant. ## ENI density on EC2 On the EC2 launch type, `awsvpc` costs an ENI per task, and every instance type has a hard cap on attached ENIs. A small instance may only host two or three `awsvpc` tasks regardless of spare CPU and memory — a nasty surprise if you sized the cluster on CPU alone. The `awsvpcTrunking` account setting (opted into per account and region) attaches a trunk interface to supported instance types and raises the number of tasks per instance substantially. It also means IP address consumption in your subnets scales with task count, so small subnet CIDRs become a real constraint on a busy cluster. On Fargate the ENI is still allocated in your subnet and still consumes an IP, but the instance-level cap is AWS's problem, not yours. ## Egress and metadata Because the task's ENI lives in your subnet, its outbound path is whatever the subnet's route table says. A task in a private subnet reaches the internet only through a NAT gateway, and reaches AWS APIs privately only through VPC endpoints. `assignPublicIp: ENABLED` is only meaningful in a subnet with an internet gateway route; in a private subnet it does nothing useful. Task metadata is served over the same interface at a link-local address, which is how the credentials endpoint and container stats are exposed. ## Choosing On Fargate there is no choice. On EC2, choose `awsvpc` when you want per-task security groups and per-task flow-log attribution — which is nearly always the right default for anything security-relevant — and fall back to `bridge` when task density per instance matters more than network isolation and trunking is not an option.

  • Why must a target group used by an awsvpc ECS service be created with target type ip?
    Because the service registers each task's own ENI private IP as a target, not an instance ID and port. Target type `instance` only accepts instance IDs, so it fits the bridge-mode dynamic-port model instead. The type is fixed at target group creation, so getting it wrong means creating a new target group rather than editing the existing one.
  • On the EC2 launch type, a cluster with plenty of free CPU and memory refuses to place more awsvpc tasks. What is the likely limit?
    The per-instance ENI attachment limit. Each awsvpc task consumes an interface, and that cap is a property of the instance type, independent of CPU and memory headroom. Enabling the `awsvpcTrunking` account setting raises the ceiling on supported instance types; otherwise use larger instances or accept lower density.
  • Two containers in the same awsvpc task both try to listen on port 8080. What happens?
    The second one fails to bind, because containers in a task share a single network namespace under awsvpc — there is no per-container address to disambiguate them. Give them distinct ports. That shared namespace is also why they can talk over `localhost` with no service discovery, which is the usual reason to co-locate a sidecar in the first place.

saying these in an interview costs you the question

  • Thinks awsvpc tasks still need dynamic host port mapping
  • Puts application security group rules on the container instance
  • Assumes a bridge-mode target group works for Fargate
  • Believes containers in one task get separate IP addresses
  • Ignores subnet IP exhaustion as task count grows

context