ping6.net
Migration

IPv6 in AWS, Azure, and GCP

Enable IPv6 in your cloud infrastructure. Practical configuration guides for AWS, Azure, and Google Cloud Platform.

ping6.netDecember 14, 20248 min read
IPv6AWSAzureGCPcloudKubernetes

Most cloud workloads still run IPv4-only. That's becoming a problem.

TL;DR - Quick Summary

Key Points:

  • Mobile networks are IPv6-first: Forcing translations adds latency for most users
  • IPv4 addresses cost money in the cloud while IPv6 is free
  • Configuration is similar across AWS, Azure, and GCP with dual-stack support
  • Kubernetes clusters can run dual-stack on all major cloud providers

Skip to: AWS Configuration | Azure Configuration | GCP Configuration | Kubernetes

Why Enable IPv6 in the Cloud#

Mobile networks have been IPv6-first for years. When your mobile users hit your service, they're coming from an IPv6 address. Running IPv4-only means forcing a translation somewhere in the path, adding latency and complexity.

Some ISPs have moved to IPv6-only networks with NAT64 for legacy IPv4 services. If you're not reachable via IPv6, you're adding an extra translation hop for these users.

IPv4 addresses cost money now. Cloud providers charge for public IPv4 addresses in most regions. IPv6 addresses are free and abundant.

The architecture is simpler too. No NAT, no port forwarding rules, no address exhaustion to manage. Every instance gets a globally routable address.


AWS IPv6 Configuration#

AWS has solid IPv6 support across most services. Start with your VPC.

VPC Dual-Stack Setup#

Add an IPv6 CIDR block to your existing VPC:

aws ec2 associate-vpc-cidr-block \
  --vpc-id vpc-abc123 \
  --amazon-provided-ipv6-cidr-block

This command requests an IPv6 prefix from AWS's pool. AWS assigns a /56 block automatically.

Associate /64 subnets to each availability zone:

aws ec2 associate-subnet-cidr-block \
  --subnet-id subnet-xyz789 \
  --ipv6-cidr-block 2600:1f13:123:4500::/64

Update your route tables. IPv6 needs its own route to the internet gateway:

aws ec2 create-route \
  --route-table-id rtb-abc123 \
  --destination-ipv6-cidr-block ::/0 \
  --gateway-id igw-xyz789

EC2 IPv6 Addressing#

Existing instances don't automatically get IPv6. Assign addresses manually:

aws ec2 assign-ipv6-addresses \
  --network-interface-id eni-abc123 \
  --ipv6-address-count 1

New instances in dual-stack subnets get IPv6 automatically if you set --ipv6-address-count 1 at launch.

Inside the instance, check that IPv6 is configured. Amazon Linux and Ubuntu handle this automatically via cloud-init, but verify with ip -6 addr show.

Security Groups#

IPv6 traffic uses separate rules. If you have an HTTP rule for 0.0.0.0/0, it won't apply to IPv6. Add ::/0:

aws ec2 authorize-security-group-ingress \
  --group-id sg-abc123 \
  --ip-permissions IpProtocol=tcp,FromPort=443,ToPort=443,Ipv6Ranges='[{CidrIpv6=::/0}]'

Common Security Mistake

Forgetting to add IPv6 rules is the most common issue. Your IPv4 security group rules won't apply to IPv6 traffic, and connections will silently fail.

Load Balancers#

Application and Network Load Balancers support dual-stack. Set ip-address-type to dualstack:

aws elbv2 set-ip-address-type \
  --load-balancer-arn arn:aws:elasticloadbalancing:... \
  --ip-address-type dualstack

The load balancer gets both A and AAAA records automatically.

Route 53 DNS#

Create AAAA records pointing to your IPv6 addresses:

aws route53 change-resource-record-sets \
  --hosted-zone-id Z1234567890ABC \
  --change-batch file://add-aaaa.json

Route 53 supports IPv6 for alias records too, which is useful for load balancers and CloudFront distributions.

Egress-Only Internet Gateway#

If you want instances to initiate outbound IPv6 connections but not accept inbound ones, use an egress-only gateway. This is IPv6's equivalent to NAT, but stateful only—there's no address translation.

aws ec2 create-egress-only-internet-gateway \
  --vpc-id vpc-abc123

Update the route table for private subnets to route IPv6 traffic through it instead of the regular internet gateway.


Azure IPv6 Configuration#

Azure's approach is similar but uses different terminology.

Virtual Network Dual-Stack#

Add an IPv6 address space to your VNet. You can't use Amazon-provided addresses here; Azure assigns from its own ranges.

az network vnet update \
  --resource-group myResourceGroup \
  --name myVNet \
  --address-prefixes "10.0.0.0/16" "fd00:db8::/56"

Azure uses fd00::/8 prefixes for its documentation examples, but you'll get public GUA addresses in production.

Add IPv6 to subnets:

az network vnet subnet update \
  --resource-group myResourceGroup \
  --vnet-name myVNet \
  --name mySubnet \
  --address-prefixes "10.0.1.0/24" "fd00:db8:1::/64"

VM IPv6 Configuration#

VMs need both IPv4 and IPv6 network interface configurations. Create a public IPv6 address:

az network public-ip create \
  --resource-group myResourceGroup \
  --name myPublicIPv6 \
  --version IPv6 \
  --sku Standard

Attach it to the network interface:

