# App Service Custom Domains and TLS Certificates

> Chapter 100 of the Courseiva AZ-104 curriculum — https://courseiva.com/learn/az-104/app-service-custom-domains

**Official objective:** 3.2 — Compute

## Introduction

For the AZ-104 exam, configuring custom domains and TLS certificates for Azure App Service is a critical skill for securing and branding web applications. On the AZ-104 exam, this topic appears in approximately 5-8% of questions under objective 3.2 (Configure and manage App Service plans and App Service). You need to understand domain validation, DNS record configuration, certificate binding, and the differences between certificate options. Mastery of this topic ensures you can deploy secure, production-ready web apps with custom domains.

## Custom Domains as Office Mailroom Service

Suppose every tenant (web app) in a large office building is assigned a default mailbox number (azurewebsites.net domain). When a tenant wants a custom address like 'Suite100@Building.com' (custom domain), they must first prove they own the building (domain verification). The building's mailroom (Azure Front Door or App Service) then updates its directory (DNS records) to accept mail for that custom address. The mailroom also needs a valid ID badge (TLS certificate) to prove it can securely deliver mail for that address. If the tenant brings their own badge (BYO certificate), the mailroom just scans it and stores a copy. If the tenant wants the mailroom to provide a badge (App Service Managed Certificate), the mailroom automatically applies for one from a trusted ID issuer (DigiCert) and renews it every 6 months. The mailroom will only accept mail for addresses that have both a verified owner and a valid badge. Without the badge, visitors (users) see a security warning. The mailroom also supports multiple tenants sharing the same custom address by using SNI (Server Name Indication), where the visitor announces which tenant they want, and the mailroom shows the correct badge for that tenant.

## Core explanation

### What Are Custom Domains and TLS Certificates?

Azure App Service provides a default domain like `myapp.azurewebsites.net`. However, production applications almost always need a custom domain (e.g., `www.contoso.com`) to present a professional brand and enable TLS. A TLS certificate is required to encrypt traffic between the client and the server over HTTPS. Without a proper certificate, browsers display security warnings, and users may lose trust.

### Domain Verification and Ownership

Before you can use a custom domain with App Service, you must prove you own the domain. Azure supports two types of domain verification:

- **Domain verification ID**: A unique GUID assigned to each App Service app. You create a `TXT` record with the name `asuid.<subdomain>` (e.g., `asuid.www`) and value equal to the verification ID. Azure checks this record to confirm ownership.
- **CNAME record verification**: For subdomains (e.g., `www.contoso.com`), you can also create a `CNAME` record pointing to the default app domain (`myapp.azurewebsites.net`). Azure verifies the CNAME exists. However, this method does not work for apex domains (e.g., `contoso.com`) because CNAME records cannot coexist with other record types at the apex.

### DNS Record Types for Domain Mapping

To route traffic to your App Service, you need to configure DNS records at your domain registrar. The record type depends on the domain:

- **Apex domain** (e.g., `contoso.com`): Use an `A` record pointing to the app's inbound IP address. This IP is static as long as the app is in a Standard or higher App Service plan (shared and basic plans may have dynamic IPs). You must also create a `TXT` record for domain verification.
- **Subdomain** (e.g., `www.contoso.com`): Use a `CNAME` record pointing to `<appname>.azurewebsites.net`. Optionally, you can use an `A` record with the IP address, but CNAME is more common because it handles IP changes automatically.
- **Wildcard domain** (e.g., `*.contoso.com`): Use a `CNAME` record with name `*` pointing to the app's default domain. This is useful for multi-tenant apps where each tenant gets a subdomain.

### TLS/SSL Certificate Binding

Once the custom domain is verified and mapped, you need to bind a TLS certificate to enable HTTPS. Azure App Service supports three types of certificates:

1. **App Service Managed Certificate**: A free, automatically managed certificate issued by DigiCert. It supports only custom domains and wildcard domains, but not apex domains. It is automatically renewed every 6 months. You cannot export the private key.
2. **Azure Key Vault Certificate**: Import a certificate stored in Azure Key Vault. This allows centralized management and rotation. The App Service must have permission to read the secret.
3. **Bring Your Own Certificate (BYO)**: Upload a PFX or PEM certificate purchased from any certificate authority. You manage renewal manually.

