DNS Privado Multi-Região No Azure

DNS Privado Multi-Região no Azure

DNS Privado Multi-Região no Azure

DNS Privado Multi-Região no Azure

Neste artigo você vai configurar o DNS privado multi-região no Azure para a Landing Zone Hub-Spoke, criando Private DNS Zones compartilhadas entre as quatro VNets — dois Hubs e dois Spokes em Brazil South e East US. Além disso, vamos criar uma zona interna do lab (blog-castilho.internal) e as zonas de privatelink para os serviços PaaS usados na série: Storage, SQL, ACR, Key Vault, Azure Monitor e Log Analytics. Tudo isso com um módulo Terraform reutilizável que cria a zona e os Virtual Network Links de uma só vez.

Série: DR Azure e Landing Zone
  • 📖 Art. 01: Planejamento de DR Azure e Landing Zone
  • 📖 Art. 02: Hub-Spoke Landing Zone com Terraform
  • 📖 Art. 03: Azure Firewall e NSGs na Landing Zone
  • 📖 Art. 04: Azure Bastion na Landing Zone sem IP Público
  • 📖 Art. 05: Azure Front Door e Traffic Manager para Failover
  • ⚙️ Art. 06 (este): DNS Privado Multi-Região no Azure
  • 🔒 Art. 07: Azure Site Recovery para VMs Multi-Região
  • 🔒 Art. 08: Azure Storage com Geo-Replicação para DR
  • 🔒 Art. 09: AKS Multi-Região com Failover no Azure
  • 🔒 Art. 10: Velero no AKS para Backup e Restore Cross-Region
  • 🔒 Art. 11: Runbooks de Failover no Azure Automation
  • 🔒 Art. 12: Simular um DR no Azure sem Impacto em Produção
  • 🔒 Art. 13: Monitoramento do DR no Azure com Azure Monitor

Sumário

Por que DNS privado multi-região no Azure é necessário

Sem DNS privado configurado, as VMs da Landing Zone que tentam acessar serviços PaaS como Storage Account ou Azure SQL via Private Endpoint recebem o IP público do serviço — mesmo que o tráfego esteja sendo roteado internamente. Isso ocorre porque o DNS público do Azure resolve os FQDNs dos serviços para IPs públicos por padrão. O DNS privado multi-região no Azure resolve esse problema criando zonas que sobrescrevem a resolução pública dentro das VNets.

Cenário Sem Private DNS Com Private DNS
VM acessa Storage Account com Private Endpoint DNS resolve IP público → tráfego sai para internet DNS resolve IP privado do PE → tráfego fica na VNet
VM acessa Azure SQL com PE Resolução para endpoint público Resolução para IP do PE na subnet
Comunicação cross-região (BRS → EUS) Sem resolução privada cross-VNet VNet Links em todas as VNets garantem resolução consistente

Zonas DNS do lab

Este lab cria sete zonas DNS privadas. As seis primeiras são as zonas de privatelink padrão do Azure para os serviços PaaS usados na série. A sétima é a zona interna do lab para registros A de VMs e serviços internos:

Zona DNS Serviço Azure Uso na série
privatelink.blob.core.windows.net Azure Blob Storage Art. 08 — Storage com geo-replicação
privatelink.database.windows.net Azure SQL Database Workloads de dados do Spoke
privatelink.azurecr.io Azure Container Registry Art. 09 — AKS Multi-Região
privatelink.vaultcore.azure.net Azure Key Vault Segredos e certificados dos workloads
privatelink.monitor.azure.com Azure Monitor Art. 13 — Monitoramento do DR
privatelink.ods.opinsights.azure.com Log Analytics Art. 13 — Log Analytics workspace
blog-castilho.internal Zona interna do lab Registros A para VMs e serviços internos

Cada zona é linkada às quatro VNets com registration_enabled = false — os registros são criados manualmente ou pelos Private Endpoints, não de forma automática pela VNet. Isso é intencional: o registro automático de VMs é útil mas pode gerar conflitos em ambientes com múltiplas VNets linkadas à mesma zona.

Arquitetura: zonas centralizadas no Hub

A estratégia de DNS privado multi-região no Azure adotada no lab é centralizar todas as zonas no Resource Group de rede do Hub primário (rg-blog-castilho-network-brazilsouth) e linkar cada zona às quatro VNets. Isso garante resolução DNS consistente independentemente de qual VNet originou a query.

