iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
💰

Preparing for AWS Public IPv4 Address Pricing Changes: EC2 Edition

に公開

Hello.
How are you doing?
I'm Ryo Yoshii, and I love the phrase "No human labor is no human error."

There was a somewhat shocking announcement from AWS on July 28, 2023 (US time).
Starting February 1, 2024, AWS will begin charging an hourly rate for public IPv4 addresses.
Previously, public IP addresses attached to running instances were free, and charges only applied to unused ones, but from February 1, 2024, they will be charged regardless of whether they are in use or not.
The charge is 0.005 USD/hour.
You can calculate the increase with the following formula: 0.005 USD/hour * 24 hours * (28|29|30|31) days * number of instances.

Action Items

When I got to the office on Monday morning and saw the announcement, I started thinking about what to do.
I anticipated a significant impact even before I started working on it.

  • Calculate the number of public IP addresses currently in use and the increased costs
  • Remove public IP addresses from EC2 instances whenever possible
  • Provision NAT Gateways for internet access (outbound from EC2) where needed
  • Consolidate web services currently exposed directly via EC2 to an ALB
  • Consider IPv6 architecture

Calculate the number of public IP addresses currently in use and the increased costs

A feature called Public IP Insights was released at the same time.
If you open this from the management console, it will display the public IP addresses used in that region.

Borrowing an image from Jeff Barr's blog, it shows the usage count for EIPs, EC2 auto-assigned IPs, managed services, and BYOIP.
img

Since the insights include things like NAT Gateways and ELBs, it doesn't show the number of EC2 public IP addresses, which is the main focus of this entry.
If you could count them in the management console, that would be fine, but since we have over 1,000 instances, I will try counting instances with public IP addresses using the AWS CLI.

# Output to a file is not strictly necessary, but I output to a file because I wanted to process it in various ways.
$ aws ec2 describe-instances > describe-instances.out
$ cat describe-instances.out | jq -r '.Reservations[].Instances[] | select(.PublicIpAddress != null) | .InstanceId' | wc -l

The command above allowed me to calculate the number of instances with public IP addresses.
In the systems I am involved with, it was about 900. If I do the math, 0.005 USD/hour * 24 hours * 31 days * 900 = 3,348 USD/month, which is an increase that is no laughing matter.

Remove public IP addresses from EC2 instances whenever possible

I want to remove public IP addresses from EC2 instances. I have considered the conditions under which this is possible:

  • No ports are exposed directly to the internet.
    • If there are ports exposed directly, consider placing them behind an ELB or CloudFront.
    • ↑ This may be driven more by security reasons such as DDoS protection and WAF rather than cost reasons.
  • No inbound traffic from the internet is needed, but outbound traffic is required; in this case, set up routes to the internet that do not go through an Internet Gateway, such as a NAT Gateway.

I believe the conditions depend on the system. However, there is a more difficult problem than these conditions: the fact that if automatic public IP address assignment is enabled at the time of EC2 instance creation, it cannot be changed later.
For instances that currently have automatic public IP assignment, it seems the only option is to create an AMI and recreate them.
There might be a workaround that takes advantage of the specification that public IP addresses cannot be assigned when using multiple ENIs, but since this is not the intended way to use them, I do not want to adopt it.

Replacing instances using AMIs can lead to accidents. I have no choice but to proceed with caution.
I will identify items that will change—such as instance IDs, private IP addresses, tags, and items that require manual reconfiguration—through sufficient testing.
If it is already managed by IaC, I can feel a bit relieved because parts other than those that change dynamically can be controlled. If I am going to introduce IaC from now on, I will import existing resources and place them under control.
If IaC is not feasible, it is possible to semi-automate the process by obtaining existing configuration values with describe-instances from the AWS CLI and passing them to the options of run-instances. It is also effective to diff the results of describe-instances between the old and new instances.

Update on August 2, 2023
Personally, I think Terraform is a simple option with fewer errors.
EC2 public IP address disabling might have been a Terraform-only choice

