<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <docs>https://blogs.law.harvard.edu/tech/rss</docs>
    <title>Networking on FXShell - DevOps &amp; Sec</title>
    <link>https://fxshelll.github.io/tags/networking/</link>
    <description>Recent content in Networking on FXShell - DevOps &amp; Sec</description>
    <image>
      <title>Networking on FXShell - DevOps &amp; Sec</title>
      <link>https://fxshelll.github.io/tags/networking/</link>
      <url>fxshell.png</url>
    </image>
    <ttl>1440</ttl>
    <generator>Hugo 0.152.2</generator>
    <language>pt-br</language>
    <lastBuildDate>Sun, 26 Apr 2026 01:47:17 UT</lastBuildDate>
    <atom:link href="https://fxshelll.github.io/tags/networking/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Application Gateway no Azure com Terraform — Lab de Backend API com Path Routing</title>
      <link>https://fxshelll.github.io/posts/terraform-azure-appgw/</link>
      <pubDate>Sat, 25 Apr 2026 00:00:00 UT</pubDate>
      <dc:creator>Felipe da Matta</dc:creator>
      <guid>https://fxshelll.github.io/posts/terraform-azure-appgw/</guid>
      <description>Se a sua aplicação expõe múltiplas APIs numa mesma infraestrutura e você precisa rotear o tráfego por URL — /api/orders para um pool, /api/inventory para outro — um Load Balancer tradicional não resolve. Ele opera na camada 4 (TCP/UDP), enxerga apenas IP e porta, e distribui conexões sem entender o conteúdo HTTP. O Azure Application Gateway opera na camada 7 e faz exatamente esse roteamento baseado em path, header e host — além de oferecer SSL termination, health probes HTTP e integração com WAF.