VNet Região Virtual Network Link
vnet-hub-blog-castilho-brazilsouth Brazil South link-hub-brazilsouth (em cada zona)
vnet-hub-blog-castilho-eastus East US link-hub-eastus (em cada zona)
vnet-spoke-blog-castilho-brazilsouth Brazil South link-spoke-brazilsouth (em cada zona)
vnet-spoke-blog-castilho-eastus East US link-spoke-eastus (em cada zona)

Com essa configuração, uma VM no Spoke de East US que tenta resolver meu-storage.blob.core.windows.net via privatelink.blob.core.windows.net vai obter o IP privado do Private Endpoint — mesmo que o PE esteja no Spoke de Brazil South, desde que o registro A aponte para o IP correto.

Pré-requisitos

  • Hub-Spoke Landing Zone implantada (Art. 02) — as quatro VNets existentes
  • Terraform ≥ 1.5 e Azure CLI autenticado
  • Storage Account de remote state configurado (bootstrap do Art. 02)
  • Módulo modules/private-dns-zone presente em scripts/modules/

O módulo Terraform private-dns-zone

Para implementar DNS privado multi-região no Azure sem repetir o mesmo código Terraform sete vezes, usamos um módulo local que encapsula a criação da zona e os quatro Virtual Network Links. O módulo recebe o nome da zona e um mapa de VNets como entrada:

# modules/private-dns-zone/main.tf

resource "azurerm_private_dns_zone" "this" {
  name                = var.zone_name
  resource_group_name = var.resource_group_name
  tags                = var.tags
}

resource "azurerm_private_dns_zone_virtual_network_link" "this" {
  for_each = var.vnet_links

  name                  = "link-${each.key}"
  resource_group_name   = var.resource_group_name
  private_dns_zone_name = azurerm_private_dns_zone.this.name
  virtual_network_id    = each.value
  registration_enabled  = false
  tags                  = var.tags
}

O for_each = var.vnet_links itera sobre o mapa de VNets e cria um link para cada uma. O nome do link usa o each.key — por exemplo, link-hub-brazilsouth, link-spoke-eastus. Assim, um único módulo cria a zona + 4 links com um único bloco module.

Passo 1 — Código Terraform da zona

O main.tf do recurso pdnsz-blog-castilho define os data sources para as quatro VNets, o mapa de links e chama o módulo com for_each para criar as sete zonas de DNS privado multi-região no Azure em paralelo:

data "azurerm_resource_group" "this" {
  name = "rg-blog-castilho-network-brazilsouth"
}

data "azurerm_virtual_network" "hub_brazilsouth" {
  name                = "vnet-hub-blog-castilho-brazilsouth"
  resource_group_name = "rg-blog-castilho-network-brazilsouth"
}

data "azurerm_virtual_network" "hub_eastus" {
  name                = "vnet-hub-blog-castilho-eastus"
  resource_group_name = "rg-blog-castilho-network-eastus"
}

data "azurerm_virtual_network" "spoke_brazilsouth" {
  name                = "vnet-spoke-blog-castilho-brazilsouth"
  resource_group_name = "rg-blog-castilho-network-brazilsouth"
}

data "azurerm_virtual_network" "spoke_eastus" {
  name                = "vnet-spoke-blog-castilho-eastus"
  resource_group_name = "rg-blog-castilho-network-eastus"
}

locals {
  vnet_links = {
    hub-brazilsouth   = data.azurerm_virtual_network.hub_brazilsouth.id
    hub-eastus        = data.azurerm_virtual_network.hub_eastus.id
    spoke-brazilsouth = data.azurerm_virtual_network.spoke_brazilsouth.id
    spoke-eastus      = data.azurerm_virtual_network.spoke_eastus.id
  }

  zones = [
    "privatelink.blob.core.windows.net",
    "privatelink.database.windows.net",
    "privatelink.azurecr.io",
    "privatelink.vaultcore.azure.net",
    "privatelink.monitor.azure.com",
    "privatelink.ods.opinsights.azure.com",
    "blog-castilho.internal",
  ]
}

module "dns_zones" {
  source   = "../../../modules/private-dns-zone"
  for_each = toset(local.zones)

