As IPv6 adoption continues to grow, organizations running workloads on AWS increasingly need networking architectures that can support both IPv4 and IPv6 traffic. While AWS provides native IPv6 capabilities, integrating them into an existing enterprise network requires careful planning to maintain security, scalability, and operational consistency.
Recently, one of our clients asked us to enable IPv6 support for their AWS environment. Since the infrastructure was already built on the ITGix AWS Landing Zone, we extended the existing hub-and-spoke networking architecture to support dual-stack (IPv4 and IPv6) connectivity without changing its centralized design principles.
Before introducing IPv6, the environment relied on a centralized hub-and-spoke architecture powered by AWS Transit Gateway, a shared AWS Network Firewall, and a dedicated egress VPC. This approach delivers several advantages, including cost optimization through a single firewall deployment and a fixed set of NAT Gateways for outbound IPv4 traffic. It also centralizes network management in a shared services AWS account, enables resource sharing through AWS Resource Access Manager (AWS RAM), and allows the entire networking stack to be provisioned and managed consistently using Terraform.
The diagram below illustrates the original hub-and-spoke network architecture before IPv6 support was introduced:

Adding IPv6 Support
The ITGix AWS Landing Zone now supports both IPv4-only and dual-stack (IPv4/IPv6) internet egress while preserving the existing centralized hub-and-spoke networking architecture.
At this stage, we do not support native IPv6-only internet egress. The primary reason is that AWS networking services are not designed to provide centralized IPv6 NAT in the same way they do for IPv4. AWS NAT Gateways support NAT64, which enables IPv6 clients to communicate with IPv4 services, but they do not provide native IPv6-to-IPv6 translation. Likewise, Egress-Only Internet Gateways allow outbound IPv6 connectivity but do not perform Network Address Translation (NAT). As a result, maintaining centralized IPv6 internet access with a shared Network Firewall would require custom NAT appliances, significantly increasing operational complexity.
Instead, our implementation focuses on the most common enterprise deployment model: supporting native IPv4 alongside dual-stack IPv4/IPv6 connectivity for workloads and internet destinations that publish both IPv4 and IPv6 endpoints.
Why IPv6 Changes the Networking Model
Unlike IPv4, IPv6 was designed with a virtually unlimited address space, eliminating the need for NAT as the standard deployment model. Rather than relying on private address ranges and address translation, IPv6 workloads typically receive globally routable addresses, with security enforced through stateful firewalls instead of NAT.
This architectural difference has a direct impact on centralized networking designs in AWS.
If a workload requires native IPv6-only internet egress, the centralized hub-and-spoke model can no longer provide internet connectivity in the same way it does for IPv4. Instead, every application VPC must deploy its own Egress-Only Internet Gateway. While these gateways do not incur additional charges, this approach removes the ability to centralize internet egress through a shared Network Firewall. Maintaining equivalent traffic inspection would therefore require deploying an AWS Network Firewall in every VPC, increasing both infrastructure complexity and operational costs.
IPv6 Addressing in AWS
There are also several AWS-specific characteristics of IPv6 addressing worth considering when designing a dual-stack environment:
- AWS-managed Global Unicast Addresses (GUA): By default, AWS allocates IPv6 CIDR blocks from its own Global Unicast Address (GUA) pool. Unlike IPv4, customers cannot freely choose these prefixes unless they use Bring Your Own IP (BYOIP).
- Unique Local Addresses (ULA): AWS recently introduced support for private IPv6 Unique Local Addresses (ULA) through AWS IP Address Manager (IPAM). ULAs are intended for internal communication and specific networking scenarios. They are not a replacement for the traditional IPv4 private-address-plus-NAT model used for internet connectivity.
What we actually support :

Traffic flow at a glance
The diagram below show how egress and ingress traffic flow through the landing zone networking. Egress internet traffic goes through the Transit Gateway to the Inspection VPC (Network Firewall), then to the Egress VPC and out – with NAT64 doing the IPv6→IPv4 translation, and native IPv6-to-internet deliberately dropped. Ingress comes in through the spoke VPC’s own Internet Gateway to a dualstack ALB and routes inside the VPC on the way back.

