Multicloud IPv6 with Terraform — Azure

Frans van Rooyen
ITNEXT
Published in
5 min readJan 21, 2021

--

I recently had the opportunity to work on a POC where I had to test IPv6 functionality AWS and Azure using Terraform. Very early on in this journey I quickly realized that documentation to accomplish this task is sparse from both cloud providers as well as HashiCorp. Also there are a number of nuances between the clouds that are not well known except having to grind through, test and learn from your mistakes. I am therefore publishing my work to provide some documentation and guidance on this process. This edition is for Azure, AWS and GCP are on the way. Full source in GitHub

Overview of the deployment

The objective of this deployment is to get an IPv4/IPv6 scalable, resilient NGNIX deployment to work in AWS and Azure using Terraform.

The requirements for this deployment are as follows:

  1. Customers need to reach this deployment via IPv4 and IPv6
  2. Single Region multi-AZ deployment
  3. Use a native L4 Load Balancer
  4. Use NGINX for Proxy/L7
  5. NGINX instances needs to auto scale

Azure Deployment

Azure supports a full dual-stack deployment on all of the Infrastructure components (VNET, Subnet, LB, VM’s etc.) This enables the IPv6 deployment to essentially be a copy of the IPv4 deployment in Terraform. Data transfers over IPv6 are billed at the same rates as IPv4. A quick overview of what we are going to create:

One thing to note is that I made the assumption that three zones are available since this was a requirement for the project. Not all Azure regions meet this requirement, please check the Azure geographies page for more information regarding this topic.

Azure IPv6 Networking

Outside of setting up Resource Groups and Subscriptions the first thing to start with is vnet creation:

The only detail that is really different in creating the vnet is the allocation of address_space that includes the IPv4 and IPv6 block we want to use, we can see this a little bit better looking at the variables file:

An important note regarding the allocation of space, for the IPv4 block we use RFC 1918 space of “10.0.0.0/16” and for the IPv6 block we use the ULA (Unique Local Address) or RFC 1884 space of “fd00:db8:deca:daed::/64” ULA address space is defined as “an IPv6 address in the address range fc00::/7. Its purpose in IPv6 is analogous to IPv4 private network addressing. Unique local addresses may be used freely, without centralized registration, inside a single site or organization or spanning a limited number of sites or organizations. They are routable only within the scope of such private networks, but not in the global IPv6 Internet”¹ Something to realize when using ULA space is that overlap can occur within an organization that wishes to route between vnets by peering them, therefore an IPv6 address management strategy is required.

The next component to look at is defining the subnet that will be used. Unlike AWS, subnets in Azure are not pinned to a particular zone but rather stretch across zones, with this in mind we will only define one subnet to make maximum use of the VM Scaleset.

Once again the variables file shows the IPv6 addition:

Next let’s take a look at the NSG (Network Security Group) that will be created:

This NSG will work for both IPv4 and IPv6 and will allow all Inbound traffic to access port 80 via TCP. We will now define the frontend public IP’s for the Load Balancer to use:

ip_version needs to be specified in order to determine the type of address for Azure to allocate and domain_name_label is used to make up the FQDN and create the A and AAAA DNS records in the Microsoft Azure DNS system.

Now it is time to look at the Load Balancer creation process, starting with creating a Standard Load Balancer and attaching the two public IP’s as frontend addresses:

Once this is complete the rest of the Load Balancer setup can be done, this includes adding backend address pools, creating a health probe and finally creating the Load Balancing rules for IPv4 and IPv6:

This is a rather large code block, but shows how the dual-stack IPv6 implementation in Azure is simply a copy, paste and replace from IPv4 to IPv6.

Azure IPv6 Compute

At this point it is time to define compute by creating a Zone balanced Linux Virtual Machine Scaleset:

Zones are defined for the Scaleset by using the zones argument, I also set the zone_balance argument to “true”

It is worth looking at the Network Interface section, where the NSG is attached and IP configuration for IPv4 and IPv6 is defined using the version argument as well as attached to the IPv4 and IPv6 Load Balancer pool. Note that one of the configurations need to be set as primary.

This concludes the Terraform scripting section, all that is left is to do some testing.

Verification

For this simple example I first check Azure Load Balancer Insights section to make sure all parts are working:

At this point IPv4 can be checked using any connectivity test:

Checking for IPv6 connectivity is a little more trickier depending on your provider etc. To make it easy I just use https://ipv6-test.com/validate.php

--

--

Sr. Architect for Adobe, Dad of three boys, Husband to a wonderful wife, Reader of Fantasy and Sci-Fi