This chapter covers static website hosting on Azure Blob Storage, a feature that allows you to host a static website directly from a storage account without needing a web server. For the AZ-104 exam, this topic appears in the Storage domain (objective 2.2) and typically accounts for 5-10% of questions related to storage features. Understanding this feature is critical because it provides a cost-effective, scalable solution for hosting static content, and the exam tests both configuration steps and integration with Azure CDN and custom domains.
Jump to a section
Imagine you own a store and want to display a menu outside. Instead of hiring a chef to cook the menu fresh each time, you print a static poster and hang it in a glass case. Customers walk by, see the same poster, and read it. The poster never changes unless you replace it manually. In Azure Blob static website hosting, your 'poster' is a set of static files (HTML, CSS, JS, images) stored in a special container. Azure's storage service acts like the glass case: it serves the files directly to visitors via HTTP, without any server-side processing. The 'glass case' is actually a web endpoint generated by Azure, and the 'poster' is your index document (like index.html). When a customer requests your site, Azure looks in the container, finds the file, and returns it. There's no application server, no database, no dynamic code—just raw files served as-is. This is perfect for scenarios where content doesn't change per user, like a company's public landing page or documentation site. The key mechanism: Azure Storage's HTTP server reads the blob container and serves files with correct MIME types, caching headers, and error documents. The 'glass case' has a built-in rule: if a request doesn't specify a file, it serves the index document; if a file is missing, it serves the custom 404 page. This analogy breaks down for dynamic features like query strings—Azure Static Website doesn't support server-side processing of query strings, but it does support client-side routing via a custom error document trick.
What is Static Website Hosting on Azure Blob?
Static website hosting on Azure Blob Storage enables you to serve static content (HTML, CSS, JavaScript, images, fonts, etc.) directly from a storage container via HTTP. The content is served as-is, with no server-side processing. This is ideal for sites that don't require dynamic content generation, such as landing pages, documentation, or single-page applications (SPAs) that rely on client-side JavaScript.
Why It Exists
Traditional web hosting requires a web server (IIS, Apache, Nginx) to process requests and serve files. For static content, this overhead is unnecessary. Azure Blob static website hosting eliminates the need for a server, reducing cost and complexity. It leverages Azure's highly durable and scalable storage infrastructure, providing built-in redundancy and global reach. The feature was introduced to offer a simple, serverless option for hosting static sites, often used in conjunction with Azure CDN for low-latency access.
How It Works Internally
When you enable static website hosting on a storage account, Azure creates two special containers: $web (for content) and $logs (for optional logging). The $web container is the root of your website. Any file you upload to $web becomes accessible via the generated URL: https://<storage-account-name>.z13.web.core.windows.net. The URL format differs based on region and endpoint type (Azure global vs. national clouds).
Azure Storage uses a front-end layer that intercepts HTTP requests to the static website endpoint. This layer maps the request path to a blob in $web. For example, a request to /index.html retrieves the blob named index.html from $web. The storage service automatically sets the correct Content-Type header based on the file extension (e.g., .html -> text/html, .css -> text/css). It also supports caching headers via the blob's Cache-Control property.
Key Components and Defaults
Index Document Name: Default is index.html. You can set a custom name (e.g., default.aspx) but only one index document is supported.
Error Document Path: Custom 404 page, e.g., 404.html. This is a single file that serves all HTTP errors (not just 404). For SPAs, you can set the error document to index.html to enable client-side routing.
Endpoint URL: Two endpoints are generated: primary and secondary (if RA-GRS is enabled). The format is: https://<account>.z<region-code>.web.core.windows.net. For example, West US 2 uses z2, West US uses z13.
Redundancy: Supports LRS, GRS, RA-GRS, and ZRS. GRS provides a secondary endpoint that is read-only for static website (same as blobs).
Custom Domain: You can map a custom domain (e.g., www.example.com) to the static website endpoint. Requires a CNAME record. HTTPS is not supported directly on the static website endpoint; you must use Azure CDN or Azure Front Door for HTTPS.
Authentication: Static website hosting is always public (anonymous access). You cannot restrict access using SAS tokens or RBAC; the content is world-readable. If you need private content, use a different approach (e.g., Azure Functions proxy).
Performance: No built-in CDN; for global low latency, integrate with Azure CDN (Standard Microsoft or Standard Verizon).
Limitations: Maximum blob size is 200 GB per file (though not practical for a website). No server-side scripting, no query string processing, no URL rewriting (except via error document trick).
Configuration and Verification
To enable static website hosting via Azure Portal:
1. Navigate to your storage account.
2. Under 'Data Management', click 'Static website'.
3. Set Index document name (e.g., index.html).
4. Set Error document path (e.g., 404.html).
5. Save. The endpoint URL appears.
6. Upload your files to the $web container (visible under 'Containers').
Via Azure CLI:
az storage blob service-properties update --account-name <storage-account-name> --static-website --404-document 404.html --index-document index.htmlTo get the endpoint:
az storage account show --name <storage-account-name> --query "primaryEndpoints.web" --output tsvVia PowerShell:
$StorageAccount = Get-AzStorageAccount -ResourceGroupName <rg> -Name <account>
Set-AzStorageServiceMetricsProperty -Context $StorageAccount.Context -ServiceType Blob -MetricsType Hour
Enable-AzStorageStaticWebsite -Context $StorageAccount.Context -IndexDocument index.html -ErrorDocument404Path 404.htmlInteraction with Related Technologies
Azure CDN: Integrate to add custom domain with HTTPS, DDoS protection, and global caching. The CDN origin is the static website endpoint. Configure caching rules to optimize performance.
Azure Front Door: Provides global load balancing and SSL termination. Use as alternative to CDN.
Azure Functions: Can be used as a proxy to add server-side logic (e.g., form handling) while keeping the static site.
Azure DevOps/GitHub Actions: Automate deployment to $web container via CI/CD pipelines.
Azure Storage Lifecycle Management: Not applicable to $web container directly; you can set rules on the container but it's not typical.
Common Configuration Mistakes
Forgetting to set index document: Without it, requests to root return 404.
Not uploading to `$web`: Files must be in $web container, not a regular blob container.
Using incorrect error document path: Must be a path relative to $web, e.g., 404.html (not /404.html).
Expecting HTTPS on custom domain without CDN: The static website endpoint only supports HTTP. For HTTPS, use Azure CDN or Front Door.
Assuming private access: Content is always public; cannot use SAS or RBAC.
Step-by-Step Mechanism of a Request
Browser sends HTTP GET to https://mystorage.z13.web.core.windows.net/.
Azure DNS resolves the domain to the storage front-end IP.
Front-end receives request, sees no path, uses index document index.html.
Front-end retrieves blob index.html from $web container.
Blob is returned with Content-Type: text/html, and optional cache headers.
Browser renders the page.
If a file is missing (e.g., /oldpage.html), front-end returns the custom error document (e.g., 404.html) with HTTP 404 status.
Enable Static Website Feature
In the Azure Portal, navigate to your storage account's 'Static website' blade. Enter the index document name (e.g., index.html) and error document path (e.g., 404.html). This triggers the creation of the $web container and assigns the web endpoint. The storage account must be a general-purpose v2 (GPv2) or BlobStorage account. The feature cannot be enabled on classic or GPv1 accounts. Once enabled, the endpoint URL is displayed.
Upload Website Files to $web
Upload all static files (HTML, CSS, JS, images) to the $web container. You can use Azure Portal, Azure CLI, PowerShell, or tools like Azure Storage Explorer. The container is hidden from the 'Containers' list by default but visible when you check. Each file becomes a blob. The path in the URL corresponds to the blob path. For example, a file 'css/style.css' in $web is accessible at /css/style.css. Ensure correct MIME types are set automatically by Azure based on extension.
Configure Custom Domain (Optional)
To use a custom domain (e.g., www.example.com), create a CNAME record in your DNS provider pointing to the static website endpoint (e.g., mystorage.z13.web.core.windows.net). Then in Azure Portal, under 'Custom domain' in the storage account, enter the domain name. The feature only supports HTTP; for HTTPS, you must integrate with Azure CDN or Front Door. The CNAME must be verified; Azure will check that the DNS record resolves to the storage endpoint.
Integrate with Azure CDN (Optional for HTTPS)
Create an Azure CDN profile and endpoint. Set the origin type to 'Custom origin' and enter the static website endpoint URL (without trailing slash). Enable HTTPS on the CDN endpoint. This provides SSL termination, DDoS protection, and global caching. The CDN endpoint becomes the public URL. You can also map your custom domain to the CDN endpoint. Caching rules can be configured to control TTL and query string caching.
Test and Verify the Website
Access the static website endpoint URL in a browser. Verify that the index page loads. Test a missing page to ensure the custom 404 page appears. Check HTTP response headers (e.g., Content-Type, Cache-Control). If using CDN, test the CDN URL. Also test custom domain if configured. Use tools like curl or browser developer tools to verify. For example: curl -I https://mystorage.z13.web.core.windows.net/ should return 200 with correct headers.
Enterprise Scenario 1: Company Landing Page
A multinational corporation needs a low-cost, highly available landing page for a product launch. The page is static HTML with CSS and JavaScript for animations. The marketing team updates content quarterly. The solution: Enable static website hosting on a GPv2 storage account with RA-GRS redundancy. Upload files via Azure DevOps pipeline. Integrate with Azure CDN (Standard Microsoft) for global low latency and HTTPS. The CDN is configured with a 24-hour cache TTL. The custom domain (product.example.com) is mapped to the CDN endpoint. This setup handles millions of requests per month at minimal cost (storage + CDN egress). Common misconfiguration: forgetting to set the error document, causing 404 errors for missing pages to return generic Azure error pages instead of branded 404 page. Also, if the CDN is not purged after updates, users may see stale content for up to 24 hours. Solution: Use Azure CDN purge API after each deployment.
Enterprise Scenario 2: Single-Page Application (SPA)
A startup deploys a React SPA for a customer portal. The SPA uses client-side routing (react-router). All routes like /dashboard and /profile must serve index.html so the JavaScript can handle routing. The solution: Enable static website hosting, set index document to index.html, and set error document to index.html. This way, any request that doesn't match a file (e.g., /dashboard) returns index.html with HTTP 200 status. However, this means actual 404 errors (e.g., missing API file) also return 200. To mitigate, the SPA's service worker can check for real 404s. The site is deployed via GitHub Actions to $web. Azure CDN is added for HTTPS. Performance consideration: The CDN caches the index.html for each path, which can cause issues if the SPA builds unique URLs. Solution: Disable query string caching or set a short TTL for HTML files.
Enterprise Scenario 3: Documentation Site
A software company hosts versioned documentation for its product. Each version is a subfolder (e.g., /v1/, /v2/). The static site generator produces HTML files. The solution: Enable static website hosting, upload all version folders to $web. The index document for each folder is index.html. Users access https://docs.example.com/v2/. The site is integrated with Azure CDN for HTTPS. The team uses Azure Storage Lifecycle Management to archive old versions to cool tier after 60 days. However, lifecycle management cannot be applied directly to $web container blobs because the container is hidden. Workaround: Use a separate container for archival and move files programmatically. Common issue: The error document is set to a single 404.html, but users expect version-specific 404 pages. Solution: Use client-side JavaScript to detect missing versions and redirect.
What AZ-104 Tests on Static Website Hosting
The exam objectives under 'Configure storage security' and 'Manage storage accounts' include enabling static website hosting, configuring custom domains, and integrating with CDN. Specific objective codes: 2.2 (Configure blob storage), 2.4 (Configure Azure Files and Azure Blob Storage). Expect 1-3 questions on this topic.
Common Wrong Answers and Why Candidates Choose Them
'Static website hosting requires a web server role.' Candidates confuse this with traditional hosting. Reality: No server needed; Azure Storage serves files directly.
'You can use SAS tokens to restrict access to the static website.' Candidates think they can secure content like blobs. Reality: Static website is always public; SAS is not supported.
'Custom domain supports HTTPS out-of-the-box.' Candidates assume Azure provides HTTPS automatically. Reality: Only HTTP; HTTPS requires CDN or Front Door.
'You can set multiple index documents.' Candidates think they can specify fallback index files. Reality: Only one index document is allowed.
'The error document handles only 404 errors.' Candidates think it's specific. Reality: It serves all HTTP errors (e.g., 403, 500) unless overridden by CDN.
Specific Numbers, Values, and Terms
Endpoint format: https://<account>.z<region-code>.web.core.windows.net
Region codes: z13 for West US, z2 for West US 2, etc. (memorize not required but pattern)
Default index document: index.html
Error document path: relative, e.g., 404.html
Container name: $web
Supported account types: GPv2 and BlobStorage only
Custom domain: requires CNAME record; HTTPS via CDN only
Redundancy: supports LRS, GRS, RA-GRS, ZRS
Maximum file size: 200 GB per blob
Edge Cases and Exceptions
RA-GRS secondary endpoint: The secondary endpoint for static website is read-only and can be used for failover. If the primary region fails, you must manually update DNS to point to the secondary endpoint.
Soft delete: If soft delete is enabled on the storage account, deleted blobs in $web are recoverable. This can cause unexpected 404s if blobs are soft-deleted.
Static website and Azure Data Lake Storage Gen2: Can be enabled on the same account, but the $web container is not hierarchical namespace-aware. Files uploaded via ADLS Gen2 APIs may not be accessible via static website.
CORS: Static website does not support CORS configuration. If you need cross-origin requests, use Azure CDN or Front Door.
How to Eliminate Wrong Answers
If a question mentions 'server-side processing', eliminate static website.
If a question mentions 'private access' or 'authentication', eliminate static website.
If a question mentions 'HTTPS for custom domain', look for CDN integration.
If a question mentions 'multiple index documents', it's wrong.
If a question mentions 'URL rewriting', it's not possible natively (use error document trick for SPAs).
Static website hosting is enabled on GPv2 or BlobStorage accounts only.
The $web container is automatically created; all files must be uploaded there.
Only one index document (e.g., index.html) is supported.
The error document serves all HTTP errors, not just 404.
Custom domain requires a CNAME record; HTTPS requires Azure CDN or Front Door.
Content is always public; no SAS or RBAC authentication.
The endpoint URL format is https://<account>.z<region>.web.core.windows.net.
RA-GRS secondary endpoint is read-only; manual failover needed.
Soft delete can cause missing files; purge CDN after updates.
For SPAs, set error document to index.html to enable client-side routing.
These come up on the exam all the time. Here's how to tell them apart.
Azure Blob Static Website
Cost: Only pay for storage and egress; no compute cost.
Scalability: Automatically scales to massive traffic without configuration.
Features: No server-side code, no authentication, HTTP only (without CDN).
Deployment: Simple file upload to $web container; no build process required.
Limitations: No custom domain HTTPS, no URL rewriting, no CORS support.
Azure App Service (Static Site)
Cost: Pay for App Service plan (compute) even if idle.
Scalability: Manual scaling or auto-scale rules; limited by plan tier.
Features: Supports server-side code, authentication, custom domains with HTTPS (free).
Deployment: Requires code deployment via Git, FTP, or CI/CD; may need build.
Limitations: More complex to configure; can run dynamic code but overkill for static.
Azure Blob Static Website
Endpoint: Directly accessible via web.core.windows.net.
HTTPS: Not supported on custom domain without CDN.
Performance: Limited to single region; latency for global users.
Cost: Storage egress costs; no CDN costs.
Caching: No built-in caching; relies on browser cache.
Azure Storage with CDN
Endpoint: CDN endpoint (e.g., .azureedge.net) with global PoPs.
HTTPS: Supported on custom domain via CDN-managed certificates.
Performance: Low latency worldwide due to edge caching.
Cost: Additional CDN egress costs; but reduces storage egress.
Caching: Configurable caching rules; cache control headers.
Mistake
Static website hosting requires an Azure App Service plan.
Correct
No compute is needed. The feature runs entirely on Azure Storage infrastructure with no additional cost beyond storage and egress.
Mistake
You can use Azure AD authentication to restrict access to the static website.
Correct
The static website endpoint is always publicly accessible. To restrict access, you must use a reverse proxy like Azure CDN with WAF or Azure Front Door with custom rules.
Mistake
The custom domain for static website supports HTTPS automatically.
Correct
The static website endpoint only supports HTTP. HTTPS requires Azure CDN or Azure Front Door. You must configure SSL on the CDN/Front Door.
Mistake
You can set multiple index documents (e.g., index.html, default.html) as fallbacks.
Correct
Only one index document name is allowed. If you need fallback behavior, you must implement it client-side or use a serverless proxy.
Mistake
The error document path can be a full URL or absolute path.
Correct
The error document path must be a relative path from the root of $web, e.g., '404.html' or 'errors/404.html'. It cannot start with '/' or be a full URL.
Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.
In the Azure Portal, go to your storage account, under 'Data Management' select 'Static website'. Set the index document name and error document path, then save. The $web container is created automatically. You can also use Azure CLI: az storage blob service-properties update --account-name <name> --static-website --404-document 404.html --index-document index.html. The account must be GPv2 or BlobStorage.
Directly, no. The static website endpoint only supports HTTP. To use HTTPS with a custom domain, you must integrate with Azure CDN (Standard Microsoft or Verizon) or Azure Front Door. Create a CDN endpoint with origin as the static website URL, enable HTTPS, and map your custom domain to the CDN endpoint.
This usually means the index document is not set or the file is not present in $web. Ensure you have enabled static website hosting with an index document name (e.g., index.html) and that index.html exists in the $web container. Also, verify that the file is uploaded to the root of $web, not a subfolder.
You cannot restrict access directly because the static website endpoint is always public. To add access control, place Azure CDN with WAF (Web Application Firewall) or Azure Front Door in front. You can configure IP whitelisting, geo-filtering, or token authentication at the CDN level.
Yes, but not directly. You can use Azure Functions as a backend API for your static site. The static site makes AJAX calls to the Function's URL. Alternatively, you can use Azure Functions as a proxy to serve the static files, but that defeats the purpose. For serverless integration, consider using Azure Static Web Apps, which combines static hosting with Functions.
The maximum blob size in Azure Storage is 200 GB per blob. However, for a website, files are typically much smaller. Keep in mind that large files will incur higher egress costs and may slow down load times. For large media files, consider using Azure CDN with caching.
Set the error document path to your index.html (e.g., index.html). This way, any request that doesn't match a file (e.g., /dashboard) will return index.html with HTTP 200 status. Your SPA's JavaScript router will then handle the client-side routing. Note that this means actual 404 errors (e.g., missing API file) also return 200, so you may need client-side logic to detect real errors.
You've just covered Static Website Hosting on Azure Blob — now see how well it sticks with free AZ-104 practice questions. Full explanations included, no account needed.
Done with this chapter?