Cloud  /  AWS

AWS Amazon Web Services 61 guides · updated 2026

Hands-on guides to compute, storage, databases, networking, and serverless on the world's most widely adopted cloud platform.

Elastic IP Addresses in AWS: Static IPs That Follow Your Resources

When you launch an EC2 instance, AWS assigns it a public IP from a shared pool. Stop the instance and that IP returns to the pool. Start it again and you get a different IP. For anything that relies on a stable address — a DNS A record, a customer’s firewall whitelist, a TLS certificate — this is a problem.

Elastic IP addresses (EIPs) solve it. An EIP is a public IPv4 address allocated to your AWS account until you explicitly release it. You control it, attach it to resources, move it between resources, and decide when to give it back.

How Elastic IPs Work

An Elastic IP is held at the account level, independent of any resource. You allocate it, then associate it with an instance or network interface. If the instance fails, you disassociate the EIP and associate it with a replacement — the address stays the same throughout.

AWS Account:
Allocated EIPs:
54.123.45.67 (associated with i-0abc123, running in us-east-1a)
54.234.56.78 (not associated — billing applies)
54.345.67.89 (associated with nat-0def456)
Action: i-0abc123 fails
Disassociate 54.123.45.67 from i-0abc123
Associate 54.123.45.67 with i-0ghi789 (replacement)
Result: DNS A record still resolves to 54.123.45.67, which now
points to the replacement instance

Allocating and Associating an EIP

Terminal window
# Allocate an Elastic IP to your account
EIP_INFO=$(aws ec2 allocate-address --domain vpc --output json)
EIP_ALLOC=$(echo $EIP_INFO | jq -r '.AllocationId')
EIP_ADDR=$(echo $EIP_INFO | jq -r '.PublicIp')
echo "Allocated: $EIP_ADDR (Allocation ID: $EIP_ALLOC)"
# Associate with a running instance
aws ec2 associate-address \
--instance-id i-0abc123 \
--allocation-id $EIP_ALLOC
# Verify the association
aws ec2 describe-addresses \
--allocation-ids $EIP_ALLOC \
--query 'Addresses[0].[PublicIp,InstanceId,AssociationId]' \
--output table

The instance now uses the EIP as its public IP. Previous auto-assigned public IP is released.

Disassociating and Reassociating

Terminal window
# Get the current association ID
ASSOC_ID=$(aws ec2 describe-addresses \
--allocation-ids $EIP_ALLOC \
--query 'Addresses[0].AssociationId' --output text)
# Disassociate from current instance
aws ec2 disassociate-address --association-id $ASSOC_ID
# Associate with new instance (failover scenario)
aws ec2 associate-address \
--instance-id i-0replacement \
--allocation-id $EIP_ALLOC

The reassociation takes seconds. A DNS record pointing to the EIP now routes to the new instance without any DNS change or TTL wait.

The Idle Cost Trap

AWS charges for Elastic IPs when they are allocated but NOT associated with a running resource. The billing:

This sounds small, but unused EIPs accumulate. A team that allocates EIPs for testing and forgets to release them can face unexpected charges.

Terminal window
# Find all unassociated EIPs (the ones costing you money)
aws ec2 describe-addresses \
--query 'Addresses[?AssociationId==`null`].[AllocationId,PublicIp]' \
--output table
# Release an unneeded EIP
aws ec2 release-address --allocation-id $EIP_ALLOC

Set up a Lambda function or AWS Config rule to alert when unassociated EIPs have been idle for more than 24 hours.

EIP Limits

Default limit: 5 Elastic IPs per region per account. This is a soft limit — you can request increases through AWS Service Quotas. Large deployments with many NAT Gateways or externally-facing services regularly request 50-100+ EIPs in a region.

Terminal window
# Check your current EIP allocation in a region
aws ec2 describe-addresses --query 'length(Addresses)' --output text
# Check the limit
aws service-quotas get-service-quota \
--service-code ec2 \
--quota-code L-0263D0A3

EIPs and the IPv4 Billing Change