### Binding Process

To bind a certificate to a custom domain:

1. Navigate to the App Service in the Azure portal.
2. Under **Settings**, select **TLS/SSL settings**.
3. In the **Private Key Certificates (.pfx)** tab, upload or import the certificate.
4. In the **Custom Domains** tab, add the custom domain and verify ownership.
5. In the **TLS/SSL bindings** tab, select the domain, choose the certificate, and set the TLS/SSL type:
   - **SNI SSL**: Multiple certificates can be bound to the same IP address. The client indicates the hostname during the TLS handshake, and the server presents the correct certificate. This is the default and recommended option. Supported by all modern browsers.
   - **IP-based SSL**: A dedicated IP address is assigned to the app, and the certificate is bound to that IP. This is required for legacy clients that do not support SNI. It incurs additional cost (Standard tier or above) and uses one IP per certificate.

### Certificate Renewal and Rotation

- **Managed certificates**: Renewed automatically 30 days before expiry. You do not need to take any action.
- **Key Vault certificates**: If you enable auto-rotation, App Service will automatically use the latest version from Key Vault. You can also manually sync.
- **BYO certificates**: You must upload a new certificate before expiry and update the binding. The old certificate will continue to work until it expires, but you should update bindings to use the new certificate.

### Interaction with Azure Front Door and Traffic Manager

If you use Azure Front Door or Traffic Manager in front of App Service, the custom domain should be configured at the Front Door/Traffic Manager level, not at the App Service. The App Service only needs to accept traffic from the Front Door/Traffic Manager IP ranges. You typically set the App Service access restrictions to allow only the Front Door/Traffic Manager IPs.

### Commands for Automation

You can use Azure CLI or PowerShell to manage custom domains and certificates:

**Azure CLI Example:**

```bash
# Add a custom domain
az webapp config hostname add --resource-group myResourceGroup --webapp-name myApp --hostname www.contoso.com

# Upload a certificate
az webapp config ssl upload --resource-group myResourceGroup --webapp-name myApp \
  --certificate-file /path/to/certificate.pfx --certificate-password myPassword --name myCertificate

# Bind the certificate
az webapp config ssl bind --resource-group myResourceGroup --webapp-name myApp \
  --certificate-thumbprint <thumbprint> --ssl-type SNI --hostname www.contoso.com
```

**PowerShell Example:**

```powershell
# Add a custom domain
New-AzWebAppCertificate -ResourceGroupName myResourceGroup -WebAppName myApp -HostName www.contoso.com

# Upload certificate
$pfxPath = "C:\path\to\certificate.pfx"
$pfxPassword = ConvertTo-SecureString -String "myPassword" -Force -AsPlainText
New-AzWebAppCertificate -ResourceGroupName myResourceGroup -WebAppName myApp -Path $pfxPath -Password $pfxPassword

# Bind certificate
New-AzWebAppSSLBinding -ResourceGroupName myResourceGroup -WebAppName myApp -CertificateThumbprint "<thumbprint>" -SslState SNI -Name www.contoso.com
```

### Defaults and Limits

- **Number of custom domains**: Up to 500 per App Service (depending on plan tier; Basic and higher support 500, Free and Shared support 5).
- **Certificate quota**: Up to 10 certificates per App Service (Free/Shared), up to 200 per plan (Basic and higher).
- **Managed certificate limitations**: Cannot be used with apex domains, cannot be exported, and only works for domains verified via TXT record.
- **IP-based SSL**: Requires a Standard or higher plan, and each IP-based binding uses a separate IP address (up to 5 IPs per app).

### Troubleshooting Common Issues

- **Domain not verified**: Ensure the TXT record `asuid.<subdomain>` exists with the correct value. DNS propagation can take up to 48 hours.
- **Certificate not showing**: The certificate must be uploaded to the App Service or accessible via Key Vault. Check that the certificate's subject name matches the custom domain.
- **Mixed content warnings**: After enabling HTTPS, ensure all resources (images, scripts) are loaded over HTTPS. Use relative URLs or update to HTTPS.
- **Certificate renewal failure for managed certificates**: The domain must still be verified. If the TXT record was removed, renewal will fail. Keep the verification record in place.

## Real-world context