</description>
      <content:encoded><![CDATA[Se a sua aplicação expõe múltiplas APIs numa mesma infraestrutura e você precisa rotear o tráfego por URL — /api/orders para um pool, /api/inventory para outro — um Load Balancer tradicional não resolve. Ele opera na camada 4 (TCP/UDP), enxerga apenas IP e porta, e distribui conexões sem entender o conteúdo HTTP. O Azure Application Gateway opera na camada 7 e faz exatamente esse roteamento baseado em path, header e host — além de oferecer SSL termination, health probes HTTP e integração com WAF.
Este lab provisiona com Terraform um cenário completo: uma API backend em Python rodando em 3 VMs, um Application Gateway com URL path map, health probes customizados e backend pools separados por rota.
Application Gateway vs Load Balancer — O Que Muda Antes de entrar no lab, vale entender por que escolher um em vez do outro. A diferença fundamental é a camada OSI em que cada um opera:
Característica Azure Load Balancer (L4) Azure Application Gateway (L7) Camada OSI 4 — TCP/UDP 7 — HTTP/HTTPS O que enxerga IP de origem/destino, porta URL, headers, cookies, hostname Roteamento Por IP + porta (regras de NAT) Por URL path, header, hostname Health probe TCP ou HTTP (código de status) HTTP com path, hostname e match de body SSL/TLS Pass-through (não termina) SSL termination e re-encryption WAF Não Sim (WAF v2 integrado ou add-on) Session affinity Por IP de origem (hash) Cookie-based affinity nativo Rewrite Não Headers, URL path e query string Autoscale Sim Sim (Standard_v2) Custo Mais barato Mais caro (paga por capacity units) Caso de uso Tráfego não-HTTP (DB, DNS, gaming) APIs, microsserviços, apps web Quando usar Load Balancer Tráfego TCP/UDP puro — bancos de dados, servidores DNS, jogos multiplayer Cenários onde você só precisa distribuir conexões por IP e porta Custo é prioridade e você não precisa de nenhum recurso HTTP Balanceamento interno entre VMs na mesma VNet sem exposição pública Quando usar Application Gateway APIs HTTP/HTTPS que precisam de roteamento por URL path (microsserviços) Aplicações que exigem SSL termination centralizado Cenários que precisam de WAF para proteção contra OWASP Top 10 Session affinity por cookie (aplicações stateful) Redirect HTTP → HTTPS, rewrite de headers e URL Vantagens do Application Gateway em detalhes Roteamento por URL path — O recurso central. Com url_path_map, o gateway inspeciona o path da requisição HTTP e direciona para backend pools diferentes. /api/orders pode ir para um conjunto de servidores otimizado para consultas de pedidos, enquanto /api/inventory vai para outro pool com mais memória. Com Load Balancer, todo tráfego na porta 80/443 vai para o mesmo backend — não há como diferenciar por rota.
Health probes HTTP inteligentes — O Load Balancer verifica se a porta TCP está respondendo. O Application Gateway faz um GET /health (ou qualquer path configurado), valida o status code HTTP e pode até verificar o conteúdo do body. Se o backend retorna 200 mas com {&quot;status&quot;:&quot;degraded&quot;}, o probe pode detectar isso. Isso reduz drasticamente falsos positivos de &ldquo;healthy&rdquo; em backends que aceitam conexão TCP mas não estão funcionando corretamente.
SSL termination (offload) — O TLS é terminado no gateway, que faz a descriptografia e encaminha tráfego HTTP puro para os backends. Isso elimina o custo de CPU de TLS em cada VM backend e centraliza a gestão de certificados em um único ponto. Opcionalmente, o gateway pode re-encriptar o tráfego para o backend (end-to-end TLS), mas o certificado pode ser diferente — self-signed, por exemplo.
WAF integrado — O Application Gateway com SKU WAF_v2 inclui proteção contra ataques OWASP Top 10 (SQL injection, XSS, CSRF) sem precisar de um appliance separado. As regras são gerenciadas centralmente e atualizadas pela Microsoft. Com Load Balancer, proteção WAF exige uma solução externa.
Autoscale zone-redundant (v2) — O SKU Standard_v2 escala automaticamente as instâncias do gateway baseado no tráfego e pode ser distribuído entre Availability Zones, eliminando o gateway como ponto único de falha.
Objetivo do Lab Provisionar com Terraform um Application Gateway que recebe requisições HTTP, roteia por URL path para backend pools distintos e monitora a saúde dos backends com health probes HTTP customizados. A aplicação backend é uma API Python minimalista que serve /api/orders, /api/inventory e /health.
Tecnologias Utilizadas Terraform é a ferramenta de Infrastructure as Code que provisiona todos os recursos no Azure de forma declarativa e versionável.
Azure Application Gateway é o balanceador de carga de camada 7 da Microsoft que inspeciona o conteúdo HTTP das requisições e roteia para diferentes backend pools baseado em regras de URL path, headers e hostnames.
Azure Virtual Network isola a infraestrutura com subnets dedicadas — uma para o Application Gateway (requisito obrigatório) e outra para os backends.
Cloud-init configura as VMs no primeiro boot, instalando Python e iniciando a API backend como um serviço systemd, sem necessidade de acesso SSH manual.
Arquitetura ┌──────────────────────────────────────────────────────────────────────┐ │ REQUEST FLOW │ │ │ │ ┌───────────┐ HTTPS ┌────────────────────────────┐ │ │ │ Usuario │ ────────► │ Application Gateway │ │ │ │ (Internet) │ │ Standard_v2 │ │ │ └───────────┘ │ │ │ │ │ Listener :80 │ │ │ │ URL Path Map: │ │ │ │ /api/orders → pool-orders │ │ │ │ /api/inventory → pool-inv │ │ │ │ Health Probe: GET /health │ │ │ └──────────┬───────────────────┘ │ │ │ :8080 │ │ ┌──────────┼──────────┐ │ │ ▼ ▼ ▼ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │backend-1 │ │backend-2 │ │backend-3 │ │ │ │10.10.2.4 │ │10.10.2.5 │ │10.10.2.6 │ │ │ │ Python │ │ Python │ │ Python │ │ │ │ API:8080 │ │ API:8080 │ │ API:8080 │ │ │ └──────────┘ └──────────┘ └──────────┘ │ └──────────────────────────────────────────────────────────────────────┘ Componente Função Application Gateway Recebe tráfego HTTP, roteia por URL path, monitora health dos backends Listener Escuta na porta 80 com o IP público do gateway URL Path Map Mapeia /api/orders e /api/inventory para backend pools diferentes Health Probe Verifica /health a cada 15s — remove backend do pool após 3 falhas Backend Pool Grupo de VMs que recebe o tráfego roteado pelo gateway vm-backend-1..3 VMs Ubuntu com API Python servindo na porta 8080 Como Funciona o Path-Based Routing Quando uma requisição chega ao Application Gateway, o processamento segue esta sequência:
O Listener aceita a conexão HTTP na porta 80 (ou 443 com TLS) A Request Routing Rule associa o listener ao URL Path Map O URL Path Map inspeciona o path da URL e encontra a path_rule correspondente A requisição é encaminhada para o Backend Pool definido na regra, usando as configurações do Backend HTTP Settings (porta 8080, timeout, affinity) O gateway mantém um Health Probe periódico que faz GET /health em cada backend — backends que falham são removidos do pool automaticamente Se nenhuma path_rule corresponde ao path da requisição, o gateway usa o default_backend_address_pool definido no path map.
Subnet dedicada: O Application Gateway v2 exige uma subnet dedicada (sem outras VMs ou serviços). O Terraform cria snet-appgw exclusivamente para o gateway e snet-backend para as VMs — não tente colocar ambos na mesma subnet.
Estrutura do Projeto terraform-azure-appgw/ ├── main.tf # Provider, backend, módulos ├── variables.tf # Variáveis de entrada ├── outputs.tf # Outputs (IP público, FQDN) ├── modules/ │ ├── networking/ │ │ ├── main.tf # VNet, subnets, NSGs │ │ ├── variables.tf │ │ └── outputs.tf │ ├── backend_app/ │ │ ├── main.tf # VMs + cloud-init (API Python) │ │ ├── variables.tf │ │ └── outputs.tf │ └── app_gateway/ │ ├── main.tf # AppGW, listeners, path map, probes │ ├── variables.tf │ └── outputs.tf └── diagrama/ ├── terraform-azure-appgw.html ├── terraform-azure-appgw.gif └── gerar_gif.py Networking — VNet e Subnets A VNet usa o CIDR 10.10.0.0/16 com duas subnets isoladas:
10.10.0.0/16 (vnet-appgw-lab) ├── 10.10.1.0/24 snet-appgw ← Application Gateway (dedicada) └── 10.10.2.0/24 snet-backend ← VMs backend O NSG da subnet do gateway permite HTTP (80), HTTPS (443) e o range de portas de gerenciamento 65200-65535 (obrigatório para o Application Gateway v2 funcionar — sem essa regra, o health do gateway fica degraded).
security_rule { name = &#34;AllowGatewayManager&#34; priority = 120 direction = &#34;Inbound&#34; access = &#34;Allow&#34; protocol = &#34;Tcp&#34; source_port_range = &#34;*&#34; destination_port_range = &#34;65200-65535&#34; source_address_prefix = &#34;GatewayManager&#34; destination_address_prefix = &#34;*&#34; } O NSG da subnet de backend permite tráfego apenas da subnet do gateway na porta 8080 — nenhum acesso direto da internet aos backends:
security_rule { name = &#34;AllowAppGwToBackend&#34; priority = 100 direction = &#34;Inbound&#34; access = &#34;Allow&#34; protocol = &#34;Tcp&#34; source_port_range = &#34;*&#34; destination_port_range = &#34;8080&#34; source_address_prefix = &#34;10.10.1.0/24&#34; destination_address_prefix = &#34;*&#34; } Backend API — Python com cloud-init Cada VM backend roda uma API HTTP em Python puro (sem framework) na porta 8080, provisionada automaticamente via cloud-init no primeiro boot. A API serve três endpoints:
Endpoint Retorno GET /health {&quot;status&quot;: &quot;healthy&quot;} — usado pelo health probe GET /api/orders Lista de pedidos fictícios + hostname do servidor GET /api/inventory Lista de estoque fictício + hostname do servidor O hostname no response permite verificar qual backend respondeu — útil para confirmar que o round-robin está funcionando.
class Handler(BaseHTTPRequestHandler): def do_GET(self): if self.path == &#34;/health&#34;: self.send_response(200) self.send_header(&#34;Content-Type&#34;, &#34;application/json&#34;) self.end_headers() self.wfile.write(json.dumps({&#34;status&#34;: &#34;healthy&#34;}).encode()) elif self.path == &#34;/api/orders&#34;: data = { &#34;server&#34;: socket.gethostname(), &#34;orders&#34;: [ {&#34;id&#34;: 1, &#34;product&#34;: &#34;Widget A&#34;, &#34;qty&#34;: 10}, {&#34;id&#34;: 2, &#34;product&#34;: &#34;Widget B&#34;, &#34;qty&#34;: 5}, ] } # ... A API roda como serviço systemd (api-backend.service) com Restart=always, garantindo que ela reinicie automaticamente em caso de crash.
Application Gateway — Path Map e Health Probes O gateway é o componente central. O Terraform configura:
URL Path Map url_path_map { name = &#34;url-path-map&#34; default_backend_address_pool_name = &#34;pool-orders&#34; default_backend_http_settings_name = &#34;http-settings-default&#34; path_rule { name = &#34;rule-orders&#34; paths = [&#34;/api/orders&#34;, &#34;/api/orders/*&#34;] backend_address_pool_name = &#34;pool-orders&#34; backend_http_settings_name = &#34;http-settings-default&#34; } path_rule { name = &#34;rule-inventory&#34; paths = [&#34;/api/inventory&#34;, &#34;/api/inventory/*&#34;] backend_address_pool_name = &#34;pool-inventory&#34; backend_http_settings_name = &#34;http-settings-default&#34; } } O default_backend_address_pool captura qualquer path que não tenha regra explícita — sem ele, o gateway retorna 502.
Health Probe probe { name = &#34;probe-health&#34; host = &#34;127.0.0.1&#34; path = &#34;/health&#34; protocol = &#34;Http&#34; interval = 15 timeout = 10 unhealthy_threshold = 3 } O probe faz GET /health a cada 15 segundos. Se um backend não responder 200 em 3 tentativas consecutivas (45 segundos), ele é removido do pool. Quando volta a responder, é readicionado automaticamente.
Backend HTTP Settings backend_http_settings { name = &#34;http-settings-default&#34; cookie_based_affinity = &#34;Disabled&#34; port = 8080 protocol = &#34;Http&#34; request_timeout = 30 probe_name = &#34;probe-health&#34; } O cookie_based_affinity está desabilitado porque a API é stateless — cada requisição pode ir para qualquer backend. Em aplicações stateful (sessões), habilitar isso faz o gateway inserir um cookie ApplicationGatewayAffinity que fixa o usuário no mesmo backend.
Executando # Inicializar terraform init # Revisar o plano terraform plan -var=&#34;admin_password=SenhaSegura123!&#34; # Aplicar terraform apply -var=&#34;admin_password=SenhaSegura123!&#34; # Testar os endpoints (após ~5 min para provisionamento + cloud-init) curl http://$(terraform output -raw appgw_public_ip)/api/orders curl http://$(terraform output -raw appgw_public_ip)/api/inventory curl http://$(terraform output -raw appgw_public_ip)/health Executando múltiplas requisições, o campo server no JSON alterna entre vm-backend-1, vm-backend-2 e vm-backend-3 — confirmando que o round-robin distribui o tráfego entre os backends.
# Verificar distribuição round-robin for i in $(seq 1 10); do curl -s http://$(terraform output -raw appgw_public_ip)/api/orders | jq .server done Monitoramento e Troubleshooting Verificar health dos backends # Via Azure CLI — mostra o estado de cada backend no pool az network application-gateway show-backend-health \ --resource-group rg-appgw-lab \ --name appgw-lab \ --query &#39;backendAddressPools[].backendHttpSettingsCollection[].servers[]&#39; \ --output table Logs de diagnóstico O Application Gateway gera logs de acesso e performance que podem ser enviados para um Log Analytics Workspace:
# Habilitar diagnostic settings az monitor diagnostic-settings create \ --name appgw-diagnostics \ --resource $(az network application-gateway show -g rg-appgw-lab -n appgw-lab --query id -o tsv) \ --workspace $(az monitor log-analytics workspace show -g rg-appgw-lab -n law-appgw-lab --query id -o tsv) \ --logs &#39;[{&#34;category&#34;:&#34;ApplicationGatewayAccessLog&#34;,&#34;enabled&#34;:true},{&#34;category&#34;:&#34;ApplicationGatewayPerformanceLog&#34;,&#34;enabled&#34;:true}]&#39; Problemas comuns Sintoma Causa provável Solução Gateway health: Unhealthy Falta da regra NSG para portas 65200-65535 Adicionar regra AllowGatewayManager Backend: Unhealthy Health probe falhando (API não está rodando) Verificar systemctl status api-backend na VM HTTP 502 Nenhum backend healthy no pool Verificar NSG da subnet backend e porta 8080 HTTP 504 Backend demora mais que o request_timeout Aumentar timeout no backend_http_settings Para Que Serve no Mercado O Application Gateway é o ponto de entrada padrão para aplicações web e APIs no Azure. Em arquiteturas de microsserviços, ele substitui a necessidade de um reverse proxy (Nginx/HAProxy) gerenciado manualmente, centralizando roteamento, TLS e WAF em um serviço gerenciado com autoscale.
A capacidade de rotear por URL path permite que uma única URL pública (api.empresa.com) distribua tráfego para dezenas de microsserviços diferentes, cada um em seu backend pool — sem que o cliente precise saber quantos serviços existem por trás.
Para times que já usam Terraform, o Application Gateway é um recurso complexo de configurar pela primeira vez (listeners, rules, probes, pools — tudo é interdependente), mas uma vez modularizado como neste lab, fica trivial replicar para novos ambientes.
Conclusão O Application Gateway resolve um problema que o Load Balancer não consegue: rotear tráfego HTTP com inteligência. Se a sua aplicação é web ou API, o gateway oferece roteamento por path, health probes inteligentes, SSL termination e WAF — tudo em um único serviço gerenciado. O Load Balancer continua sendo a escolha certa para tráfego não-HTTP (bancos de dados, protocolos customizados), mas para qualquer coisa que fala HTTP, o Application Gateway é a ferramenta adequada.
Referências Azure Application Gateway — Documentação oficial URL path-based routing overview Application Gateway vs Load Balancer Health probes — Application Gateway WAF on Application Gateway Terraform azurerm_application_gateway Subnet requirements for Application Gateway v2 ]]></content:encoded>
    </item>
  </channel>
</rss>
