Help us improve the AWS re:Post Knowledge Center by sharing your feedback in a brief survey. Your input can influence how we create and update our content to better support your AWS journey.
How do I identify, monitor, and optimize my Amazon VPC public IPv4 address usage?
I want to identify, monitor, and optimize my Amazon Virtual Private Cloud (Amazon VPC) IPv4 address usage.
Resolution
Note: If you receive errors when you run AWS Command Line Interface (AWS CLI) commands, then see Troubleshooting errors for the AWS CLI. Also, make sure that you're using the most recent AWS CLI version.
All public IPv4 addresses incur a charge of $0.005 for each IP address each hour whether attached to a service or not. If you're an AWS Free Tier customer for Amazon Elastic Compute Cloud (Amazon EC2), then you receive 750 free hours of usage. This free usage is for when you launch an Amazon EC2 instance with a public IPv4 address.
Activate Public IP insights
You can use Public IP insights to monitor, analyze, and audit the public IPv4 addresses that your services currently use across AWS Regions.
To activate Public IP insights, create an Amazon VPC IP Address Manager (IPAM) pool. To identify public IPv4 address usage, integrate IPAM Public IP insights with a single AWS account or with your AWS Organizations accounts.
Note: There's no cost for Public IP insights under the Free Tier. For Advanced Tier pricing information, see the IPAM tab on the Amazon VPC pricing page. When you integrate IPAM with Organizations, you can use Public IP insights for all Regions and accounts in your organization, even in Free Tier.
To view the results, you can use the Amazon VPC console or the AWS CLI.
Note: After you create an IPAM pool, Public IP insights generates a report for your public IPv4 addresses. The time required to generate the report is based on the size of your organization.
Activate your Cost and Usage Report
Your AWS Cost and Usage Report (CUR) includes usage data for both in use and unused public IPv4 addresses. When you create your CUR, select Include resource IDs to get detailed resource-level analysis. After you create your CUR, AWS updates the report files that contain data for the month to date at least once a day. You can use the report files to analyze historical IPv4 address usage data.
Note: You can access the reports from an Amazon Simple Storage Service (Amazon S3) bucket. AWS can take up to 24 hours to deliver reports to your Amazon S3 bucket.
Immediately identify public IPv4 addresses
Note: It's a best practice to use CUR and Public IP insights for your planned analysis of public IPv4 address usage.
To immediately identify services that use public IPv4 addresses, use the Amazon EC2 console or the AWS CLI.
Amazon EC2 console
To analyze your network interfaces to view the AWS services that use public IPv4 addresses, complete the following steps:
- Open the Amazon EC2 console.
- In the navigation pane, under Network & Security, choose Network Interfaces.
- Under the Public IPv4 Addresses filter, enter <*> to identify the elastic network interfaces that use the primary public IPv4 address.
- Use the network interface description and interface type to identify the service that uses the public IPv4 address.
- To show all public and secondary IP addresses that have network interfaces in a Region, run the following command:
Note: Replace example-region with your Region.aws ec2 describe-network-interfaces --region example-region --query 'NetworkInterfaces[*].PrivateIpAddresses[?Association.PublicIp].Association.PublicIp[]' --output table
For public IPv4 addresses that AWS Site-to-Site VPN uses, see How do I check the current status of my VPN tunnel?
For public IPv4 addresses that the standard and custom AWS Global Accelerator, see Viewing your accelerators.
To view idle or associated elastic IP addresses, complete the following steps:
- Open the Amazon EC2 console.
- In the navigation pane, under Network & Security, choose Elastic IPs.
- Select an elastic IP address to view the resources that use that elastic IP address.
Note: For more information about the usage, check the Network interface or Instance fields.
There's no charge for bring your own IP addresses (BYOIPs). AWS bills Global Accelerator in the us-west-2 Region.
AWS CLI
Prerequisites: Run the aws configure AWS CLI command to set your credentials. Also, install Boto3. For more information, see Install Boto3 on the Boto3 website.
To immediately identify services that use public IPv4 addresses, complete the following steps from an AWS CloudShell or Linux environment:
-
Create the following file:
touch public_ipv4_recon.py -
Run the following command to edit the file:
vim public_ipv4_recon.py -
Copy and paste the following code into the file, and then save the file:
#!/usr/bin/env python3 import pprint import boto3, sys profile = boto3.Session(profile_name=sys.argv[1]) aga = profile.client('globalaccelerator', region_name='us-west-2') ec2 = boto3.client('ec2') def global_public_ipv4_lookup(aga): try: # global accelerator next_token = None while True: if next_token: resource = aga.list_accelerators( NextToken = next_token ) else: resource = aga.list_accelerators( ) print('Describing world wide Global Accelerators...') print('Note: AWS Global Accelerators are billed in us-west-2....') print(f'Number of AGA: {len(resource["Accelerators"])}') print('-'*40) for item in resource["Accelerators"]: print(f'Name: {item["Name"]}') if 'IpSets' in item.keys(): for ip in item["IpSets"][0]["IpAddresses"]: print(f'Public IPv4: {ip}') print(f'Status: {item["Status"]}') print() next_token = resource.get("NextToken") if next_token is None: break print() # custom_routing_accelerators next_token = None while True: if next_token: custom_routing = aga.list_custom_routing_accelerators( NextToken = next_token ) else: custom_routing = aga.list_custom_routing_accelerators( ) print('Describing world wide Custom Routing Accelerators...') print('Note: AWS Global Accelerators are billed in us-west-2....') print(f'Number of custom AGA: {len(custom_routing["Accelerators"])}') print('-'*40) for item in custom_routing["Accelerators"]: if 'IpSets' in item.keys(): for ip in item["IpSets"][0]["IpAddresses"]: print(f'Public IPv4: {ip}') print(f'Status: {item["Status"]}') print() next_token = custom_routing.get("NextToken") if next_token is None: break print() except Exception as err: print(f'Error found: {err}...') pass def public_ipv4_lookup(ec2): try: # vpn next_token = None while True: if next_token: vpn = ec2.describe_vpn_connections( NextToken = next_token ) else: vpn = ec2.describe_vpn_connections( ) print('Describing VPNs...') print(f'Number of Vpn connections: {len(vpn["VpnConnections"])}') print('-'*40) for item in vpn["VpnConnections"]: if 'VpnConnectionId' in item.keys(): print(f'Vpn Id: {item["VpnConnectionId"]}') for ip in item["VgwTelemetry"]: print(f'Public ipv4: {ip["OutsideIpAddress"]}') print() next_token = vpn.get("NextToken") if next_token is None: break print() # elastic ip eip = ec2.describe_addresses( ) print('Describing Elastic IPs...') print(f'Number of Elastic Ips: {len(eip["Addresses"])}') print('-'*40) for item in eip["Addresses"]: if 'AllocationId' in item.keys(): print(f'Eip Id: {item["AllocationId"]}') print(f'Public ipv4: {item["PublicIp"]}') print() print() # network interfaces next_token = None while True: if next_token: interface = ec2.describe_network_interfaces( NextToken=next_token ) else: interface = ec2.describe_network_interfaces( ) print('Describing Network Interfaces...') print(f'Number of interfaces: {len(interface["NetworkInterfaces"])}') print('Only printing Interfaces with a public IPv4 address...') print('-'*40) for item in interface["NetworkInterfaces"]: for ip in item["PrivateIpAddresses"]: if 'Association' not in ip.keys(): pass else: print(f'Interface Id: {item["NetworkInterfaceId"]}') print(f'Description: {item["Description"]}') print(f'Status: {interface["NetworkInterfaces"][0]["Status"]}') print(f'Public Ip: {ip["Association"]["PublicIp"]}\n') next_token = interface.get("NextToken") if next_token is None: break except Exception as err: print(f'Error found: {err}...') pass # Run code if len(sys.argv) < 3 or not sys.argv[2]: global_public_ipv4_lookup(aga) regions_list = ec2.describe_regions( AllRegions=False ) for region in regions_list['Regions']: if region["OptInStatus"] == 'opted-in' or 'opt-in-not-required': print(f'\n**********-[{region["RegionName"]}]-**********\n') public_ipv4_lookup( ec2=profile.client('ec2', region_name=region["RegionName"]) ) elif sys.argv[2]: global_public_ipv4_lookup(aga) public_ipv4_lookup( ec2=profile.client('ec2', region_name=sys.argv[2]) ) -
To check in all Regions, run the following command:
python3 public_ipv4_recon.py example-cli-profileNote: Replace example-cli-profile with the name of the configured AWS CLI profile or any profile name defined in the .aws/credentials file. If you use Windows, then replace python3 with python.
-or-
To check a specific Region, run the following command:python3 public_ipv4_recon.py example-cli-profile example-regionNote: Replace example-cli-profile with the name of the configured AWS CLI profile or any profile name defined in the .aws/credentials file. Replace example-region with the Region.
If you're not authorized to run the request or the Region is deactivated for your account, then you might receive the following error:
"Error found: An error occurred (AuthFailure) when calling the <API> operation: AWS was not able to validate the provided access credentials..."
Optimize public IPv4 addresses usage and adopt IPv6 addresses
To optimize costs, enhance your current architecture to minimize the use of public IPv4 addresses. It's a best practice to migrate to IPv6. There's no charge for IPv6 addresses.
- Tags
- Amazon VPC
- Language
- English

Relevant content
- Accepted Answerasked 2 years ago
AWS OFFICIALUpdated 8 months ago
AWS OFFICIALUpdated 4 months ago
AWS OFFICIALUpdated 9 months ago