In a typical enterprise deployment, a company like Contoso hosts its main website (`www.contoso.com`) and a customer portal (`portal.contoso.com`) on Azure App Service. They use a single wildcard certificate `*.contoso.com` purchased from a public CA (e.g., DigiCert) to secure both domains. The certificate is uploaded to the App Service and bound to each domain using SNI SSL. The company also uses Azure Front Door for global load balancing and DDoS protection. In this case, the custom domains are configured at the Front Door level, and the App Service only allows traffic from Front Door's IP ranges via access restrictions. The Front Door terminates TLS and re-encrypts traffic to the App Service using a separate certificate (or the same one).

Another scenario: A SaaS provider offers white-labeled applications where each customer gets a subdomain like `customer1.saasapp.com`. They use an App Service Managed Certificate for the wildcard domain `*.saasapp.com`. The managed certificate is free and auto-renewed, reducing operational overhead. However, they must keep the `asuid.*` TXT record in place for renewal. They also use Azure Traffic Manager to route traffic to different regional App Service instances. The custom domain is configured at Traffic Manager, which then resolves to the App Service's default domain.

A common misconfiguration is using an IP-based SSL binding unnecessarily, which consumes a public IP address and costs extra. For example, a developer might choose IP-based SSL because they think it is required for all certificates, but SNI works with virtually all modern clients. Another issue is forgetting to update the DNS record when the App Service's inbound IP changes (which can happen if the app is scaled down to Free/Shared tier). To avoid this, always use CNAME records for subdomains, which are immune to IP changes. For apex domains, ensure the App Service is on a Standard or higher plan to have a static IP.

Performance considerations: TLS termination at the App Service adds CPU overhead. For high-traffic sites, consider offloading TLS to Azure Front Door or Application Gateway. Certificate renewal can cause brief downtime if not handled correctly. Managed certificates are renewed seamlessly, but BYO certificates require manual intervention. Setting up monitoring alerts for certificate expiry is a best practice.

## Exam focus

The AZ-104 exam tests objective 3.2, which includes configuring custom domains and TLS certificates. Expect 3-5 questions on this subtopic. Key areas:

1. **Domain verification methods**: Know the difference between TXT record verification (required for all domains, especially apex) and CNAME verification (subdomains only). The exam often presents a scenario where a user cannot add an apex domain because they only created a CNAME record. The correct answer is to create a TXT record with `asuid.@` or `asuid.` and the verification ID.

2. **Certificate types and limitations**: 
   - App Service Managed Certificate: Free, auto-renewed, but cannot be used with apex domains. This is a common trick question: "You want to secure contoso.com with a free certificate. What should you do?" The answer is not a managed certificate; you need a BYO or Key Vault certificate. 
   - BYO certificate: Must be PFX with private key included. The password is required during upload.
   - Key Vault certificate: Requires granting App Service access via Managed Identity or access policies. The exam might ask about permissions.

3. **SSL binding types**: SNI vs. IP-based. SNI is the default and works with all modern browsers. IP-based is only needed for legacy clients (e.g., IE on Windows XP). The exam might ask: "You need to support a legacy application that does not support SNI. What should you use?" Answer: IP-based SSL.

4. **Common wrong answers**: 
   - Selecting "App Service Managed Certificate" for an apex domain. 
   - Thinking that a CNAME record at the apex is valid (it is not). 
   - Confusing domain verification with DNS resolution. Verification is separate from traffic routing.
   - Assuming that uploading a certificate automatically binds it to a domain (you must create a binding).

5. **Numbers to memorize**: 
   - Maximum custom domains per app: 500 (Basic and higher), 5 (Free/Shared).
   - Maximum certificates per app: 200 (Basic and higher), 10 (Free/Shared).
   - Managed certificate renewal period: every 6 months.
   - IP-based SSL requires Standard plan or higher.

6. **Edge cases**: 
   - If you delete the verification TXT record, managed certificate renewal will fail. The exam might ask why a certificate expired unexpectedly.
   - If you use a CNAME record for verification, you must keep it for the certificate to renew? Actually, managed certificates require TXT verification; CNAME verification does not suffice for renewal. The exam may test that you need both a TXT record for verification and a separate DNS record for traffic.