IPv6 Implementation
The centralized networking implementation of the AWS Landing Zone automatically assigns CIDR blocks for dualstack (IPv4 + IPv6) support to networking components and route tables. It also handles the routing that this dualstack setup requires at every layer: spoke VPCs, the Transit Gateway, the Network Firewall, the Egress VPC, and the full route back to the applications.
VPCs
Each VPC gets an IPv6 CIDR. It is selected and provided by Amazon automatically when IPv6 support is enabled – we do not pass IPv6 CIDR blocks the way we do for IPv4; AWS generates them.

Subnets
Each subnet also gets an IPv6 CIDR.

Subnet route tables
Subnet route tables include routes for both IPv4 and IPv6.

Network Firewall
The firewall is deployed with a dualstack IP configuration.

The HOME_NET variable is also extended with both the IPv4 supernet CIDR (10.0.0.0/8, which covers all VPCs) and the individual IPv6 CIDRs. The IPv6 CIDRs have to be listed individually because AWS assigns each VPC a distinct, non-contiguous, globally unique IPv6 block rather than carving them from a single private range. So unlike IPv4 – where 10.0.0.0/8 covers every VPC – there is no single IPv6 supernet that covers all VPCs without also including address space we don’t own.

Additionally, to support IPv6 we need equivalent firewall rules for both address families. For example, allowing traffic to the AWS IMDS (instance metadata service) for both IPv4 and IPv6:
# Allow access to IMDS for instance credentials #
pass tcp $HOME_NET any -> 169.254.169.254 80 (msg:"Allow IMDS (instance metadata)"; sid:10000; rev:1;)
# IPv6 IMDS endpoint (link-local, consistent across all VPCs)
pass tcp $HOME_NET any -> fd00:ec2::254 80 (msg:"Allow IMDS IPv6 (instance metadata)"; sid:10009; rev:1;)
Transit Gateway routing
Route traffic from any VPC to be inspected by the Network Firewall (the example shows the dev VPC → inspection VPC; the same approach applies to staging and prod).

Route the traffic that has been inspected by the Network Firewall on to the Egress VPC, and the responses from the Egress VPC back to the spoke VPC the request originated from – handling both IPv4-only and dualstack IPv4/IPv6 traffic.

Egress VPC (traffic to the internet) – dualstack IPv4/IPv6
The route table in the Egress VPC directs traffic to the internet and directs the responses from the internet back to the Transit Gateway, handling both the IPv4-only and dualstack IPv4/IPv6 cases.

NAT64 and DNS64
One of the key components of our dual-stack implementation is support for NAT64 and DNS64, which enable workloads running in dual-stack subnets to communicate with IPv4-only internet services.
The route 64:ff9b::/96 → NAT Gateway (shown in the previous diagram) exists specifically for this purpose.
Since IPv4 and IPv6 use different protocol stacks, an IPv6 client cannot communicate directly with an IPv4-only endpoint. While IPv6 adoption continues to grow, many public APIs, software repositories, and third-party services are still available only over IPv4. AWS addresses this interoperability challenge by combining DNS64, provided by the Amazon VPC DNS Resolver, with NAT64, implemented by the AWS NAT Gateway.
How DNS64 Works
When an application performs a DNS lookup, the Amazon VPC DNS Resolver follows one of two paths:
- If the destination publishes an AAAA record, the resolver returns the native IPv6 address.
- If only an A record exists, the resolver generates a synthetic IPv6 address by embedding the IPv4 address into the well-known 64:ff9b::/96 prefix.
For example, an IPv4 address of 93.184.216.34 is translated into:
64:ff9b::5db8:d822
where 5db8 is the hexadecimal representation of 93.184.216.34.
From the application’s perspective, it is communicating with a standard IPv6 address and remains completely unaware that translation will occur later in the networking stack.
How NAT64 Works
When traffic reaches the AWS NAT Gateway, NAT64 performs the protocol translation:
- The NAT Gateway recognizes the 64:ff9b::/96 prefix.
- It extracts the embedded IPv4 destination address.
- It performs source NAT using the NAT Gateway’s public IPv4 address.
- The packet is forwarded to the IPv4 internet through the Internet Gateway.
- Return traffic is tracked using connection state, translated back into IPv6, and delivered to the originating workload.
This process is completely transparent to the application, allowing IPv6-enabled workloads to access IPv4-only services without requiring any application changes.
Routing Behavior
Our implementation intentionally restricts native IPv6 internet access.
The only IPv6 egress route configured is:
64:ff9b::/96 → NAT Gateway (NAT64)
There is no ::/0 route pointing to an Egress-Only Internet Gateway or Internet Gateway. As a result, native IPv6 internet traffic is blocked at the VPC router, while IPv6-to-IPv4 communication continues to function through DNS64 and NAT64.
Testing Egress Connectivity in the Centralized Network
To validate the implementation, we launched an Amazon EC2 instance in a dual-stack subnet and verified outbound connectivity using AWS Systems Manager (SSM).
Because the subnet is configured for dual-stack networking, enabling automatic IPv6 address assignment results in the instance receiving both an IPv4 and an IPv6 address. AWS does not provision IPv6-only instances within a dual-stack subnet—IPv6-only networking requires an IPv6-only subnet.
Deploy a Test EC2 Instance
Create an Amazon EC2 instance in a dual-stack subnet and:
- Apply the mandatory resource tags required by the Landing Zone.
- Enable AWS Systems Manager (SSM) connectivity for remote access.
- Configure the instance to automatically assign an IPv6 address during launch.