  zone_name           = each.value
  resource_group_name = data.azurerm_resource_group.this.name
  vnet_links          = local.vnet_links
  tags                = var.tags
}

O for_each = toset(local.zones) cria uma instância do módulo para cada zona. O Terraform cria todas as sete zonas em paralelo, cada uma com seus quatro Virtual Network Links — totalizando 7 zonas + 28 links (7 × 4) em um único terraform apply.

Passo 2 — Executar o Terraform

export AZURE_SUBSCRIPTION_ID="<SUBSCRIPTION_ID>"
export TF_STATE_RG="rg-blog-castilho-tfstate"
export TF_STATE_SA="<storage-account-name>"
export TF_STATE_CONTAINER="tfstate"

cd scripts/art-06-dns-privado/pdnsz-blog-castilho

cat > backend.hcl <<EOF
resource_group_name  = "$TF_STATE_RG"
storage_account_name = "$TF_STATE_SA"
container_name       = "$TF_STATE_CONTAINER"
key                  = "pdnsz-blog-castilho.tfstate"
EOF

terraform init -backend-config=backend.hcl -reconfigure
terraform apply -var subscription_id="$AZURE_SUBSCRIPTION_ID"

O apply cria 35 recursos (7 zonas + 28 links) da solução de DNS privado multi-região no Azure e leva cerca de 3 a 5 minutos. A criação é rápida porque Private DNS Zones são recursos leves, sem necessidade de provisionamento de instância.

# Exemplo de output esperado:
Apply complete! Resources: 35 added, 0 changed, 0 destroyed.

# Recursos criados (exemplo para uma zona):
# module.dns_zones["privatelink.blob.core.windows.net"].azurerm_private_dns_zone.this
# module.dns_zones["privatelink.blob.core.windows.net"].azurerm_private_dns_zone_virtual_network_link.this["hub-brazilsouth"]
# module.dns_zones["privatelink.blob.core.windows.net"].azurerm_private_dns_zone_virtual_network_link.this["hub-eastus"]
# module.dns_zones["privatelink.blob.core.windows.net"].azurerm_private_dns_zone_virtual_network_link.this["spoke-brazilsouth"]
# module.dns_zones["privatelink.blob.core.windows.net"].azurerm_private_dns_zone_virtual_network_link.this["spoke-eastus"]

Passo 3 — Adicionar registros DNS

Após criar as zonas, você pode adicionar registros manualmente para serviços internos do lab. Os registros de Private Endpoint são criados automaticamente pelo Azure quando o PE é provisionado — mas para a zona interna blog-castilho.internal, os registros A precisam ser criados explicitamente:

# Exemplo: adicionar registro A para uma VM de gerenciamento
az network private-dns record-set a add-record \
  --resource-group rg-blog-castilho-network-brazilsouth \
  --zone-name blog-castilho.internal \
  --record-set-name mgmt-brazilsouth \
  --ipv4-address 10.0.0.200

# Verificar o registro
az network private-dns record-set a show \
  --resource-group rg-blog-castilho-network-brazilsouth \
  --zone-name blog-castilho.internal \
  --name mgmt-brazilsouth

# Agora uma VM em qualquer VNet linkada resolve:
# mgmt-brazilsouth.blog-castilho.internal → 10.0.0.200

Verificar a configuração do DNS privado multi-região no Azure

# Listar todas as zonas DNS privadas no Resource Group
az network private-dns zone list \
  --resource-group rg-blog-castilho-network-brazilsouth \
  --query "[].{name:name, numberOfRecords:numberOfRecordSets}" \
  --output table

# Exemplo de output esperado:
# Name                                       NumberOfRecords
# -----------------------------------------  ---------------
# blog-castilho.internal                     1
# privatelink.azurecr.io                     1
# privatelink.blob.core.windows.net          1
# privatelink.database.windows.net           1
# privatelink.monitor.azure.com              1
# privatelink.ods.opinsights.azure.com       1
# privatelink.vaultcore.azure.net            1

# Verificar Virtual Network Links de uma zona
az network private-dns link vnet list \
  --resource-group rg-blog-castilho-network-brazilsouth \
  --zone-name "privatelink.blob.core.windows.net" \
  --query "[].{name:name, vnet:virtualNetwork.id, status:provisioningState}" \
  --output table

