devuplabs.cloud
PreviewLab1.5 hours

ENIs and IPs

ENIs, public vs Elastic IPs, source/destination check, IP exhaustion, and Fargate subnet sizing.

  • This builds on The VPC Itself through Load Balancers. Your VPC, subnets, route tables, and IGW must exist.
  • In a new terminal session, run the resume script at the end of Load Balancers.
  • Read the callout before every step. Predict, run, verify.

ENI: What It Is and What It Carries

Goal

Understand what an ENI is, what properties it holds, and why every networked resource in AWS is ultimately an ENI.

Estimated time: 30 minutes

What an ENI actually is

What's happening here

An Elastic Network Interface (ENI) is the fundamental networking primitive in AWS. Every resource that has network connectivity. EC2 instances, Fargate tasks, Lambda functions in a VPC, RDS instances, VPC endpoint ENIs, NAT Gateways, is ultimately one or more ENIs. An ENI carries:

  • One primary private IPv4 address (assigned from the subnet CIDR, permanent for the life of the ENI)
  • Zero or more secondary private IPv4 addresses (same subnet)
  • Zero or one public IPv4 address (ephemeral, assigned to the primary private IP)
  • Zero or one Elastic IP (static, associated with one private IP)
  • One or more security groups (up to 5 by default)
  • One MAC address (stays with the ENI, moves with it when re-attached)
  • A source/destination check flag (enabled by default; must be disabled for NAT instances)

The ENI is the object. The instance, task, or service is what the ENI is attached to. Understanding this distinction explains many things: why security groups attach per-resource not per-subnet, why a secondary ENI can be moved from one instance to another carrying its IP and MAC, and why ECS Fargate consumes one IP per task.

PropertyExampleMeaning
NetworkInterfaceIdeni-xxxxxxxxxxStable identifier
SubnetIdsubnet-xxxFixed AZ, ENI cannot move across AZs
VpcIdvpc-xxxFixed VPC, ENI cannot move across VPCs
PrivateIpAddress10.0.11.xPrimary private IP, permanent, from subnet CIDR
PrivateIpAddresses[primary+secondary]All private IPs on this ENI
Association.PublicIp54.x.x.xEphemeral public IP (changes on stop/start)
Association.AllocationIdeipalloc-xxxEIP association (static, persists)
Groups[sg-xxx, ...]Security groups (firewall rules)
MacAddressxx:xx:xx:xx:xx:xxFixed to ENI, moves with it
SourceDestChecktrue/falseMust be false for NAT/routing instances
Attachment.StatusattachedWhich instance/resource it is attached to
Statusin-use/availableavailable = not attached to anything

Create a standalone ENI

What's happening here

ENIs can be created independently of any instance or service. A standalone ENI has status available: it exists, has a private IP reserved from the subnet, and can be attached to a resource later. This is how you pre-allocate IPs, create failover setups (detach from failed instance, attach to replacement), or hold a specific IP address for a future deployment. The private IP is reserved the moment the ENI is created, even before anything is attached.

bash
# Create a standalone ENI in the private subnet
export ENI_ID=$(aws ec2 create-network-interface \
  --subnet-id $PRIVATE_SUBNET_AZ1 \
  --description "networking-lab standalone ENI" \
  --groups $SG_APP \
  --region $AWS_REGION \
  --query 'NetworkInterface.NetworkInterfaceId' --output text)

aws ec2 create-tags --resources $ENI_ID \
  --tags Key=Name,Value=lab-eni --region $AWS_REGION

echo "ENI ID: $ENI_ID"

# Inspect everything about it
aws ec2 describe-network-interfaces \
  --network-interface-ids $ENI_ID \
  --region $AWS_REGION \
  --query 'NetworkInterfaces[0].{
    Id:NetworkInterfaceId,
    Status:Status,
    PrivateIP:PrivateIpAddress,
    Subnet:SubnetId,
    AZ:AvailabilityZone,
    MAC:MacAddress,
    SGs:Groups[*].GroupId,
    SourceDestCheck:SourceDestCheck,
    PublicIP:Association.PublicIp
  }'

Observe: Status: available (not attached). PrivateIP is assigned from 10.0.11.0/24. PublicIP is null, standalone ENIs don't get public IPs automatically. SourceDestCheck: true by default.

Checkpoint: ENI created, status available: private IP assigned.


Add a secondary private IP to the ENI

What's happening here

An ENI can hold multiple private IP addresses from the same subnet CIDR. The first is the primary (it cannot be removed. Additional ones are secondary) they can be assigned and unassigned at will. This is used for hosting multiple SSL certificates on one instance (each cert gets its own IP), for container networking (each container on an EC2 instance gets its own secondary IP on the host's ENI), and for custom fail-over where a floating IP moves between ENIs. Each secondary private IP consumes one address from the subnet.

bash
# Add a secondary private IP (let AWS pick one)
aws ec2 assign-private-ip-addresses \
  --network-interface-id $ENI_ID \
  --secondary-private-ip-address-count 1 \
  --region $AWS_REGION

# Verify both IPs
aws ec2 describe-network-interfaces \
  --network-interface-ids $ENI_ID \
  --region $AWS_REGION \
  --query 'NetworkInterfaces[0].PrivateIpAddresses[*].{IP:PrivateIpAddress,Primary:Primary}'

Observe: two IPs now, one with Primary: true: one with Primary: false. Both are allocated from the 10.0.11.0/24 subnet and are unavailable to any other resource.

bash
# Remove the secondary IP
SECONDARY_IP=$(aws ec2 describe-network-interfaces \
  --network-interface-ids $ENI_ID \
  --region $AWS_REGION \
  --query 'NetworkInterfaces[0].PrivateIpAddresses[?Primary==`false`].PrivateIpAddress' \
  --output text)

aws ec2 unassign-private-ip-addresses \
  --network-interface-id $ENI_ID \
  --private-ip-addresses $SECONDARY_IP \
  --region $AWS_REGION

echo "Secondary IP $SECONDARY_IP released back to subnet pool."

Public IPs vs Elastic IPs

Goal

Understand the difference between auto-assigned public IPs and Elastic IPs. Demonstrate that public IPs are ephemeral. Assign an EIP and observe it persists.

Estimated time: 20 minutes

Unlock all 24 AWS services & 291+ lab sessions (~180 hours)

Pricing