Since February 2024, AWS charges $0.005 per hour for any public IPv4 address — including auto-assigned IPs and EIPs associated with running instances. Previously, an EIP on a running instance was free.

This change makes the EIP cost model simpler: you pay $0.005/hr for every public IPv4 address regardless of whether it is an EIP or auto-assigned.

For this reason, some teams are migrating to IPv6-only workloads or using private addressing with NLBs that provide static IPs without requiring EIPs on instances.

EIPs with NAT Gateway

Every public NAT Gateway requires an Elastic IP. The EIP is what makes the NAT Gateway reachable from the internet and provides the stable source IP that external services see.

Terminal window
# Create EIP for NAT Gateway
NAT_EIP=$(aws ec2 allocate-address \
--domain vpc \
--tag-specifications 'ResourceType=elastic-ip,Tags=[{Key=Name,Value=nat-gw-1a},{Key=Purpose,Value=nat-gateway}]' \
--query 'AllocationId' --output text)
# Create NAT Gateway with this EIP
aws ec2 create-nat-gateway \
--subnet-id subnet-public-1a \
--allocation-id $NAT_EIP \
--tag-specifications 'ResourceType=natgateway,Tags=[{Key=Name,Value=nat-1a}]'

The NAT Gateway’s EIP appears as the source IP for all outbound traffic from private subnets. If you need to whitelist your AWS environment’s IP at an external service, this is the IP to provide.

EIPs and High Availability Patterns

Active-Passive Failover

For services that cannot use a load balancer (databases with direct IP dependencies, custom TCP servers), EIP remapping provides basic failover:

import boto3
def failover_to_standby(primary_instance_id, standby_instance_id, eip_allocation_id):
ec2 = boto3.client('ec2')
# Get current association
addresses = ec2.describe_addresses(AllocationIds=[eip_allocation_id])
current_assoc = addresses['Addresses'][0].get('AssociationId')
if current_assoc:
ec2.disassociate_address(AssociationId=current_assoc)
print(f"Disassociated from primary")
# Associate with standby
ec2.associate_address(
InstanceId=standby_instance_id,
AllocationId=eip_allocation_id
)
print(f"Moved EIP to standby instance {standby_instance_id}")
# Called from a CloudWatch alarm action or Lambda health check
failover_to_standby('i-0primary', 'i-0standby', 'eipalloc-0abc123')

This pattern is simpler than running a full load balancer for scenarios where only one active server is needed.

EIP Best Practices

Tag every EIP with purpose and owner. EIPs are one of the most commonly orphaned resources. A tag like Purpose=nat-gateway-1a and Owner=platform-team makes it easy to find the right owner when auditing.

Release EIPs immediately when not needed. There is no reason to hold an EIP “just in case”. If you need one again, allocate a new one. The only scenario where holding an EIP makes sense is if you have externally-imposed IP allowlists that are slow to update.

Use Route 53 instead of EIPs for DNS when possible. Route 53 health checks + failover routing let you change the IP your domain resolves to within 60 seconds. This eliminates the need for EIP remapping in most active-passive scenarios.

Automate EIP audit. A weekly Lambda function that emails a report of unassociated EIPs prevents slow accumulation of idle charges.

Common Interview Questions

Q: What is the difference between a public IP and an Elastic IP? A public IP is auto-assigned from AWS’s pool and changes if the instance stops. An Elastic IP is allocated to your account, remains the same until you release it, and can be associated with different resources as needed.

Q: How many Elastic IPs can you have per region? Default is 5, but this is a soft limit that can be increased. AWS limits EIPs because IPv4 addresses are scarce.

Q: If you stop and start an instance with an EIP, does it keep the EIP? Yes. The EIP association persists through stop/start. The instance’s auto-assigned public IP (if any) may change, but the EIP remains.

Q: Does an EC2 instance see its Elastic IP in its network interface configuration? No. The instance sees only its private IP when checking its network interface (e.g., with ip addr). The Elastic IP mapping happens at the Internet Gateway level, transparently to the instance.