DNS64 configuration.

Make sure the Security Group assigned to the instance has an IPv6 outbound rule as well.

Make sure the created instance has an IPv6 address.

Access the instance via SSM.
- If SSM agent is not connected make sure there are outbound rules in the SG that allow at least port 443
- Setup a VPC endpoint for ssm and ssmmessages (make sure it includes IPv6 support so that we test this part as well)

- Those endpoints have to be created in the shared-services account as it is not allowed to create VPC endpoints on a shared VPC (so we cannot create them directly in the dev account).

- Make sure the Security Group of the VPC endpoint allows inbound requests from the Dev VPC on both IPv4 and IPv6 addresses

Test IPv6 connectivity
Test that the DNS resolver synthesizes destinations that have only IPv4 addresses using DNS64 to 64:ff9b:: (checkip.amazonaws.com is currently with an IPv4 only address).
[root@ip-10-3-1-74 ~]# dig +short AAAA checkip.amazonaws.com
checkip.check-ip.aws.a2z.com.
64:ff9b::3ff:146d
64:ff9b::22f1:8ae0
64:ff9b::6c83:f08a
64:ff9b::6c84:4594
64:ff9b::3f21:dea9
64:ff9b::3411:3ca
64:ff9b::3431:50c4
64:ff9b::36ab:255b
The same test but on a domain that does have an IPv6 address as well (we successfully get its IPv6 address without DNS64 having to synthesize)
[root@ip-10-3-1-74 ~]# dig +short AAAA www.google.com
2001:4860:4826:7700::
2001:4860:482a:7700::
2001:4860:4827:7700::
2001:4860:4829:7700::
2001:4860:482c:7700::
2001:4860:482b:7700::
2001:4860:482d:7700::
2001:4860:4828:7700::
NAT64 – full IPv6->IPv4 round trip through inspection VPC (and firewall) + egress NAT
[root@ip-10-3-1-74 ~]# curl -6 -v --connect-timeout 8 https://checkip.amazonaws.com
* Host checkip.amazonaws.com:443 was resolved.
* IPv6: 64:ff9b::3411:3ca, 64:ff9b::3431:50c4, 64:ff9b::6c84:4594, 64:ff9b::3ff:146d, 64:ff9b::22f1:8ae0, 64:ff9b::36ab:255b, 64:ff9b::6c83:f08a, 64:ff9b::3f21:dea9
* IPv4: (none)
* Trying [64:ff9b::3411:3ca]:443...
* ALPN: curl offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* SSL Trust Anchors:
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256 / x25519 / RSASSA-PSS
* ALPN: server accepted h2
* Server certificate:
* subject: CN=checkip.amazonaws.com
* start date: Nov 3 00:00:00 2025 GMT
* expire date: Dec 2 23:59:59 2026 GMT
* issuer: C=US; O=Amazon; CN=Amazon RSA 2048 M01
* Certificate level 0: Public key type RSA (2048/112 Bits/secBits), signed using sha256WithRSAEncryption
* Certificate level 1: Public key type RSA (2048/112 Bits/secBits), signed using sha256WithRSAEncryption
* Certificate level 2: Public key type RSA (2048/112 Bits/secBits), signed using sha256WithRSAEncryption
* subjectAltName: "checkip.amazonaws.com" matches cert's "checkip.amazonaws.com"
* SSL certificate verified via OpenSSL.
* Established connection to checkip.amazonaws.com (64:ff9b::3411:3ca port 443) from 2a05:d014:ad1:7401:c49d:5ba9:619c:68f5 port 59300
* using HTTP/2
* [HTTP/2] [1] OPENED stream for https://checkip.amazonaws.com/
* [HTTP/2] [1] [:method: GET]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: checkip.amazonaws.com]
* [HTTP/2] [1] [:path: /]
* [HTTP/2] [1] [user-agent: curl/8.17.0]
* [HTTP/2] [1] [accept: */*]
> GET / HTTP/2
> Host: checkip.amazonaws.com
> User-Agent: curl/8.17.0
> Accept: */*
>
* Request completely sent off
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
< HTTP/2 200
< date: Mon, 03 Aug 2026 13:14:44 GMT
< content-type: text/plain;charset=UTF-8
< content-length: 13
< server: nginx
< vary: Origin
< vary: Access-Control-Request-Method
< vary: Access-Control-Request-Headers
<
3.73.200.135
* Connection #0 to host checkip.amazonaws.com:443 left intact
We see that the response has returned “3.73.200.135“ which is the IPv4 address of one of the NAT gateways. Essentially proving that even though we sent an IPv6 request, the destination received our request from the IPv4 IP address of the NAT Gateway and than returned the response back on the same path. NAT64 took care of translating back from IPv4 to IPv6 and back into the machine that the request originated from.
Native IPv6 to the internet – traffic is dropped (this is expected, since we support IPv4-only + dualstack IPv6/IPv4, but we do not support IPv6-only destinations)
[root@ip-10-3-1-74 ~]# curl -6 -v --connect-timeout 5 https://www.google.com
* Host www.google.com:443 was resolved.
* IPv6: 2001:4860:4828:7700::, 2001:4860:482d:7700::, 2001:4860:482b:7700::, 2001:4860:482c:7700::, 2001:4860:4829:7700::, 2001:4860:4827:7700::, 2001:4860:482a:7700::, 2001:4860:4826:7700::
* IPv4: (none)
* Trying [2001:4860:4828:7700::]:443...
* Trying [2001:4860:482d:7700::]:443...
* Trying [2001:4860:482b:7700::]:443...
* Trying [2001:4860:482c:7700::]:443...
* Trying [2001:4860:4829:7700::]:443...
* Trying [2001:4860:4827:7700::]:443...
* Trying [2001:4860:482a:7700::]:443...
* Trying [2001:4860:4826:7700::]:443...
* Connection timed out after 5001 milliseconds
* closing connection #0
curl: (28) Connection timed out after 5001 milliseconds
(we get a timeout because the EC2 instance still gets a default ::/0 route via Router Advertisement, so it sends a TCP SYN request, but then gets dropped by the dev VPC router because the subnet route table has no route for ::/0)
East-west traffic (VPC-to-VPC over Transit Gateway)
VPC to VPC traffic fully supports native IPv6. Unlike internet egress, there is no NAT64 or address translation involved – workloads talk to each other using their real IPv6 GUAs, and the Transit Gateway routes the traffic between VPCs using the per-VPC /56 routes present in the spoke route tables (<remote VPC /56> → TGW).
This requires Isolation mode to be disabled so that VPCs have routes to each other, by default VPC to VPC traffic is disabled at the Transit Gateway level in order to provide isolation between Dev, Staging, and Production environments, unless it is explicitly required for them to be able to talk to each other. Isolation mode works by dropping traffic destined to other VPCs

Isolation mode can be disabled with the feature flag:
disable_environment_isolation = false // set to true to disable isolation mode
Test connectivity between VPCs
From an EC2 instance on the Dev VPC in a private subnet, reaching an nginx test server running in the staging VPC – native IPv6, no NAT64.
[root@ip-10-3-1-74 ~]# curl -6 -v http://[2a05:d014:1a5b:c800:5b1e:2a7c:9f43:1d2e]/
* Trying [2a05:d014:1a5b:c800:5b1e:2a7c:9f43:1d2e]:80...
* Connected to 2a05:d014:1a5b:c800:5b1e:2a7c:9f43:1d2e (2a05:d014:1a5b:c800:5b1e:2a7c:9f43:1d2e) port 80
* using HTTP/1.x
> GET / HTTP/1.1
> Host: [2a05:d014:1a5b:c800:5b1e:2a7c:9f43:1d2e]
> User-Agent: curl/8.17.0
> Accept: */*
>
* Request completely sent off
< HTTP/1.1 200 OK
< Server: nginx/1.28.0
< Date: Wed, 05 Aug 2026 08:11:47 GMT
< Content-Type: text/plain
< Content-Length: 84
< Connection: keep-alive
<
Hello from staging-vpc (ip-10-4-1-88 / 2a05:d014:1a5b:c800:5b1e:2a7c:9f43:1d2e)
* Connection #0 to host 2a05:d014:1a5b:c800:5b1e:2a7c:9f43:1d2e left intact
Ingress Connectivity (Internet to Workloads)
Unlike internet egress, ingress connectivity supports all deployment models:
- IPv4-only
- Dual-stack (IPv4/IPv6)
- IPv6-only
Supporting IPv6 ingress requires minimal changes to the standard ITGix AWS Landing Zone architecture. The traffic flow remains:
Internet Gateway → Application Load Balancer (public subnet) → Workload (private subnet)
The key reason this works is that the Application Load Balancer (ALB) terminates the client connection and establishes a separate connection to the backend target. As a result, the client-facing connection and the workload connection are independent.
This means an ALB configured for dual-stack or IPv6 can accept IPv6 client connections even when the backend workload itself has only an IPv4 address. The ALB handles the protocol translation transparently, allowing existing applications to support IPv6 ingress without requiring IPv6 addresses on the compute resources.
Response traffic also follows the standard VPC routing model. Since both the ALB and the workload reside within the same VPC, return traffic uses the local VPC route rather than traversing the centralized networking infrastructure. Consequently, ingress traffic and the corresponding responses never pass through the centralized egress path.
10.3.0.0/16 -> local
2a05:d014:ad1:7400::/56 -> local
ALBs have to be configured in dualstack mode

The ALB gets created with both A and AAAA records behind its DNS name
IPv4 (A)
dig test123-612930072.eu-central-1.elb.amazonaws.com A
; <<>> DiG 9.20.26 <<>> test123-612930072.eu-central-1.elb.amazonaws.com A
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 50976
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;test123-612930072.eu-central-1.elb.amazonaws.com. IN A
;; ANSWER SECTION:
test123-612930072.eu-central-1.elb.amazonaws.com. 57 IN A 52.59.38.209
;; Query time: 7 msec
;; SERVER: 10.18.12.1#53(10.18.12.1) (UDP)
;; WHEN: Tue Aug 04 15:14:20 EEST 2026
;; MSG SIZE rcvd: 93
IPv6 (AAAA)
dig test123-612930072.eu-central-1.elb.amazonaws.com AAAA
; <<>> DiG 9.20.26 <<>> test123-612930072.eu-central-1.elb.amazonaws.com AAAA
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 60875
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;test123-612930072.eu-central-1.elb.amazonaws.com. IN AAAA
;; ANSWER SECTION:
test123-612930072.eu-central-1.elb.amazonaws.com. 60 IN AAAA 2a05:d014:ad1:7405:6957:a7d8:5190:f0be
;; Query time: 37 msec
;; SERVER: 10.18.12.1#53(10.18.12.1) (UDP)
;; WHEN: Tue Aug 04 15:15:17 EEST 2026
;; MSG SIZE rcvd: 105
Security Groups of the ALB have to also include IPv6 traffic
Inbound

Outbound

DNS records for our applications have to include both IPv4 (A) and IPv6 (AAAA) records

IPv4
dig testipv6.dev.lz.itgix.eu A
; <<>> DiG 9.20.26 <<>> testipv6.dev.lz.itgix.eu A
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 57431
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;testipv6.dev.lz.itgix.eu. IN A
;; ANSWER SECTION:
testipv6.dev.lz.itgix.eu. 60 IN A 52.59.38.209
;; Query time: 255 msec
;; SERVER: 10.18.12.1#53(10.18.12.1) (UDP)
;; WHEN: Tue Aug 04 15:15:40 EEST 2026
;; MSG SIZE rcvd: 69
IPv6
dig testipv6.dev.lz.itgix.eu AAAA
; <<>> DiG 9.20.26 <<>> testipv6.dev.lz.itgix.eu AAAA
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 55190
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;testipv6.dev.lz.itgix.eu. IN AAAA
;; ANSWER SECTION:
testipv6.dev.lz.itgix.eu. 60 IN AAAA 2a05:d014:ad1:7405:6957:a7d8:5190:f0be
;; Query time: 58 msec
;; SERVER: 10.18.12.1#53(10.18.12.1) (UDP)
;; WHEN: Tue Aug 04 15:15:43 EEST 2026
;; MSG SIZE rcvd: 81
Test IPv6 ingress connectivity from the internet (curl -6 forces IPv6 so we hit the ALB’s AAAA (dualstack ALB in a public subnet)
$ curl -6 -v https://testipv6.dev.lz.itgix.eu/
* Trying [2a05:d014:ad1:7405:6957:a7d8:5190:f0be]:443...
* Connected to testipv6.dev.lz.itgix.eu (2a05:d014:ad1:7405:6957:a7d8:5190:f0be) port 443
* ALPN: curl offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256 / x25519 / RSASSA-PSS
* ALPN: server accepted h2
* Server certificate:
* subject: CN=testipv6.dev.lz.itgix.eu
* start date: Aug 1 00:00:00 2026 GMT
* expire date: Aug 31 23:59:59 2027 GMT
* subjectAltName: host "testipv6.dev.lz.itgix.eu" matched cert's "testipv6.dev.lz.itgix.eu"
* issuer: C=US; O=Amazon; CN=Amazon RSA 2048 M03
* SSL certificate verify ok.
* Established connection to testipv6.dev.lz.itgix.eu (2a05:d014:ad1:7405:6957:a7d8:5190:f0be) port 443
* using HTTP/2
* [HTTP/2] [1] OPENED stream for https://testipv6.dev.lz.itgix.eu/
* [HTTP/2] [1] [:method: GET]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: testipv6.dev.lz.itgix.eu]
* [HTTP/2] [1] [:path: /]
* [HTTP/2] [1] [user-agent: curl/8.17.0]
* [HTTP/2] [1] [accept: */*]
> GET / HTTP/2
> Host: testipv6.dev.lz.itgix.eu
> User-Agent: curl/8.17.0
> Accept: */*
>
* Request completely sent off
< HTTP/2 200
< date: Wed, 05 Aug 2026 08:18:03 GMT
< content-type: text/plain
< content-length: 64
< server: nginx/1.28.0
<
Hello over native IPv6 via dualstack ALB (backend ip-10-3-2-57)
* Connection #0 to host testipv6.dev.lz.itgix.eu left intact
Summary
The ITGix AWS Landing Zone now provides end-to-end IPv6 support, enabling IPv6 ingress from the internet, east-west communication between VPCs, and dual-stack internet egress, while preserving the benefits of our centralized hub-and-spoke networking architecture. Organizations can continue to leverage a shared AWS Network Firewall, centralized AWS Transit Gateway, and a common set of NAT Gateways without redesigning their existing networking model.
The only limitation is native IPv6-only internet egress. AWS currently does not provide a mechanism for centralized source NAT for native IPv6 traffic, and the Amazon-assigned IPv6 CIDR block for each VPC remains tied to that VPC. As a result, centralized native IPv6 internet egress is not currently practical without introducing additional infrastructure.
In practice, this limitation has little impact for most environments. Workloads can still access both IPv4-only and dual-stack internet services through centralized, firewall-inspected DNS64/NAT64. For workloads that require native IPv6 internet connectivity, a per-VPC deployment using an Egress-Only Internet Gateway remains a supported option.
Perhaps the biggest advantage is that the entire solution is fully automated using Terraform. Dual-stack VPCs, IPv6 CIDR allocation, subnet configuration, AWS Transit Gateway routing, AWS Network Firewall policies, and the DNS64/NAT64 egress path are all managed as infrastructure as code. Enabling IPv6 for a new AWS environment therefore becomes a simple configuration change rather than a networking redesign.