az network nic ip-config create \
  --resource-group myResourceGroup \
  --nic-name myNIC \
  --name ipv6config \
  --private-ip-address-version IPv6 \
  --vnet-name myVNet \
  --subnet mySubnet \
  --public-ip-address myPublicIPv6

Load Balancer with IPv6#

Azure Load Balancer needs separate frontend IP configurations for IPv4 and IPv6:

az network lb frontend-ip create \
  --resource-group myResourceGroup \
  --lb-name myLoadBalancer \
  --name LoadBalancerFrontEndIPv6 \
  --public-ip-address myPublicIPv6

Configure backend pools, health probes, and rules for both stacks. The configuration is duplicated, which feels tedious but gives you full control.

DNS Zones#

Add AAAA records to Azure DNS:

az network dns record-set aaaa add-record \
  --resource-group myResourceGroup \
  --zone-name example.com \
  --record-set-name www \
  --ipv6-address 2001:db8::1

GCP IPv6 Configuration#

Google Cloud has been slower to adopt IPv6 than AWS and Azure, but support has improved significantly.

VPC IPv6 Configuration#

GCP VPCs support dual-stack, but IPv6 is still in preview for some features. Enable it on subnet creation:

gcloud compute networks subnets create mysubnet \
  --network=myvpc \
  --region=us-central1 \
  --range=10.0.1.0/24 \
  --stack-type=IPV4_IPV6 \
  --ipv6-access-type=EXTERNAL

GCP assigns a /64 from its 2600:1900::/28 range.

Compute Engine Instances#

Instances in dual-stack subnets get IPv6 automatically. Verify with:

gcloud compute instances describe myinstance \
  --zone=us-central1-a \
  --format="get(networkInterfaces[0].ipv6Address)"

Firewall rules need explicit IPv6 CIDR blocks:

gcloud compute firewall-rules create allow-ipv6-http \
  --network myvpc \
  --allow tcp:80 \
  --source-ranges ::/0

Cloud Load Balancing#

Google's global load balancers support IPv6. Set the IP version when creating a forwarding rule:

gcloud compute forwarding-rules create ipv6-lb-forwarding-rule \
  --load-balancing-scheme=EXTERNAL \
  --ip-protocol=TCP \
  --ports=443 \
  --address=myipv6address \
  --ip-version=IPV6 \
  --target-https-proxy=mytargetproxy \
  --global

Google automatically provisions an anycast IPv6 address for global load balancers.

Cloud DNS#

Create AAAA records:

gcloud dns record-sets create www.example.com \
  --zone=myzone \
  --type=AAAA \
  --ttl=300 \
  --rrdatas=2001:db8::1

Kubernetes and IPv6#

Major managed Kubernetes services now support dual-stack clusters.

Dual-Stack Clusters#

EKS, AKS, and GKE can run dual-stack. Pods get both IPv4 and IPv6 addresses. Enable during cluster creation:

# EKS
eksctl create cluster --name mycluster --ip-family ipv4,ipv6

This creates a cluster where pods receive addresses from both families.

# GKE
gcloud container clusters create mycluster \
  --enable-ip-alias \
  --stack-type=IPV4_IPV6

Services can expose both address families. Set ipFamilyPolicy: RequireDualStack in your Service manifest.

Pod IPv6 Addressing#

Each pod receives addresses from both families. CNI plugins (VPC CNI, Calico, Cilium) handle address assignment. Check pod addresses:

kubectl get pods -o wide

Applications inside pods should bind to :: to listen on both IPv4 and IPv6.

Service IPv6#

Services get ClusterIP addresses from both families. LoadBalancer services provision cloud load balancers with dual-stack frontends automatically if the cluster supports it.

Ingress Controller Compatibility

Not all Ingress controllers support IPv6 yet. Verify your controller's documentation before deploying dual-stack services.


Common Challenges#

Application Support#

Most modern languages and frameworks support IPv6, but older applications might not. Java applications sometimes need -Djava.net.preferIPv6Addresses=true to prefer IPv6.

Databases are tricky. MySQL and PostgreSQL support IPv6, but connection strings and client libraries need proper bracket notation: psql -h [2001:db8::1] -p 5432.

Monitoring Gaps#

Some monitoring tools only collect IPv4 metrics by default. CloudWatch, Azure Monitor, and Cloud Monitoring support IPv6, but custom dashboards might need updates.

Third-party APM tools (Datadog, New Relic) handle dual-stack, but verify your agents are configured correctly.

Cost Considerations#

IPv6 itself is free, but egress costs remain. In fact, some cloud providers charge the same egress rates for IPv6 as IPv4, which doesn't provide cost savings—just architectural benefits.

AWS charges for egress-only internet gateways in some regions. Check the pricing page before deploying.


Testing Your Cloud IPv6#

Don't assume it works. Test from an IPv6-only network.

Disable IPv4 on your local machine temporarily:

# Linux
sudo ip addr del <your-ipv4-address> dev eth0

This forces all connections to use IPv6.

# macOS
sudo ifconfig en0 inet delete

Try accessing your service. If it fails, you've got configuration issues.

Use online tools like ipv6-test.com to verify reachability from different locations.

Check DNS propagation with dig AAAA yourdomain.com from multiple resolvers.

Test load balancer behavior under dual-stack traffic. Some load balancers have subtle routing differences between address families that only appear under load.

Test Cloud Connectivity

Use our Ping Tool to verify your cloud instances are reachable over IPv6.

Additional Resources#