ExpressRoute vs VPN Gateway: Quando Escolher Cada Um (com Terraform)

Conectar um datacenter on-premises ao Azure tem duas respostas clássicas — e a decisão entre ExpressRoute vs VPN Gateway aparece cedo em qualquer projeto híbrido. VPN Gateway é um túnel IPsec sobre a internet pública; ExpressRoute é um circuito de conectividade privada via provedor de telecom. A resposta certa depende menos de qual é “melhor” e mais de latência, previsibilidade e orçamento.

Quinto artigo da série artigos-network: ExpressRoute vs VPN Gateway, os dois lado a lado com Terraform, os dois aplicados de verdade — incluindo uma mudança recente do Azure que derruba qualquer tutorial de VPN Gateway publicado antes desta mudança.

Segurança: a pre-shared key da conexão IPsec é sensível. Nunca insira IDs de subscription, chaves ou segredos diretamente nos comandos — use TF_VAR_*, um arquivo .tfvars fora do Git, ou o Azure Key Vault.

Sumário

Pré-requisitos

Sobre pré-requisitos do comparativo ExpressRoute vs VPN Gateway com Terraform, você vai precisar do Azure CLI autenticado (az login), do Terraform >= 1.5 e de permissão de Network Contributor na subscription. O provider usado é o azurerm ~> 4.0.

az account show --query "{name:name, id:id}" -o table

Nesse ambiente de teste do ExpressRoute vs VPN Gateway, os dois recursos compartilham a mesma VNet e a mesma GatewaySubnet (nome exigido pelo Azure — só um gateway por VNet reconhece essa subnet específica), mas não se conectam um ao outro: cada um representa um caminho de conectividade independente.

VPN Gateway: túnel IPsec sobre a internet

O VPN Gateway estabelece um túnel IPsec criptografado sobre a internet pública até um roteador on-premises. No Terraform, isso significa um azurerm_virtual_network_gateway, um azurerm_local_network_gateway (representando o roteador do “outro lado” — aqui com IP e address-space fictícios só pra validar a sintaxe) e a conexão entre os dois:

resource "azurerm_virtual_network_gateway" "vpn" {
  name                = "vpngw-blog-castilho"
  resource_group_name = azurerm_resource_group.hybrid.name
  location             = azurerm_resource_group.hybrid.location
  type                 = "Vpn"
  vpn_type             = "RouteBased"
  sku                  = "VpnGw1AZ"

  ip_configuration {
    name                          = "vnetGatewayConfig"
    public_ip_address_id          = azurerm_public_ip.vpn_gateway.id
    private_ip_address_allocation = "Dynamic"
    subnet_id                     = azurerm_subnet.gateway.id
  }
}

resource "azurerm_local_network_gateway" "on_premises" {
  name                = "lng-on-premises-blog-castilho"
  resource_group_name = azurerm_resource_group.hybrid.name
  location             = azurerm_resource_group.hybrid.location
  gateway_address      = "203.0.113.1" # IP fictício de exemplo
  address_space         = ["192.168.0.0/16"]
}

resource "azurerm_virtual_network_gateway_connection" "site_to_site" {
  name                       = "conn-site-to-site-blog-castilho"
  resource_group_name       = azurerm_resource_group.hybrid.name
  location                   = azurerm_resource_group.hybrid.location
  type                       = "IPsec"
  virtual_network_gateway_id = azurerm_virtual_network_gateway.vpn.id
  local_network_gateway_id  = azurerm_local_network_gateway.on_premises.id
  shared_key                 = var.shared_key
}

Troubleshooting: VpnGw1 não-AZ descontinuado

A primeira tentativa deste Terraform usava sku = "VpnGw1" — o SKU “clássico”, que aparece em praticamente todo tutorial de VPN Gateway publicado até aqui. O apply falhou:

Error: creating Virtual Network Gateway: unexpected status 400 (400 Bad Request)
NonAzSkusNotAllowedForVPNGateway: VpnGw1-5 non-AZ SKUs are no longer
supported for VPN gateways. Only VpnGw1-5AZ SKUs can be created going forward.

A correção óbvia — trocar pra VpnGw1AZ — revelou um segundo problema em cascata:

Error: unexpected status 400 (400 Bad Request)
VmssVpnGatewayPublicIpsMustHaveZonesConfigured: Standard Public IPs associated
with VPN Gateways with AZ VPN skus must have zones configured.

Os SKUs *AZ são zone-redundant por natureza — e exigem que o Public IP associado também seja, com zones = ["1", "2", "3"] explicitamente declarado. Sem isso, o Azure rejeita a criação do gateway mesmo com o SKU certo. Se você tem Terraform de VPN Gateway escrito antes dessa mudança, são dois ajustes, não um: SKU *AZ e Public IP com zonas.

ExpressRoute: conectividade privada via provedor

Do outro lado do ExpressRoute vs VPN Gateway, o ExpressRoute Circuit é mais simples de declarar, mas depende de negociação com um provedor de conectividade real pra funcionar de ponta a ponta — o circuito sozinho não conecta a nada até um provedor físico (Equinix, Megaport etc.) provisionar o outro lado:

resource "azurerm_express_route_circuit" "this" {
  name                  = "expressroute-blog-castilho"
  resource_group_name  = azurerm_resource_group.hybrid.name
  location               = azurerm_resource_group.hybrid.location

  service_provider_name = "Equinix"
  peering_location       = "Washington DC"
  bandwidth_in_mbps      = 50

  sku {
    tier   = "Standard"
    family = "MeteredData"
  }
}

