Get Hands-on with Amazon EKS - Workshop Event Series
Whether you're taking your first steps with Kubernetes or you're an experienced practitioner looking to sharpen your skills, our Amazon EKS workshop series delivers practical, real-world experience that moves you forward. Learn directly from AWS solutions architects and EKS specialists through hands-on sessions designed to build your confidence with Kubernetes. Register now and start building with Amazon EKS!
Adopting IPv6 to your existing Amazon VPC
As IPv6 adoption grows across AWS customers, ensuring customer applications can be accessed over both IPv4 and IPv6 is becoming essential. By adopting IPv6 and it's features to an existing VPC, it allows customers to deliver business outcomes by building highly scalable architectures on IPv6 while maintaining backwards compatibility with your existing IPv4 workloads.
Introduction
In this post we explain how you can adopt IPv6 to your existing Virtual Private Cloud (VPC) providing flexible connectivity for customers to connect to their applications over the internet. We outline the steps to configure your VPC to operate in both IPv4 and IPv6 mode, enable dual-stack support for AWS services and ensure seamless access to your resources using either IPv4 or IPv6 addressing.
Prerequisites
We assume you are familiar with fundamental networking constructs on AWS such as, Amazon VPC, as well as its components like Internet Gateways, Egress-only Internet Gateways, Security Groups, Network ACLs, Elastic Network Interfaces, Elastic IP addresses and Network Load Balancers, in addition to how they work with IPv6. Refer to the IPv6 on AWS whitepaper for more detailed information on all of these constructs and how they support IPv6.
Baseline Architecture
Our initial setup, depicted in the following figure, uses one AWS-assigned IPv4 CIDR block in our VPC: with a public subnet routable to the internet. Individual resources within the public subnet such as EC2 instances and Network Load Balancer have Elastic IP attached to their elastic network interfaces through which they communicate (ingress and egress) with users and resources within the VPC and over the internet.
Figure 1: Initial VPC setup with IPv4-Only CIDR block
Now, let’s take a look at IPv6 adoption steps for your VPC and how to configure IPv6 using either AWS Command Line Interface (AWS CLI) or the AWS Management Console.
Step 1: Add an IPv6 CIDR Block to your VPC
Before your Amazon VPC could support IPv6 traffic, it needs an IPv6 address range to be assigned. AWS by default provides a /56 CIDR block space when you add an Amazon-provided IPv6 CIDR block to your VPC. This block is now reserved for your account in the region of your choice and can be subdivided into 256 /64 subnets. It is worth noting that,
- You cannot modify or shrink this block once assigned.
- You can only have one Amazon-provided IPv6 block per VPC.
Figure 2: Associating a IPv6 CIDR block to an existing Amazon VPC
Configuration using AWS Management Console:
Now that your VPC has been allocated an IPv6 CIDR block, the next step is to assign a /64 IPv6 block as part of your existing public subnet. This step enables the subnet to host IPv6 capable resources such as Amazon EC2, Elastic Load Balancing, and containers.
Configuration using AWS CLI:
Before we begin, ensure the AWS CLI is installed, up-to date and configured with appropriate credentials and region. Use the describe-vpcs command to make sure you have the right VPC ID of your existing VPC you’d like to enable for IPv6.
aws ec2 describe-vpcs --query "VPC[*].{VPC:VpcId,CIDR:CidrBlock}" --output table
Use associate-vpc-cidr-block command to allocate a /56 IPv6 CIDR block to your VPC from Amazon’s global address pool.
aws ec2 associate-vpc-cidr-block \
--vpc-id vpc0ab7************* \
--amazon-provided-ipv6-cidr-block
Use the following command to verify successful /56 IPv6 CIDR block association to your existing VPC
aws ec2 describe-vpcs \
--vpc-id vpc-0254************* \
--query "Vpcs[].Ipv6CidrBlockAssociationSet" \
--output table
After verifying IPv6 CIDR block allocation to your VPC, use associate-subnet-cidr-block to assign a /64 IPv6 block to your existing public subnet. This step establishes the groundwork for deploying dual-stack (IPv4 + IPv6) applications/workloads.
aws ec2 associate-subnet-cidr-block \
--subnet-id subnet-0d7e************* \
--ipv6-cidr-block 2600:1f18:26f7:c100::/64
Use the following command to verify successful /64 IPv6 CIDR block creation for your existing subnet.
aws ec2 describe-subnets \
--subnet-id subnet-0d7e************* \
--query "Subnets[*].{SubnetId:SubnetId,Ipv6CidrBlockAssociationSet:Ipv6CidrBlockAssociationSet}" \
--output table
Step 2: Configure IPv6 default route in the route table
Once your public subnet has an IPv6 CIDR block, the resources that get assigned an IPv6 address requires the appropriate routing configuration to send outbound traffic to the internet. In most cases, this means adding a route entry to your route table that sends all IPv6 traffic (::/0) to the Internet Gateway allowing public IPv6 connectivity.
Figure 3: Configuring IPv6 default route in the route table
Configuration using AWS Management Console:
Configuration using AWS CLI:
While using the CLI, the first step is to identify the route table id associated with your public subnet to which you assigned a /64 IPv6 CIDR block.
aws ec2 describe-route-tables \
--filters "Name=association.subnet-id,Values=subnet-0d7e************* \
--query "RouteTables[*].{RouteTableId:RouteTableId,AssociationSet:Associations[*].AssociationId" \
--output table
If there are no explicit subnet associations to a route table, the CLI output will return “None”. This means, the subnet uses the main route table of the VPC by default. You can use associate-route-table command if you’d like to explicitly make an association.
aws ec2 associate-route-table \
--subnet-id subnet-0d7e************* \
--route-table-id rtb-04ca96b5af7728cc3
As a rule of thumb, always double check which route table is associated with your subnet before making modifications especially in scenarios where you have multiple custom route tables in your VPC and accidental IPv6 routing updates could expose your private subnets to public IPv6 traffic unintended. As an additional layer of protection, always consider using security groups and network ACLs (NACLs).
Step 3: Change Load Balancer to Dual-stack and update Security Groups
AWS supports dual-stack Network Load Balancers (NLB), allowing you to expose your applications to users regardless of the IP version they use. In the subsequent steps, we will review:
- How to enable dual-stack mode for your NLBs
- Verifying your NLB FQDN supports both IPv4 (A) and IPv6 (AAAA) DNS records.
- Updating security groups to allow only desired traffic inbound. For this example, we’re going to allow all IPv6 traffic.
Figure 4: Update load balancer to support dual-stack connectivity
Configuration using AWS Management Console:
- Enabling dual-stack mode on the load balancer
- Verifying DNS resolution for both IPv4 and IPv6 address type using nslookup or dig commands.
$ dig blog-nlb-8a1b24ce93c9073c.elb.us-east-1.amazonaws.com A +short
100.27.76.247
$ dig blog-nlb-8a1b24ce93c9073c.elb.us-east-1.amazonaws.com AAAA +short
2600:1f18:26f7:c100:e2b2:f59b:a746:d3aa
- Update security groups and add IPv6 rules to allow inbound access to your load balancer. (Note: The example shared here is in the assumption that your NLBs are associated with security groups during creation. You cannot associate a security group to an existing NLB without security groups. You would have to perform a blue/green deployment to switch to a new NLB to support security groups.)
Configuration using AWS CLI:
- Enabling dual-stack mode on the load balancer
Use describe-load-balancers command to verify the IPAddressType of your load balancer.
aws elbv2 describe-load-balancers \
--names blog-nlb \
--query "LoadBalancers[*].{Name:LoadBalancerName, IPType:IpAddressType}" \
--output table
Once verified the IPAddressType is “ipv4”, modify the load balancer IP type to “dualstack” using set-ip-address-type command.
aws elbv2 set-ip-address-type \
--load-balancer-arn arn:aws:elasticloadbalancing:us-east-1:9187********:loadbalancer/net/blog-nlb/8a1b24ce93c9073c \
--ip-address-type dualstack
- Update security groups and add IPv6 rules to allow inbound access to your load balancer.
After modifying your NLB to “dualstack” ip address type, make sure your NLB security group is updated to allow inbound IPv6 traffic. Use describe-load-balancers command to verify the attached security group to your load balancer
aws elbv2 describe-load-balancers \
--names blog-nlb \
--query "LoadBalancers[*].SecurityGroups" \
--output table
Use authorize-security-groups-ingress command to add an IPv6 rule to accept all traffic.
aws ec2 authorize-security-group-ingress \
--group-id sg-02a0b8ab94e5ea977 \
--ip-permissions 'IpProtocol=all,Ipv6Ranges=[{CidrIpv6=::/0}]'
[Optional] After adding the IPv6 rule, verify the inbound rule was successfully added by looking for “Ipv6Ranges”.
aws ec2 describe-security-groups \
--group-ids sg-02a0b8ab94e5ea977 \
--query "SecurityGroups[*].IpPermissions" \
--output table
Step 4: User connectivity patterns for dual-stack enabled Load Balancer
Now that your VPC, subnets and NLB are all IPv6-enabled, let us look at the following user connectivity patterns to your dual-stack NLB.
• Setup 1: IPv4 users → dual-stack NLB → IPv4 EC2 targets
• Setup 2: IPv6 users → dual-stack NLB → IPv4 EC2 targets
Figure 5: Connectivity patterns for your dual-stack Load Balancer
Configuration using AWS Management Console:
• Setup 1: IPv4 users → dual-stack NLB → IPv4 EC2 targets
• Setup 2: IPv6 users → dual-stack NLB → IPv4 EC2 targets
For both of these setups, we will create a target group with IPv4-only EC2 instances as targets. Once created, associate the target group to the existing network load balancer “blog-nlb”.
Configuration using AWS CLI:
- Create a target group using create-target-group command with ip-address-type as “ipv4”
aws elbv2 create-target-group \
--name blog-target-group \
--protocol TCP \
--port 80 \
--vpc-id vpc0ab7************* \
--target-type instance \
--ip-address-type ipv4
- Given that we already have the NLB created, let us now modify the listener using modify-listener command to forward TCP traffic to newly created target group “blog-target-group”
aws elbv2 modify-listener \
--listener-arn arn:aws:elasticloadbalancing:us-east-1:9187********:listener/net/blog-nlb/8a1b24ce93c9073c/342e570eadd6c811 \
--default-actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:us-east-1:9187********:targetgroup/blog-target-group/8bcdf0f7648f378e
- Verify your listener has been successfully updated and forward traffic to “blog-target-group” using describe-listeners command.
aws elbv2 describe-listeners \
--load-balancer-arn arn:aws:elasticloadbalancing:us-east-1:9187********:loadbalancer/net/blog-nlb/8a1b24ce93c9073c \
--query "Listeners[*].DefaultActions[*].TargetGroupArn" \
--output table
Verifications
-
Test the connectivity to the dual-stack NLB with an IPv4 user:
curl -4 http://blog-nlb-8a1b24ce93c9073c.elb.us-east-1.amazonaws.com
| <html><body><h1>It works!</h1></body></html> -
Test the connectivity to the dual-stack NLB with an IPv6 user:
curl -6 http://blog-nlb-8a1b24ce93c9073c.elb.us-east-1.amazonaws.com
| <html><body><h1>It works!</h1></body></html>
Step 5: Dual-stack EC2 for end-to-end IPv6 connectivity
To achieve end-to-ed IPv6 connectivity for the below scenario, the EC2 instances behind the NLB requires IPv6 address assignment to its primary elastic network interface (ENI). This ensures traffic arriving via the dual-stack NLB is routed all the way to your instance over IPv6.
(Note: The IPv6 address assigned to the ENI must be its primary IPv6 address. AWS does not support making IPv6 a secondary address on an ENI when you require it to respond to incoming traffic through a dual-stack NLB.)
Figure 6: Add IPv6 address to EC2 instances
Configuration using AWS Management Console:
• Setup: IPv6 users → dual-stack NLB → IPv6 EC2 targets
For this setup, we will first assign an IPv6 address to the primary elastic network interface of the EC2 instance. Once this step is completed, we will then create a new target group with IPv6-only EC2 instances as targets. After target group creation, associate the new target group to the existing network load balancer “blog-nlb”. Similar to the NLB, make sure to update your EC2 instance security groups to allow only desired traffic inbound. For this example, we’re going to allow all IPv6 traffic.
Configuration using AWS CLI:
- Assign a primary IPv6 address using assign-ipv6-address command.
aws ec2 assign-ipv6-addresses \
--network-interface-id eni-0f7c7bcfe71077e50 \
--ipv6-address-count 1
Alternatively, you can also manually specify an IPv6 address from your /64 subnet CIDR block to be the primary address of your network interface.
2. Verify IPv6 Assignment using describe-network-interfaces command.
aws ec2 describe-network-interfaces \
--network-interface-ids eni-0f7c7bcfe71077e50 \
--query 'NetworkInterfaces[*].Ipv6Addresses' \
--output table
- Create a target group using create-target-group command with ip-address-type as “ipv6”
aws elbv2 create-target-group \
--name blog-target-group \
--protocol TCP \
--port 80 \
--vpc-id vpc0ab7************* \
--target-type instance \
--ip-address-type dualstack
- Given that we already have the NLB created, let us now modify the listener using modify-listener command to forward TCP traffic to newly created target group “blog-target-group-IPv6”
aws elbv2 modify-listener \
--listener-arn arn:aws:elasticloadbalancing:us-east-1:9187********:listener/net/blog-nlb/8a1b24ce93c9073c/342e570eadd6c811 \
--default-actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:us-east-1:9187********:targetgroup/blog-target-group-IPv6/e0b559b642c415b9
- Verify your listener has been successfully updated and forward traffic to “blog-target-group-IPv6” using describe-listeners command.
aws elbv2 describe-listeners \
--load-balancer-arn arn:aws:elasticloadbalancing:us-east-1:9187********:loadbalancer/net/blog-nlb/8a1b24ce93c9073c \
--query "Listeners[*].DefaultActions[*].TargetGroupArn" \
--output table
Verifications
-
Test the connectivity to the dual-stack NLB with an IPv6 user:
curl -6 http://blog-nlb-8a1b24ce93c9073c.elb.us-east-1.amazonaws.com
| <html><body><h1>It works!</h1></body></html> -
Test and verify telnet to IPv6 address of your EC2 instance on port 22
telnet 2600:1f18:26f7:c100:e6cb:219f:c4d5:621c 22
| Trying 2600:1f18:26f7:c100:e6cb:219f:c4d5:621c...
| Connected to 2600:1f18:26f7:c100:e6cb:219f:c4d5:621c.
| Escape character is '^]'.
| SSH-2.0-OpenSSH_8.7
Conclusion
This blog post helps you get started with your IPv6 cloud adoption journey. We’ve walked through the complete process of IPv6 adoption on an Amazon VPC: from assigning CIDR blocks to your VPC and subnets, to configuring a dual-stack Network Load Balancer, and finally ensuring your EC2 instances can communicate over IPv6 establishing end-to-end IPv6 connectivity for your AWS workloads. If you have questions about this post, then start a new thread on the Amazon Networking and Content Delivery Forum, AWS re:Post or contact AWS Support.
About the authors
Aishwarya Subramaniam
Aishwarya Subramaniam is a Sr. Solutions Architect at AWS. She works with SMB customers and AWS Partner Network consultants to accelerate customers’ business outcomes by providing expertise in analytics and other AWS services.
Sushil Ranganathan
Sushil Ranganathan is a Senior Technical Account Manager at Amazon Web Services. He has over 12 years of industry experience and is passionate about helping customers in the strategic industries build and operationalize enterprise-scale solutions in the AWS cloud. Outside work, he loves photography, music and traveling to new places and learning about their culture.
- Language
- English
Super clear and practical walkthrough. I like how it breaks IPv6 adoption into incremental steps without disrupting existing IPv4 workloads, especially the dual-stack NLB patterns and CLI examples. This makes IPv6 feel much less intimidating to adopt in real production VPCs.
I'm glad you find it helpful, Ashish.
Relevant content
- asked 4 years ago
AWS OFFICIALUpdated 3 years ago
AWS OFFICIALUpdated 2 years ago