To eliminate wrong answers, focus on the mechanism: verification proves ownership; DNS records route traffic; certificates enable HTTPS. Each step is independent but required. If a question says "cannot add custom domain," check if the DNS record type is appropriate for the domain type. If "HTTPS not working," check if the certificate is bound and matches the domain.

## Step by step

1. **Verify Domain Ownership** — In the Azure portal, navigate to your App Service, select 'Custom domains' under Settings, and click 'Add custom domain'. You will see a Domain Verification ID (a GUID). Create a TXT record in your DNS zone with the host as `asuid.<subdomain>` (e.g., `asuid.www`) and the value as the Verification ID. Alternatively, for subdomains, you can create a CNAME record pointing to `<appname>.azurewebsites.net` to verify ownership. Azure will check for the existence of this record. DNS propagation may take a few minutes to several hours. Once Azure detects the record, the domain status changes to 'Approved'.
2. **Configure DNS Record for Traffic** — After verification, you need to configure the DNS record that routes traffic to your App Service. For an apex domain (e.g., `contoso.com`), create an A record pointing to the app's inbound IP address (found in the Custom Domains blade). For a subdomain (e.g., `www.contoso.com`), create a CNAME record pointing to `<appname>.azurewebsites.net`. For a wildcard domain (e.g., `*.contoso.com`), create a CNAME record with name `*`. Ensure the record type matches the domain type. CNAME records cannot be used at the apex. Also, if you used a TXT record for verification, it can remain or be removed after verification, but it's recommended to keep it for managed certificate renewal.
3. **Obtain a TLS Certificate** — Choose one of three certificate options: App Service Managed Certificate (free, auto-renewed, for custom domains only, not apex), Azure Key Vault certificate (imported from Key Vault), or Bring Your Own (upload a PFX/PEM file). For managed certificates, no action is needed—they are created automatically when you enable HTTPS. For BYO, ensure the certificate's subject name matches the custom domain (e.g., `CN=www.contoso.com` or `CN=*.contoso.com`). The certificate must include the full chain (root and intermediate). Upload the certificate in the 'TLS/SSL settings' > 'Private Key Certificates (.pfx)' tab. For Key Vault, import the certificate and grant App Service access via Managed Identity or access policies.
4. **Bind Certificate to Domain** — In the 'TLS/SSL bindings' tab, click 'Add TLS/SSL Binding'. Select the custom domain from the dropdown. Choose the certificate you uploaded or imported. Select the TLS/SSL type: SNI SSL (recommended, allows multiple certificates on the same IP) or IP-based SSL (dedicated IP, needed for legacy clients). IP-based SSL incurs additional cost and uses a separate IP address. Click 'Add Binding'. The binding may take a few minutes to propagate. After binding, the custom domain will serve HTTPS traffic. Verify by browsing to `https://www.contoso.com`.
5. **Verify and Monitor** — After binding, test the HTTPS connection using a browser or `curl -v https://www.contoso.com`. Ensure the certificate is trusted and the domain name matches. Check the certificate details (issuer, expiry date). For managed certificates, monitor renewal status in the Azure portal. If using BYO, set up a reminder to renew before expiry. Also, check for mixed content warnings: use a tool like SSL Labs to scan the site. If you have multiple domains, repeat the binding process for each domain. For wildcard certificates, you can bind the same certificate to multiple subdomains.

## Comparisons

### App Service Managed Certificate vs Bring Your Own Certificate (BYO)

**App Service Managed Certificate:**
- Free of charge
- Automatically renewed every 6 months
- Cannot be exported
- Only for custom domains and wildcard domains (not apex)
- Requires TXT domain verification record to remain for renewal

**Bring Your Own Certificate (BYO):**
- Cost varies by CA (typically $50-$500/year)
- Manual renewal required
- Can be exported and used elsewhere
- Works with any domain including apex
- No dependency on Azure verification records after initial binding

### SNI SSL vs IP-based SSL

**SNI SSL:**
- Multiple certificates on same IP address
- Supported by all modern browsers
- No additional cost
- Default binding type
- Requires client SNI support

**IP-based SSL:**
- Dedicated IP address per certificate
- Required for legacy clients (e.g., IE on XP)
- Additional cost (Standard plan or higher)
- Limited to 5 IP addresses per app
- No client support needed