Aqui já dá pra ver uma diferença prática de ExpressRoute vs VPN Gateway: o apply do ExpressRoute Circuit demorou quase 30 minutos só pra provisionar o recurso do lado do Azure — mesmo sem nenhum provedor físico conectado ainda. Vale considerar esse tempo no planejamento se você for testar em ambiente de estudo.

terraform plan e apply

terraform init -backend-config=backend.hcl
terraform plan -out=tfplan.out
terraform apply tfplan.out

Pra deixar o teste de ExpressRoute vs VPN Gateway completo, o ambiente cria 8 recursos: Resource Group, VNet + GatewaySubnet, Public IP zone-redundant, VPN Gateway, Local Network Gateway, Connection IPsec e o ExpressRoute Circuit. Tempo total: o VPN Gateway sozinho levou quase 33 minutos pra provisionar — de longe o recurso mais lento de toda a série até aqui.

Testando de verdade: os dois lados aplicados

Testando os dois lados do ExpressRoute vs VPN Gateway com tudo provisionado, a conexão IPsec mostra o estado real — e esse é um ponto importante de expectativa: como o Local Network Gateway aponta pra um IP fictício (não existe roteador nenhum do outro lado respondendo), a conexão nunca vai ficar “Connected”:

az network vpn-connection show \
  --name conn-site-to-site-blog-castilho \
  --resource-group rg-blog-castilho-hybrid \
  --query "{status: connectionStatus, dataIn: ingressBytesTransferred, dataOut: egressBytesTransferred}"

# { "status": "Unknown", "dataIn": 0, "dataOut": 0 }
ExpressRoute vs VPN Gateway: conexão VPN site-to-site aplicada de verdade, status Unknown por falta de peer real
Conexão IPsec real no portal: status Unknown, 0 bytes trafegados — esperado sem peer on-premises de verdade

Esse Unknown com 0 bytes trafegados não é falha do Terraform nem do Azure — é exatamente o esperado quando o “outro lado” não existe fisicamente. Numa migração real, esse mesmo comando é o primeiro lugar a checar quando uma conexão VPN não sobe: connectionStatus diferente de Connected aponta pra configuração incompatível do peer (chave errada, IP errado, ou o próprio peer offline).

Do lado do ExpressRoute, o circuito em si confirma provisionado no Azure, mas sem provedor físico conectado:

az network express-route show \
  --name expressroute-blog-castilho \
  --resource-group rg-blog-castilho-hybrid \
  --query "{provisioningState: provisioningState, providerState: serviceProviderProperties.serviceProviderProvisioningState}"

# { "provisioningState": "Succeeded", "providerState": null }

provisioningState: Succeeded confirma que o recurso do lado do Azure está pronto — mas providerState vazio mostra que falta a parte que só um provedor de conectividade real completa: o “cross-connect” físico até o datacenter do cliente. É essa etapa, fora do controle do Terraform, que torna o ExpressRoute mais lento de contratar (semanas a meses) mesmo com o circuito provisionado em minutos.

ExpressRoute vs VPN Gateway: quando escolher cada um

Na prática, no ExpressRoute vs VPN Gateway: VPN Gateway vence em setup rápido (minutos a horas, não semanas) e custo previsível — bom pra POCs, ambientes de desenvolvimento, filiais pequenas, ou como fallback de um ExpressRoute existente. A latência e a variabilidade de performance da internet pública são a troca aceita.

ExpressRoute vence quando latência previsível e throughput garantido importam de verdade — cargas de trabalho sensíveis a latência, grandes volumes de dados entre on-premises e Azure, ou requisitos de compliance que exigem tráfego fora da internet pública. O custo de entrada é maior e o provisionamento depende de terceiros, mas a experiência de rede é consistente.

Não é incomum ver os dois juntos em produção: ExpressRoute como caminho primário, VPN Gateway como fallback automático se o circuito cair — o melhor dos dois mundos pra quem pode pagar por ambos. Nesse cenário combinado, o dilema ExpressRoute vs VPN Gateway deixa de ser “ou um ou outro” e vira “os dois, com papéis diferentes”.

Custo

No confronto de custo entre ExpressRoute vs VPN Gateway, os dois recursos deste artigo têm custo mensal recorrente mesmo sem tráfego real: o VPN Gateway VpnGw1AZ cobra por hora de gateway ativo (algo na faixa de US$ 140-160/mês proporcional), e o ExpressRoute Circuit Standard cobra mensalmente mesmo sem um provedor físico conectado. É o motivo pelo qual este ambiente, diferente da maioria dos outros da série, foi aplicado, validado e destruído no mesmo dia — não vale manter rodando sem necessidade real — vale o mesmo cuidado pros dois lados do ExpressRoute vs VPN Gateway:

terraform destroy

Conclusão

Na comparação final entre ExpressRoute vs VPN Gateway, não existe resposta universal — existe a resposta certa pro seu orçamento, sua tolerância a latência e o tempo que você tem pra esperar um provedor de conectividade. O que este artigo confirma na prática é que ambos continuam evoluindo: o VPN Gateway com a migração forçada pra SKUs zone-redundant (*AZ) é uma mudança recente que pega quem segue tutoriais antigos, e vale checar antes de replicar qualquer exemplo de Terraform publicado há mais de alguns meses.

Encerrando o comparativo ExpressRoute vs VPN Gateway: esse foi o último artigo pendente da série artigos-network + artigos-paas. Veja também Container Apps e Service Bus.

Referências oficiais

Interessado em saber mais sobre esse assunto?

Deixe uma resposta

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

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

Continuar lendo