Fundamentação Teórica: Map an Existing Custom DNS Name to an App Service
1. Intuição Inicial
Imagine que você criou um negócio e tem um endereço físico: "Rua das Flores, 123, São Paulo". Mas nos seus cartões de visita, você coloca "www.meunegocio.com.br" porque é mais fácil de lembrar e mais profissional. Existe um serviço de redirecionamento que, quando alguém busca pelo seu endereço web, sabe que deve ir para "Rua das Flores, 123".
No Azure, quando você cria um App Service, ele recebe um endereço padrão como meuapp.azurewebsites.net. Funciona, mas não é profissional e não representa sua marca. O DNS (Domain Name System) é o "serviço de redirecionamento" da internet: você configura seu domínio customizado www.minhaempresa.com.br para apontar para o App Service, e então adiciona esse domínio customizado ao App Service para que ele aceite requisições naquele nome.
Mapear um custom DNS name é o processo de fazer esses dois passos: provar ao Azure que você é dono do domínio, e então configurar os registros DNS para apontar para o App Service.
2. Contexto
Por que custom domains importam
Por padrão, todos os App Services têm URLs no formato {nome}.azurewebsites.net. Isso é aceitável para desenvolvimento e testes, mas tem limitações para produção:
- Não representa a identidade da marca
- Muda se o app for renomeado ou recriado
- Usuários desconfiam de URLs não reconhecidas
- SEO (Search Engine Optimization) é prejudicado
- Certificados SSL gratuitos do Azure Managed Certificate não funcionam sem custom domain
Custom domains são pré-requisito para certificados TLS customizados e para qualquer aplicação de produção voltada para usuários externos.
O que depende de custom domains
- Certificados TLS/SSL: o certificado deve ser emitido para o custom domain
- HTTPS: sem custom domain, o HTTPS funciona apenas para
azurewebsites.net - Email e outros serviços: subdomínios do mesmo domínio principal
- SEO e analytics: métricas por domínio
3. Construção dos Conceitos
3.1 Como o DNS funciona (conceitos essenciais)
O DNS é um sistema hierárquico de tradução de nomes. Quando um usuário digita www.ecommerce.com.br no navegador, uma série de consultas acontece:
DNS Autoritativo é o servidor que tem a resposta definitiva para um domínio. É onde você cria os registros (A, CNAME, TXT, etc.) que controlam para onde o domínio aponta.
3.2 Tipos de registros DNS relevantes
CNAME (Canonical Name): aponta um nome para outro nome. www.ecommerce.com.br CNAME para meuapp.azurewebsites.net. O DNS então resolve meuapp.azurewebsites.net para obter o IP final.
A Record: aponta um nome diretamente para um endereço IPv4. ecommerce.com.br A para 40.76.100.1.
TXT Record: texto arbitrário associado a um nome DNS. Usado para verificação de ownership (provar que você controla o domínio).
AAAA Record: igual ao A Record mas para IPv6.
3.3 Limitação crítica do CNAME para domínio raiz (apex/naked domain)
O padrão DNS não permite usar CNAME para o domínio raiz (ecommerce.com.br sem subdomínio). Isso ocorre porque o padrão DNS exige que o domínio raiz tenha registros SOA e NS, e CNAME não pode coexistir com outros registros no mesmo nível.
Para o domínio raiz, as opções são:
- Usar um A Record apontando para o IP do App Service (mas o IP pode mudar)
- Usar ALIAS/ANAME Record (se seu provedor DNS suportar) que funciona como CNAME mas é permitido no apex
- Usar Azure DNS que suporta Alias Records nativamente
- Redirecionar domínio raiz para www no provedor DNS
3.4 O processo de verificação de ownership
O Azure não permite que qualquer pessoa adicione qualquer domínio a um App Service. Antes de adicionar um custom domain, você precisa provar que é o dono do domínio. O Azure oferece dois métodos:
Método CNAME (para subdomínios):
Criar um CNAME record de www.ecommerce.com.br apontando para meuapp.azurewebsites.net. Isso prova ownership porque apenas quem controla o DNS do domínio pode criar esse registro.
Método TXT (recomendado para evitar downtime):
Criar um TXT record em asuid.www.ecommerce.com.br com o valor do Domain Verification ID do App Service. Isso permite verificar ownership sem apontar o tráfego para o App Service ainda (útil para migrações).
O Domain Verification ID é um identificador único do seu App Service que o Azure usa para confirmar que o domínio pertence a você. Ele fica em Portal > App Service > Custom domains > Domain verification ID.
3.5 O processo completo para subdomínios vs. domínio raiz
Para subdomínio (www.ecommerce.com.br):
| Registro | Nome | Tipo | Valor |
|---|---|---|---|
| Verificação | asuid.www | TXT | <domain-verification-id> |
| Mapeamento | www | CNAME | meuapp.azurewebsites.net |
Para domínio raiz (ecommerce.com.br) com Azure DNS:
| Registro | Nome | Tipo | Valor |
|---|---|---|---|
| Verificação | asuid | TXT | <domain-verification-id> |
| Mapeamento | @ | A (Alias) | meuapp.azurewebsites.net |
4. Visão Estrutural
Fluxo completo de mapeamento de custom domain
Como o App Service recebe requisições com custom domain
O header Host da requisição HTTP é o que o Azure usa para rotear para o App Service correto. Múltiplos App Services podem compartilhar o mesmo IP do Azure; o host header distingue para qual app a requisição deve ir.
5. Funcionamento na Prática
TTL (Time to Live) e propagação DNS
Quando você cria ou modifica registros DNS, as mudanças não são imediatas. O TTL de um registro DNS define quantos segundos outros servidores podem fazer cache da resposta. Um TTL de 3600 significa que pode levar até 1 hora para que a mudança se propague globalmente.
Estratégia para migração com mínimo downtime:
- Semanas antes: Reduzir o TTL do registro atual para 60-300 segundos
- No momento da migração: Mudar o registro para o novo destino
- Como o TTL é pequeno, a propagação acontece em minutos em vez de horas
- Após confirmar que funciona: aumentar o TTL de volta para o normal (3600+)
Traffic Manager e Front Door com custom domains
Se o App Service estiver por trás do Azure Traffic Manager ou Azure Front Door, o mapeamento DNS aponta para esses serviços, não diretamente para o App Service:
Com Azure Front Door:
- CNAME
www.ecommerce.com.braponta paraecommerce.azurefd.net - O Front Door roteia para o App Service backend
- Certificados TLS são gerenciados pelo Front Door, não pelo App Service diretamente
Com Traffic Manager:
- CNAME
www.ecommerce.com.braponta paraecommerce.trafficmanager.net - Traffic Manager roteia para o App Service com base em políticas (latência, prioridade, etc.)
Comportamentos não óbvios
O App Service valida o domínio a cada verificação. Quando você tenta adicionar um custom domain, o Azure consulta o DNS naquele momento. Se o registro DNS ainda não propagou (TTL alto), a verificação falha. Isso não é erro: é necessário aguardar propagação.
Tier mínimo para custom domains é Shared (D1). O tier Free (F1) não suporta custom domains. Você precisa de pelo menos o tier Shared para adicionar um custom domain.
Wildcard custom domains requerem certificado wildcard.
Você pode adicionar um custom domain wildcard (*.ecommerce.com.br) ao App Service, mas vai precisar de um certificado wildcard para habilitar HTTPS nele.
Múltiplos custom domains podem apontar para o mesmo App Service.
Um único App Service pode ter dezenas de custom domains. Por exemplo: www.empresa.com.br, empresa.com.br, loja.empresa.com.br, todos podem apontar para o mesmo app.
O domain verification ID é específico por App Service, não por domínio. O mesmo verification ID é usado para verificar qualquer domínio naquele App Service. Se você tem 5 domínios diferentes no mesmo app, o TXT record de cada um usa o mesmo verification ID.
6. Formas de Implementação
Portal do Azure
Quando usar: configuração manual, verificação visual, ambientes de uso único
Passo a passo via portal:
- Portal > App Service > Custom domains
- Copiar o Domain verification ID (mostrado na tela)
- Ir ao seu provedor DNS (GoDaddy, Registro.br, Cloudflare, etc.)
- Criar o TXT record:
asuid.wwwcom valor<domain-verification-id> - Criar o CNAME record:
wwwapontando parameuapp.azurewebsites.net - Aguardar propagação DNS
- Voltar ao portal > + Add custom domain
- Digitar
www.ecommerce.com.br - Clicar em Validate; o portal confirma os registros encontrados
- Se válido: Add custom domain
Azure CLI
# Ver o Domain Verification ID do App Service
az webapp show \
--resource-group "rg-webapp" \
--name "ecommerce-frontend" \
--query "customDomainVerificationId" \
--output tsv
# Listar custom domains existentes
az webapp config hostname list \
--resource-group "rg-webapp" \
--webapp-name "ecommerce-frontend" \
--output table
# Adicionar custom domain ao App Service
# (requer que os registros DNS já estejam configurados e propagados)
az webapp config hostname add \
--resource-group "rg-webapp" \
--webapp-name "ecommerce-frontend" \
--hostname "www.ecommerce.com.br"
# Adicionar domínio raiz (apex domain)
az webapp config hostname add \
--resource-group "rg-webapp" \
--webapp-name "ecommerce-frontend" \
--hostname "ecommerce.com.br"
# Remover custom domain do App Service
az webapp config hostname delete \
--resource-group "rg-webapp" \
--webapp-name "ecommerce-frontend" \
--hostname "www.ecommerce.com.br"
# Verificar se o DNS está configurado corretamente antes de adicionar
# (útil para debug de problemas de propagação)
az webapp show \
--resource-group "rg-webapp" \
--name "ecommerce-frontend" \
--query "outboundIpAddresses" \
--output tsv
# Verificar IPs de saída (para criar A records corretos)
az webapp show \
--resource-group "rg-webapp" \
--name "ecommerce-frontend" \
--query "possibleOutboundIpAddresses" \
--output tsv
# Se usando Azure DNS: criar registros diretamente via CLI
# Criar TXT record para verificação
az network dns record-set txt add-record \
--resource-group "rg-dns" \
--zone-name "ecommerce.com.br" \
--record-set-name "asuid.www" \
--value "<domain-verification-id>"
# Criar CNAME record para www
az network dns record-set cname set-record \
--resource-group "rg-dns" \
--zone-name "ecommerce.com.br" \
--record-set-name "www" \
--cname "ecommerce-frontend.azurewebsites.net" \
--ttl 300
# Criar Alias record (ANAME) para apex domain via Azure DNS
az network dns record-set a create \
--resource-group "rg-dns" \
--zone-name "ecommerce.com.br" \
--name "@" \
--target-resource "/subscriptions/<sub-id>/resourceGroups/rg-webapp/providers/Microsoft.Web/sites/ecommerce-frontend"
# Criar TXT de verificação para apex domain
az network dns record-set txt add-record \
--resource-group "rg-dns" \
--zone-name "ecommerce.com.br" \
--record-set-name "asuid" \
--value "<domain-verification-id>"
Azure PowerShell
# Ver Domain Verification ID
(Get-AzWebApp -ResourceGroupName "rg-webapp" -Name "ecommerce-frontend").CustomDomainVerificationId
# Adicionar custom domain
New-AzWebAppCustomHostnameBinding `
-ResourceGroupName "rg-webapp" `
-WebAppName "ecommerce-frontend" `
-Hostname "www.ecommerce.com.br"
# Listar custom domains
Get-AzWebAppCustomHostnameSsl `
-ResourceGroupName "rg-webapp" `
-WebAppName "ecommerce-frontend"
# Se usando Azure DNS: criar registros
# TXT record para verificação
$txtRecord = New-AzDnsRecordConfig -Value "<domain-verification-id>"
New-AzDnsRecordSet `
-ResourceGroupName "rg-dns" `
-ZoneName "ecommerce.com.br" `
-Name "asuid.www" `
-RecordType TXT `
-Ttl 300 `
-DnsRecords $txtRecord
# CNAME record para www
$cnameRecord = New-AzDnsRecordConfig -Cname "ecommerce-frontend.azurewebsites.net"
New-AzDnsRecordSet `
-ResourceGroupName "rg-dns" `
-ZoneName "ecommerce.com.br" `
-Name "www" `
-RecordType CNAME `
-Ttl 300 `
-DnsRecords $cnameRecord
Bicep com Azure DNS
// Azure DNS Zone (se gerenciando DNS no Azure)
resource dnsZone 'Microsoft.Network/dnsZones@2018-05-01' = {
name: 'ecommerce.com.br'
location: 'global'
}
// TXT record para verificação (www)
resource txtVerification 'Microsoft.Network/dnsZones/TXT@2018-05-01' = {
parent: dnsZone
name: 'asuid.www'
properties: {
TTL: 300
TXTRecords: [
{
value: [webApp.properties.customDomainVerificationId]
}
]
}
}
// CNAME record para www
resource cnameWww 'Microsoft.Network/dnsZones/CNAME@2018-05-01' = {
parent: dnsZone
name: 'www'
properties: {
TTL: 300
CNAMERecord: {
cname: '${webApp.name}.azurewebsites.net'
}
}
}
// Alias record para apex domain (@ record)
resource aliasApex 'Microsoft.Network/dnsZones/A@2018-05-01' = {
parent: dnsZone
name: '@'
properties: {
TTL: 300
targetResource: {
id: webApp.id // Alias apontando para o App Service
}
}
}
// Adicionar custom domain ao App Service
resource customHostname 'Microsoft.Web/sites/hostNameBindings@2022-09-01' = {
parent: webApp
name: 'www.ecommerce.com.br'
properties: {
siteName: webApp.name
hostNameType: 'Verified'
}
dependsOn: [cnameWww, txtVerification]
}
7. Controle e Segurança
Verificar propagação DNS antes de adicionar o domain
# Verificar se CNAME está propagado (de múltiplas perspectivas)
# Via Linux/Mac:
dig CNAME www.ecommerce.com.br
# Via Windows:
nslookup -type=CNAME www.ecommerce.com.br
# Via ferramenta online: https://dnschecker.org ou https://whatsmydns.net
# Verificar se TXT de verificação está propagado
dig TXT asuid.www.ecommerce.com.br
# Verificar resolução do app diretamente
dig A ecommerce-frontend.azurewebsites.net
Evitar domínio takeover
Domain takeover é quando alguém cria um App Service e mapeia um domínio que aponta para um App Service deletado. Se www.empresa.com.br tem CNAME para empresa.azurewebsites.net e o App Service empresa é deletado, qualquer pessoa pode criar um novo App Service com o nome empresa e receber o tráfego do domínio da empresa.
Proteção: sempre remova os registros DNS antes ou junto com a deleção do App Service. Nunca deixe registros CNAME apontando para App Services que não existem mais.
# Ao deletar um app: primeiro verificar e remover custom domains
az webapp config hostname list \
--resource-group "rg-webapp" \
--webapp-name "ecommerce-frontend" \
--output table
# Remover cada custom domain antes de deletar o app
az webapp config hostname delete \
--resource-group "rg-webapp" \
--webapp-name "ecommerce-frontend" \
--hostname "www.ecommerce.com.br"
8. Tomada de Decisão
Escolha do método de verificação
| Situação | Método | Motivo |
|---|---|---|
| Novo domínio, app novo | CNAME (www) + TXT | Um CNAME já verifica e redireciona |
| Migração com zero downtime | TXT apenas (primeiro) | Verifica sem redirecionar tráfego ainda |
| Domínio raiz (apex) | TXT + A ou ALIAS | CNAME não é permitido no apex |
| Wildcard | TXT em asuid + CNAME wildcard | Wildcard CNAME cobre todos os subdomínios |
Gerenciador DNS: Azure DNS vs. Registrador externo
| Critério | Azure DNS | Registrador Externo (GoDaddy, Cloudflare) |
|---|---|---|
| Integração nativa com App Service | Alias Records nativo | Precisa de A record manual |
| Gerenciamento centralizado | Sim, tudo no Azure | DNS separado |
| Propagação | DNS global, TTL padrão 3600 | Depende do provedor |
| Suporte a Apex com CNAME-like | Sim (Alias Records) | Depende: Cloudflare sim, GoDaddy não |
| Custo | ~$0.50/zona + $0.40/milhão queries | Geralmente incluído no registro |
| Recomendação | Recomendado se possível | Use se domínio já está lá e funciona |
9. Boas Práticas
Sempre use o método TXT para verificação em migrações. O método TXT verifica ownership sem alterar para onde o tráfego vai. Isso permite: verificar o domínio no App Service destino, configurar o certificado TLS, testar via hosts file local, e só então mudar o CNAME para redirecionar o tráfego de produção.
Reduza o TTL antes de migrações. Um TTL de 3600 significa propagação de até 1 hora. Semanas antes da migração, reduza para 60-300 segundos. Depois de confirmar que funciona, volte para 3600.
Use Azure DNS para aproveitamento dos Alias Records. Azure DNS suporta Alias Records nativamente para Azure resources, incluindo App Service. Isso resolve o problema do apex domain sem precisar de IPs estáticos.
Documente todos os custom domains e seus registros DNS. Quando um app é migrado ou deletado, é fácil esquecer de remover registros DNS. Mantenha um inventário: qual domínio, qual CNAME/A Record, qual App Service, data de criação.
Configure alerta para respostas DNS anômalas. Azure Monitor pode alertar quando um custom domain começa a retornar erros (NXDOMAIN, SERVFAIL), o que pode indicar expiração de domínio, alteração acidental de DNS, ou domain takeover.
10. Erros Comuns
| Erro | Por que acontece | Como evitar |
|---|---|---|
| Verificação falha mesmo após configurar DNS | Propagação DNS ainda não completou | Aguardar propagação; verificar TTL atual; usar dig/nslookup |
| CNAME criado para apex domain sem funcionar | RFC DNS não permite CNAME no apex | Usar Azure DNS com Alias Records ou A record com IP estático |
| App Service deletado mas CNAME ainda existe | DNS não atualizado após deleção | Remover custom domain do app ANTES de deletar; atualizar DNS |
| Tier Free sem suporte a custom domain | Limitação do tier Free | Usar mínimo Shared (D1) para custom domains |
| Domain Verification ID errado no TXT | Cópia incorreta do ID | Copiar o ID diretamente do portal, sem espaços |
| TXT criado em nome errado | asuid.www vs asuid | Para www: asuid.www; para apex: asuid sem subdomínio |
| App acessível em azurewebsites.net mas não no custom domain | Binding não criado no App Service | Após configurar DNS, também adicionar o domain via CLI/portal |
O erro mais comum em produção
Fazer a migração sem reduzir o TTL antecipadamente. Com TTL de 3600, após mudar o CNAME para apontar para o novo App Service, parte dos usuários continua sendo enviada para o servidor antigo por até uma hora. Em e-commerce, isso significa pedidos perdidos e experiência degradada. Sempre reduza o TTL para 60 segundos pelo menos 48 horas antes de qualquer migração de domínio.
11. Operação e Manutenção
Verificar status de todos os custom domains
# Listar todos os apps com seus custom domains
az graph query -q "
Resources
| where type == 'microsoft.web/sites'
| mv-expand hostNames = properties.hostNames
| where hostNames !endswith 'azurewebsites.net'
| where hostNames !endswith 'scm.azurewebsites.net'
| project AppName=name, RG=resourceGroup, CustomDomain=hostNames"
# Verificar se um domínio está corretamente mapeado
DOMAIN="www.ecommerce.com.br"
EXPECTED_CNAME="ecommerce-frontend.azurewebsites.net"
ACTUAL=$(dig CNAME "$DOMAIN" +short)
if [ "$ACTUAL" = "${EXPECTED_CNAME}." ]; then
echo "DNS OK: $DOMAIN -> $ACTUAL"
else
echo "ALERTA: DNS divergente para $DOMAIN. Esperado: $EXPECTED_CNAME, Atual: $ACTUAL"
fi
Renovação de domínio e monitoramento de expiração
Custom domains dependem de que o registro do domínio esteja ativo. Se o domínio expirar no registrador, todos os custom domains associados param de funcionar.
Configure alertas no seu registrador para renovação automática e mantenha os dados de pagamento atualizados. A expiração de um domínio é uma das falhas mais catastróficas e ao mesmo tempo mais evitáveis.
12. Integração e Automação
Provisionamento automático de DNS + custom domain via pipeline
# Azure DevOps: criar DNS records e custom domain como parte do deploy
steps:
- task: AzureCLI@2
displayName: 'Configurar DNS e Custom Domain'
inputs:
azureSubscription: 'prod-subscription'
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
APP_NAME="ecommerce-frontend"
RESOURCE_GROUP="rg-webapp"
DNS_ZONE="ecommerce.com.br"
DNS_RG="rg-dns"
SUBDOMAIN="www"
# Obter Domain Verification ID
VERIFICATION_ID=$(az webapp show \
--resource-group "$RESOURCE_GROUP" \
--name "$APP_NAME" \
--query "customDomainVerificationId" -o tsv)
# Criar TXT record para verificação
az network dns record-set txt add-record \
--resource-group "$DNS_RG" \
--zone-name "$DNS_ZONE" \
--record-set-name "asuid.${SUBDOMAIN}" \
--value "$VERIFICATION_ID"
# Criar CNAME record
az network dns record-set cname set-record \
--resource-group "$DNS_RG" \
--zone-name "$DNS_ZONE" \
--record-set-name "$SUBDOMAIN" \
--cname "${APP_NAME}.azurewebsites.net" \
--ttl 300
# Aguardar propagação (em ambiente automatizado, pode ser necessário retry)
sleep 60
# Adicionar custom domain ao App Service
az webapp config hostname add \
--resource-group "$RESOURCE_GROUP" \
--webapp-name "$APP_NAME" \
--hostname "${SUBDOMAIN}.${DNS_ZONE}"
echo "Custom domain ${SUBDOMAIN}.${DNS_ZONE} configurado com sucesso"
Terraform para DNS + custom domain
# Azure DNS Zone
resource "azurerm_dns_zone" "main" {
name = "ecommerce.com.br"
resource_group_name = azurerm_resource_group.dns.name
}
# TXT record para verificação
resource "azurerm_dns_txt_record" "verification" {
name = "asuid.www"
zone_name = azurerm_dns_zone.main.name
resource_group_name = azurerm_resource_group.dns.name
ttl = 300
record {
value = azurerm_linux_web_app.main.custom_domain_verification_id
}
}
# CNAME record
resource "azurerm_dns_cname_record" "www" {
name = "www"
zone_name = azurerm_dns_zone.main.name
resource_group_name = azurerm_resource_group.dns.name
ttl = 300
record = "${azurerm_linux_web_app.main.name}.azurewebsites.net"
}
# Custom domain no App Service
resource "azurerm_app_service_custom_hostname_binding" "www" {
hostname = "www.ecommerce.com.br"
app_service_name = azurerm_linux_web_app.main.name
resource_group_name = azurerm_resource_group.app.name
depends_on = [
azurerm_dns_txt_record.verification,
azurerm_dns_cname_record.www
]
}
13. Resumo Final
Pontos essenciais:
- Mapear um custom domain envolve dois passos: configurar registros DNS no provedor, e adicionar o domínio ao App Service
- O Azure exige verificação de ownership via TXT record (
asuid.{subdominio}) antes de aceitar o custom domain - Para subdomínios: use CNAME apontando para
{appname}.azurewebsites.net - Para domínio raiz (apex): CNAME não é permitido pelo padrão DNS; use A record com IP do App Service, ou Alias Record se o provedor DNS suportar (Azure DNS suporta nativamente)
- Custom domains requerem tier mínimo Shared (D1); tier Free (F1) não suporta
Diferenças críticas:
- CNAME vs. A Record: CNAME resolve dinamicamente para o IP atual do App Service (recomendado para subdomínios); A Record precisa ser atualizado manualmente se o IP mudar
- CNAME vs. Alias/ANAME: CNAME não é permitido no apex; Alias/ANAME resolve como CNAME mas é permitido no apex (específico por provedor DNS)
- Método CNAME vs. TXT para verificação: CNAME como verificação já redireciona tráfego; TXT verifica sem redirecionar (ideal para migrações)
- TTL 300 vs. TTL 3600: TTL baixo permite migração rápida; TTL alto significa propagação lenta
O que precisa ser lembrado para o AZ-104:
- O Domain Verification ID está em Portal > App Service > Custom domains
- O TXT record de verificação para
www.domain.comé criado emasuid.www(não emwww) - Para apex domain
domain.com, o TXT record vai emasuid(sem subdomínio) - Comando CLI para adicionar:
az webapp config hostname add --hostname <dominio> - Tier Free não suporta custom domains; mínimo é Shared
- Propagação DNS pode levar até o valor do TTL em segundos; para debug, use
digounslookup - Domain takeover acontece quando CNAME aponta para App Service deletado; sempre remova o DNS ao deletar apps