Azure Public IP addresses serve as the critical entry point for public connections to Azure resources. Whether you are deploying a single virtual machine, a complex load balancer, or a global application gateway, the way you define and manage your IP address space impacts your network's reliability, routing efficiency, and scalability. By utilizing Terraform and HashiCorp Configuration Language (HCL), engineers can define, preview, and deploy this infrastructure as code, ensuring consistency across environments and reducing the risks associated with manual portal configuration.
Understanding Azure Public IP Fundamentals
A public IP address in Azure is a resource that provides a consistent entry point for internet-based traffic to reach your cloud resources. These addresses are categorized by SKUs, tiers, and routing preferences, each serving specific architectural needs.
Public IP SKUs and Tiers
Azure offers two primary SKUs for public IP addresses: Basic and Standard. The selection of a SKU determines the capabilities and limitations of the resource.
- Basic SKU: Typically used for simpler deployments, though it is being phased out in favor of Standard for most modern scenarios.
- Standard SKU: Provides higher reliability, availability zone support, and is required for IPv6 deployments.
Furthermore, public IP addresses are divided into two tiers based on their scope of reach:
- Regional: The IP address is bound to a specific Azure region.
- Global: The IP address is not bound to a single region, allowing for global load balancing and traffic management.
Routing Preferences
When creating a public IP, the routing preference defines how traffic is routed to the resource. There are two available choices:
- Internet Routing: This is the default routing, where traffic uses the public internet to reach the Azure network.
- Microsoft Network Routing: This optimizes traffic by keeping it within the Microsoft global network for as long as possible, potentially reducing latency and increasing security.
Terraform Architecture for Public IP Management
Terraform enables a declarative approach to infrastructure. Instead of executing a series of commands, you define the desired end-state of your network in configuration files.
The HCL Workflow
The process of deploying Azure public IPs via Terraform follows a strict lifecycle:
- Definition: You write HCL syntax to specify the provider (azurerm) and the public IP resources.
- Preview: The
terraform plancommand creates an execution plan. This is a critical step that allows the engineer to see exactly what will be created, modified, or destroyed without actually applying changes to the cloud environment. - Deployment: The
terraform applycommand executes the plan, communicating with Azure APIs to provision the resources. - Cleanup: When resources are no longer required,
terraform plan -destroy -out main.destroy.tfplancan be used to generate a plan specifically for the removal of the infrastructure.
Technical Implementation: IPv4 Configuration
The implementation of an IPv4 public IP depends on the required availability and routing needs. For production environments, a Standard SKU with static allocation and zone redundancy is recommended.
Standard IPv4 Implementation
The following configuration demonstrates a high-availability setup using the azurerm_public_ip resource. This setup includes zone redundancy, meaning the IP is distributed across multiple availability zones (1, 2, and 3) to prevent a single point of failure.
```hcl
resource "azurermresourcegroup" "example" {
name = "rg-pip-example"
location = "germanywestcentral"
}
resource "azurermpublicip" "myRoutingPreferenceStandardPublicIP" {
name = "myRoutingPreferenceStandardPublicIP"
resourcegroupname = azurermresourcegroup.example.name
location = azurermresourcegroup.example.location
allocationmethod = "Static"
sku = "Standard"
ipversion = "IPv4"
# Configuring Routing Preference via IP Tags
ip_tags = {
RoutingPreference = "Internet"
}
# Enabling Availability Zones for high availability
zones = ["1", "2", "3"]
}
```
IP Allocation Methods
There are two primary allocation methods for public IP addresses:
- Static: The IP address is assigned at the time of resource creation and remains unchanged for the lifetime of the resource. This is essential for DNS records and firewall whitelisting.
- Dynamic: The IP address is not allocated until the resource (such as a VM or Load Balancer) is started. If the resource is stopped and deallocated, the IP may change.
Implementing IPv6 in Azure
As the internet transitions toward IPv6, Azure provides full support for IPv6 public IPs. These are foundational for resources that must be directly reachable over IPv6 from the internet, including directly exposed virtual machines, load balancers, and application gateways.
Critical IPv6 Constraints
When implementing IPv6, engineers must adhere to several strict constraints:
- SKU Requirement: For all current deployments, IPv6 public IPs must use the Standard SKU.
- Allocation Requirement: Standard IPv6 public IPs exclusively use Static allocation.
- NIC Limitations: A Network Interface Card (NIC) can have only one IPv6 IP configuration, and it can have at most one IPv6 public IP attached.
- Dual-Stack Services: Certain services, such as the Azure Application Gateway, require separate Public IP resources for IPv4 and IPv6 to function in a dual-stack mode.
Terraform IPv6 Configuration
To deploy an IPv6 public IP, the ip_version attribute must be explicitly set to IPv6.
```hcl
locals {
location = "East East"
rg_name = "rg-ipv6-demo"
}
resource "azurermpublicip" "ipv6primary" {
name = "pip-ipv6-primary"
location = local.location
resourcegroupname = local.rgname
sku = "Standard"
ipversion = "IPv6"
allocationmethod = "Static"
domainnamelabel = "myapp-ipv6"
tags = {
Environment = "production"
}
}
Attaching IPv6 to a Subnet configuration
resource "azurermnetworkinterfaceipconfiguration" "ipv6config" {
name = "ipv6"
subnetid = azurermsubnet.main.id
privateipaddressallocation = "Dynamic"
privateipaddressversion = "IPv6"
publicipaddressid = azurermpublicip.ipv6_primary.id
}
```
Verification of IPv6 Deployment
After running terraform apply, you can verify the assigned IPv6 address and its DNS resolution using the Azure CLI and standard network tools:
To retrieve the IP address:
az network public-ip show --resource-group rg-ipv6-demo --name pip-ipv6-primary --query ipAddressTo verify the AAAA record resolution:
dig AAAA myapp-ipv6.eastus.cloudapp.azure.com
Managing Public IP Prefixes
For organizations requiring a large block of contiguous IP addresses, Azure provides the Public IP Address Prefix resource. A prefix is essentially a reserved range of Standard SKU public IP addresses.
Benefits of IP Prefixes
Using a prefix allows you to:
- Ensure a contiguous range of IPs for firewall rule simplification.
- Assign static public IP addresses from the prefix to multiple resources, such as virtual machines or load balancers.
- Maintain a predictable IP range even as you scale your resources.
When a public IP is created from a prefix, it inherits the properties of that prefix, providing a more structured approach to IP address management (IPAM) within the Azure cloud.
Advanced Public IP Attributes and Exports
The azurerm_public_ip resource provides several attributes that can be exported and used as inputs for other resources.
Exported Attributes
- fqdn: This is the fully qualified domain name of the A DNS record associated with the public IP. It is created by concatenating the
domain_name_labelwith the regionalized DNS zone. - ip_address: The actual IP address assigned to the resource.
Note on Dynamic Allocation
It is important to note that for Dynamic public IPs, the ip_address attribute is not populated until the IP is actually attached to a device (e.g., a VM or Load Balancer). To obtain a dynamic IP address in Terraform, the azurerm_public_ip data source must be used after the attachment has occurred.
Comparative Technical Specifications
The following table summarizes the differences between the primary public IP configurations available in Azure.
| Feature | Basic SKU | Standard SKU (IPv4) | Standard SKU (IPv6) |
|---|---|---|---|
| Allocation Method | Static or Dynamic | Static or Dynamic | Static Only |
| Availability Zones | Not Supported | Supported | Supported |
| Routing Preference | Not Available | Internet / Microsoft | Internet / Microsoft |
| Tier | Regional | Regional or Global | Regional |
| Default Security | Open/Open-by-default | Closed-by-default | Closed-by-default |
| Resource Use | Legacy/Simple | Production/Enterprise | Modern Dual-Stack |
Modularizing Public IP Deployment
For scalability, it is recommended to use Terraform modules rather than standalone resources. This allows for the reuse of configurations across different environments (Dev, Stage, Prod).
Module Implementation Example
A well-structured module allows the operator to pass variables for location, SKU, and zones, making the infrastructure highly flexible.
```hcl
module "publicip" {
source = "../../modules/public-ip"
name = "pip-example"
resourcegroupname = azurermresourcegroup.example.name
location = azurermresourcegroup.example.location
allocationmethod = "Static"
zones = ["1"]
ddosprotectionmode = "Disabled"
domainnamelabel = "my-public-ip"
idletimeoutinminutes = 10
ipversion = "IPv4"
sku = "Standard"
sku_tier = "Regional"
tags = {
Environment = "Production"
Owner = "Network Team"
}
}
```
Managing Multiple IPs with for_each
When deploying a suite of services (e.g., a web front-end, an API gateway, and a management portal), using the for_each meta-argument prevents code duplication.
```hcl
variable "services" {
type = list(string)
default = ["web", "api", "gateway"]
}
resource "azurermpublicip" "ipv6services" {
foreach = toset(var.services)
name = "pip-ipv6-${each.key}"
location = local.location
resourcegroupname = local.rgname
sku = "Standard"
ipversion = "IPv6"
allocation_method = "Static"
}
```
Importing Existing Public IPs
In scenarios where public IPs were created manually via the Azure Portal or CLI, they can be brought under Terraform management using the terraform import command. This prevents the destruction of existing resources during the transition to Infrastructure as Code.
The command requires the specific resource ID from Azure:
bash
terraform import azurerm_public_ip.myPublicIp /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.Network/publicIPAddresses/myPublicIpAddress1
Once imported, the state file is updated, and the developer can then write the corresponding HCL code to match the existing configuration.
Conclusion
The deployment of Azure Public IP addresses via Terraform provides a robust mechanism for managing internet ingress to cloud resources. By understanding the distinction between Basic and Standard SKUs, the nuances of IPv4 versus IPv6, and the strategic use of Availability Zones, engineers can build highly resilient network architectures. The transition to IPv6, in particular, requires a strict adherence to the Standard SKU and Static allocation constraints to ensure successful connectivity. Furthermore, the use of Public IP prefixes offers a scalable path for managing larger IP blocks. By leveraging HCL's declarative nature, including the use of modules and for_each loops, organizations can ensure that their public-facing infrastructure is documented, repeatable, and easily maintainable. The integration of routing preferences—choosing between Internet and Microsoft Network routing—further allows for the fine-tuning of traffic latency and security, completing the toolkit for modern Azure network engineering.