Update on August 1, 2023
Restoring an EC2 instance from AWS Backup will restore it to almost its original state.
Tags can also be restored if you configure them in advance, provided the backup was created after May 22, 2023. I think this can be a means of replacing instances using AMIs.
I tested how much EC2 configuration can be restored with AWS Backup

For instances behind an ALB, I will consider a method of creating two target groups and gradually migrating traffic while weighing them.
For Auto Scaling EC2 instances, it might be sufficient to just change the launch template.

Disabling automatic subnet assignment

Previously, primary public IP addresses in use were not subject to charges, so I didn't pay much attention to them. However, from now on, I want to disable the automatic public IP address assignment for subnets.
This prevents the situation where an instance is assigned a public IP address when launched without thinking. The operation will involve explicitly specifying whether a public IP address is needed when launching an instance.
img

You can display subnets with automatic public IP assignment enabled using the following command:

aws ec2 describe-subnets | jq -r '.Subnets[] | select(.MapPublicIpOnLaunch == true ) | .SubnetId'

Specify the SubnetId displayed above to disable it via command:

$ aws ec2 modify-subnet-attribute --no-map-public-ip-on-launch --subnet-id SubnetID

Provision a NAT Gateway for instances requiring internet access (outbound from EC2)

I will prepare a NAT Gateway for internet access.
However, the cost is a concern. Let's look at the Amazon VPC pricing for the Tokyo region as of the time of writing.

  • Price per NAT Gateway (USD/hour): 0.062 USD
  • Price per GB of processed data (USD): 0.062 USD
  • Data transfer from Amazon EC2 to the internet (outbound): Same as EC2 data transfer rates

I want to compare the NAT Gateway cost with the new public IP address charges and adopt it if the NAT Gateway is cheaper.
While it is difficult to estimate the amount of processed data in advance, the only way is to make a prediction based on the "Data Transfer" items in the previous month's AWS bill.

Hourly cost: 0.062 USD/Hour * 24h * 31days * {Number of NAT Gateways}
Communication cost: 0.062 * Predicted data volume

If the formula "New charges incurred by public IP addresses > Hourly cost + Communication cost" holds true, then it is acceptable.

Consolidate Web services directly exposed on EC2 into an ALB

It is possible to consolidate multiple hosts into a single ALB by using ALB host-based routing.
This host-based routing might be usable in cases where EC2 instances are directly exposed to the internet. Since the default limit is 100 rules per ALB and 25 certificates, it is worth considering if the number of sites is around that scale.
However, one thing to be aware of is that the blast radius in the event of a failure will increase. The number of sites affected when a single ALB goes down or slows down will increase.

Consider IPv6 architecture

Not right away, but there will come a time when IPv6 becomes widespread in the near future. Preparing for that is not a bad thing.

The services that support IPv6 on AWS are described below. It seems possible to build an internal network with IPv6, but it might still be tough for externally exposed services. There is also the current reality that clients (home routers, ISPs, etc.) do not yet fully support IPv6.
AWS services that support IPv6

Many examples of IPv6 architectural configurations are introduced on the AWS blog. I feel that the shortcut is to customize based on the configurations introduced here.

Dual-stack IPv6 architectures for AWS and hybrid networks
Dual-stack IPv6 architectures for AWS and hybrid networks – Part 2

Summary

I was quite surprised by the new pricing announced this time. A substantial price hike by AWS itself is rare, and I also felt, "Why there?"
IPv4 address exhaustion has been talked about for a long time, but perhaps it has become more realistic with the widespread adoption of public clouds.
For an account that heavily uses EC2, the impact will be significant, and I think there may not be enough time to complete the work by February 2024. It looks like I will have no choice but to work on it bit by bit.

References

describe-instances
[Small tips] Items that change or require reconfiguration after restoring EC2 with AWS Backup
[Update] AWS Backup now supports restoring resources with tags
AWS services that support IPv6

Discussion