## Common misconceptions

- **Misconception:** You can use a CNAME record for an apex domain like contoso.com. **Reality:** CNAME records cannot coexist with other record types at the zone apex per RFC 1912. Azure does not allow CNAME at the apex; you must use an A record pointing to the app's IP address.
- **Misconception:** App Service Managed Certificate can be used for any domain, including apex domains. **Reality:** Managed certificates cannot be used for apex domains (e.g., contoso.com). They only support subdomains and wildcard subdomains. For apex, you need a BYO or Key Vault certificate.
- **Misconception:** Uploading a certificate automatically binds it to the custom domain. **Reality:** Uploading only makes the certificate available. You must explicitly create a TLS/SSL binding that associates the certificate with a specific domain.
- **Misconception:** Once domain verification is done, you can remove the TXT record. **Reality:** While verification is a one-time check, removing the TXT record will cause managed certificate renewal to fail. It is recommended to keep the verification record as long as the domain is associated with the app.
- **Misconception:** IP-based SSL is required for all custom domains. **Reality:** IP-based SSL is only needed for legacy clients that do not support SNI. SNI SSL works with all modern browsers and is the default. IP-based incurs extra cost and uses a dedicated IP.

## Key takeaways

- Domain verification is a prerequisite for adding a custom domain; use TXT record with asuid prefix for all domains, or CNAME for subdomains only.
- For apex domains, use an A record pointing to the app's inbound IP; for subdomains, use a CNAME to the app's default domain.
- App Service Managed Certificate is free and auto-renewed but cannot be used for apex domains.
- SNI SSL is the default and recommended binding type; IP-based SSL is only for legacy client compatibility.
- Certificate binding is a separate step from uploading; you must explicitly associate a certificate with a domain.
- Keep the domain verification TXT record in place for managed certificate renewal.
- Maximum custom domains per app: 500 (Basic+), 5 (Free/Shared). Maximum certificates per app: 200 (Basic+), 10 (Free/Shared).
- Azure CLI command to bind certificate: az webapp config ssl bind --certificate-thumbprint <thumbprint> --ssl-type SNI --hostname <domain>.
- Managed certificates are issued by DigiCert and are free, but cannot be exported.
- Key Vault certificates require App Service access via Managed Identity or access policies.

## FAQ

**Can I use an App Service Managed Certificate for contoso.com (apex domain)?**

No. App Service Managed Certificate does not support apex domains. You must use a Bring Your Own certificate or a certificate from Azure Key Vault. Managed certificates only work for subdomains and wildcard subdomains.

**What DNS record should I create for www.contoso.com to point to my App Service?**

Create a CNAME record with name 'www' pointing to <your-app-name>.azurewebsites.net. For the apex contoso.com, you must use an A record pointing to the app's static IP address.

**How do I verify domain ownership for a custom domain?**

In the Azure portal, go to App Service > Custom domains > Add custom domain. You will get a Domain Verification ID. Create a TXT record with host as 'asuid.<subdomain>' (e.g., asuid.www) and value as the verification ID. Alternatively, for subdomains, you can create a CNAME record pointing to the app's default domain.

**What happens if my App Service Managed Certificate fails to renew?**

The most common reason is that the domain verification TXT record (asuid) was removed. Ensure the record still exists. If renewal fails, you can manually trigger renewal by going to the TLS/SSL settings and selecting 'Renew' for the certificate.

**Can I bind multiple certificates to the same custom domain?**

No. Each custom domain can have only one certificate bound at a time. If you bind a new certificate, it replaces the existing one.

**What is the difference between SNI and IP-based SSL?**

SNI SSL allows multiple certificates on the same IP address; the client indicates the hostname during the TLS handshake. IP-based SSL assigns a dedicated IP address to the certificate, which is needed for clients that do not support SNI (e.g., older browsers). SNI is the default and recommended option.

**How do I upload a certificate to App Service using Azure CLI?**

Use the command: az webapp config ssl upload --resource-group <rg> --webapp-name <app> --certificate-file <path> --certificate-password <password> --name <cert-name>. Then bind it with az webapp config ssl bind.

---

Interactive version with quiz and diagrams: https://courseiva.com/learn/az-104/app-service-custom-domains
