When working with AWS EC2 instances, you might encounter a frustrating behavior: attempting to associate a second Elastic IP (EIP) automatically disassociates the first one. This occurs because:
# This AWS CLI command will fail for non-VPC instances:
aws ec2 associate-address --instance-id i-1234567890abcdef0 --public-ip 203.0.113.1
aws ec2 associate-address --instance-id i-1234567890abcdef0 --public-ip 203.0.113.2
# The second command disassociates the first IP
The key to multiple EIP assignments lies in using Amazon Virtual Private Cloud (VPC). In the EC2-Classic network (older accounts), each instance can only have one public IP. However, VPC-enabled accounts support:
- Multiple EIPs through secondary private IPs
- Network interface attachments
- Better IP management flexibility
Here's how to properly assign multiple EIPs:
# 1. Allocate new Elastic IPs
aws ec2 allocate-address --domain vpc
# 2. Create secondary network interface (if needed)
aws ec2 create-network-interface --subnet-id subnet-123456 --description "Secondary ENI"
# 3. Assign secondary private IP
aws ec2 assign-private-ip-addresses --network-interface-id eni-123456 --secondary-private-ip-address-count 1
# 4. Associate EIPs
aws ec2 associate-address --allocation-id eipalloc-123456 --network-interface-id eni-123456 --private-ip-address 10.0.0.25
For instances that need multiple IPs with distinct security profiles:
# Attach additional ENI to instance
aws ec2 attach-network-interface \
--network-interface-id eni-123456 \
--instance-id i-1234567890abcdef0 \
--device-index 1
# Then associate EIP with the new ENI
aws ec2 associate-address \
--allocation-id eipalloc-123456 \
--network-interface-id eni-123456
If you're still facing problems:
- Verify your instance type supports multiple network interfaces
- Check VPC subnet settings for IP availability
- Ensure IAM permissions include ec2:AssociateAddress and ec2:AssignPrivateIpAddresses
For mission-critical deployments:
- Use Terraform or CloudFormation for repeatable configurations
- Implement IP failover with AWS Lambda
- Monitor EIP usage with CloudWatch
Many AWS users encounter this exact situation: when attempting to associate a second Elastic IP with an EC2 instance, the system automatically disassociates the existing Elastic IP. This behavior is by design in the EC2-Classic environment, but can be overcome by using VPC.
AWS imposes different networking rules between EC2-Classic and VPC environments. The key differences:
- EC2-Classic: Only 1 Elastic IP per instance (new association replaces the old one)
- VPC: Multiple Elastic IPs per instance through multiple network interfaces
1. Verify Your Instance is in a VPC
Check your instance's details in AWS Console or via CLI:
aws ec2 describe-instances --instance-id i-1234567890abcdef0 --query 'Reservations[].Instances[].VpcId'
2. Create Additional Network Interfaces
Each Elastic IP needs its own ENI (Elastic Network Interface):
aws ec2 create-network-interface \
--subnet-id subnet-12345678 \
--description "Secondary ENI for multi-EIP setup" \
--groups sg-12345678
3. Attach ENIs to Your Instance
aws ec2 attach-network-interface \
--network-interface-id eni-12345678 \
--instance-id i-1234567890abcdef0 \
--device-index 1
4. Associate Elastic IPs
Now associate EIPs to each interface:
aws ec2 associate-address \
--allocation-id eipalloc-12345678 \
--network-interface-id eni-12345678
Consider a web server hosting multiple SSL sites, each needing its own IP:
- Create 3 ENIs (1 primary + 2 secondary)
- Attach all to the instance
- Assign unique Elastic IPs to each
- Configure web server to listen on specific IPs
- Instance type must support multiple network interfaces (most current gen instances do)
- Additional ENIs count toward your account's service limits
- Each secondary ENI incurs additional hourly charges
- Remember to update security groups for all ENIs
If Elastic IPs aren't working as expected:
# Check ENI attachments
aws ec2 describe-network-interfaces --filters Name=attachment.instance-id,Values=i-1234567890abcdef0
# Verify EIP associations
aws ec2 describe-addresses --filters Name=instance-id,Values=i-1234567890abcdef0