
Use this bash script to automatically find and release unassociated Elastic IP addresses across all AWS regions. Unattached EIPs cost money, so regular cleanup directly impacts your AWS bill.
Introduction
Unattached Elastic IPs cost about $0.005/hour each (~$3.60/month per EIP). One or two of these is nothing, but they pile up across multi-account environments, especially in regions where someone spun up a NAT or workload, deleted it, and forgot the EIP was sitting there detached.
This is a small bash script that runs in CloudShell, scans every region, finds Elastic IPs with no Association, and releases them. Cron it monthly or run on demand.
Once an Elastic IP is released, you cannot get the same IP address back. If any external systems or DNS records reference this IP, they will need to be updated. Document your EIPs before running cleanup scripts.
Use This
- AWS CloudShell
- Bash Script
Do This
- Open CloudShell
- Create bash file: touch removeEIP.sh
- Create contents of bash file: vi removeEIP.sh
- Type in code below
- Save the file
- Change the file to an executable file: chmod +x removeEIP.sh
- Run the script: ./removeEIP.sh
AWS charges approximately $0.005 per hour for each unattached Elastic IP address. This adds up to roughly $3.60 per month per unused EIP - a small amount that can become significant at scale.
Write This
#!/bin/bash
# Fetch all AWS regions
for region in $(aws ec2 describe-regions --output text --query 'Regions[].RegionName')
do
echo "Checking region $region"
# Fetch all Elastic IPs not allocated to a network interface
for allocation in $(aws ec2 describe-addresses --region "$region" --query "Addresses[?AssociationId==null].AllocationId" --output text)
do
echo "Releasing unattached Elastic IP with allocation id $allocation in region $region"
aws ec2 release-address --region "$region" --allocation-id "$allocation"
done
# Add other services and their corresponding commands here
# ...
done
Before releasing EIPs, export a list of all your Elastic IPs with their allocation IDs and associated resources using: aws ec2 describe-addresses --output json > eip-backup.json. This creates a record you can reference if needed.
What The Heck Does This Code Do
- Gets a list of all AWS regions
- For each of the region found, find all Elastic IP Addresses
- Find any Elastic IP Addresses that are not associated to anything
- Relase the unused Elastic IP Addresses
Troubleshooting
Common Issues and Solutions
AuthFailure Error
- Problem: Cannot release Elastic IP due to authentication failure
- Solution: Ensure your IAM user/role has ec2:ReleaseAddress permission. Check if the EIP was allocated in a different account or if there are SCPs blocking the action.
EIP Associated with NAT Gateway
- Problem: Script shows EIP as unattached but release fails
- Solution: EIPs attached to NAT Gateways may show as unassociated in some queries. Check NAT Gateway associations before releasing.
DisassociateAddress Required
- Problem: EIP cannot be released because it's still associated
- Solution: The script filters for unassociated EIPs. If you need to release an associated EIP, first disassociate it using aws ec2 disassociate-address.
EIP Limit Reached After Release
- Problem: Cannot allocate new EIP after releasing old ones
- Solution: AWS has regional EIP limits (default is 5). Request a limit increase through Service Quotas if needed.
Released EIP Still Appearing in Billing
- Problem: Charges continue after releasing EIP
- Solution: Billing is updated at the end of the billing cycle. Check Cost Explorer to confirm the EIP was released and charges stopped from that point forward.