# Exemplo de output esperado:
# Name                  VNet (parcial)                                Status
# --------------------  --------------------------------------------  ---------
# link-hub-brazilsouth  .../vnet-hub-blog-castilho-brazilsouth        Succeeded
# link-hub-eastus       .../vnet-hub-blog-castilho-eastus             Succeeded
# link-spoke-brazilsouth .../vnet-spoke-blog-castilho-brazilsouth     Succeeded
# link-spoke-eastus     .../vnet-spoke-blog-castilho-eastus           Succeeded

Troubleshooting

Problema Causa Solução
VM resolve IP público mesmo com Private Endpoint VNet não está linkada à zona DNS privada Confirme que o VNet Link existe e está Succeeded para a VNet da VM
ZoneAlreadyExists Zona criada anteriormente por outro processo Importe a zona existente: terraform import e re-execute o apply
Link com registration_enabled = true duplica registros Conflito entre registro automático e manual Use registration_enabled = false e gerencie registros explicitamente
Módulo não encontrado no terraform init Caminho relativo incorreto em source Verifique o caminho relativo de pdnsz-blog-castilho/ até modules/private-dns-zone/ — deve ser ../../../modules/private-dns-zone
Resolução DNS falha para zona .internal Sufixo não reconhecido pelo DNS resolver da VNet Zonas .internal são válidas no Azure Private DNS — confirme que a VNet está linkada

Limpeza dos recursos

cd scripts/art-06-dns-privado/pdnsz-blog-castilho
terraform destroy -var subscription_id="$AZURE_SUBSCRIPTION_ID"
# Remove 35 recursos: 7 zonas + 28 links

Próximos passos

Com o DNS privado multi-região no Azure configurado, as zonas de privatelink estão prontas para receber os registros automáticos dos Private Endpoints criados nos próximos artigos. O Art. 07 aborda o Azure Site Recovery para proteger VMs contra falha de região, configurando replicação contínua de Brazil South para East US com Terraform.

Série: DR Azure e Landing Zone
  • 📖 Art. 01: Planejamento de DR Azure e Landing Zone
  • 📖 Art. 02: Hub-Spoke Landing Zone com Terraform
  • 📖 Art. 03: Azure Firewall e NSGs na Landing Zone
  • 📖 Art. 04: Azure Bastion na Landing Zone sem IP Público
  • 📖 Art. 05: Azure Front Door e Traffic Manager para Failover
  • ⚙️ Art. 06 (este): DNS Privado Multi-Região no Azure
  • 🔒 Art. 07: Azure Site Recovery para VMs Multi-Região
  • 🔒 Art. 08: Azure Storage com Geo-Replicação para DR
  • 🔒 Art. 09: AKS Multi-Região com Failover no Azure
  • 🔒 Art. 10: Velero no AKS para Backup e Restore Cross-Region
  • 🔒 Art. 11: Runbooks de Failover no Azure Automation
  • 🔒 Art. 12: Simular um DR no Azure sem Impacto em Produção
  • 🔒 Art. 13: Monitoramento do DR no Azure com Azure Monitor

Interessado em saber mais sobre artigos relacionados ao Microsoft Azure CLIQUE AQUI

🚀 Vamos nos conectar?

Não perca nenhuma oportunidade! Cadastre-se nas minhas redes e no canal do YouTube para receber conteúdos de TI, Cloud, Azure, Kubernetes e DevOps em primeira mão.

Dica: No Facebook, todos os artigos do blog são publicados automaticamente. Vale a pena curtir!


💬 Dúvidas ou Problemas?

Com o intuito de ajudar a comunidade, caso você tenha dúvidas ou encontre problemas na execução dos comandos deste artigo, deixe um comentário abaixo. Responderei o mais breve possível!

Muito obrigado pela visita e até o próximo post!

Jefferson Castilho Especialista em Cloud & DevOps.

Este guia técnico é exclusivo do Blog do Castilho. Explore nossa para mais conteúdos sobre IA e Cloud.

 

Deixe uma resposta

Rolar para cima

Descubra mais sobre Blog do Castilho - Tecnologia | FinOps | DevOps | Cloud

Assine agora mesmo para continuar lendo e ter acesso ao arquivo completo.

Continue reading