From Azure Front Door Back to Zero Cost – Migrating a Hexo Blog to Azure Static Web Apps

2026-02-04
From Azure Front Door Back to Zero Cost – Migrating a Hexo Blog to Azure Static Web Apps

TL;DR

Azure CDN (Classic) was retired, Azure Front Door took its place, and a previously cheap static blog
started generating 30€+ per month.

This article describes how a Hexo-based static blog was migrated from Azure Storage + Front Door to Azure Static Web Apps (Free Tier) — including GitHub Actions, custom domain, redirects, and a custom 404 page — ending up with zero ongoing hosting cost again.

Background

This article builds on two earlier posts:

The original setup was:

That setup worked reliably for a long time and is not repeated here in detail.

The Problem: Azure CDN Retirement → Front Door → Cost Explosion

When Azure CDN (Classic) was deprecated, Azure offered an automatic migration to Azure Front Door.

Functionally, the migration was transparent:

Financially, it was not.

Azure Front Door is a powerful enterprise product (global routing, WAF, rules engine), but for a personal site it is massive overkill. After noticing invoices of 30€+ per month, it became clear that this setup was no longer acceptable, at least not for my humble purposes.

So, the goal was

Host a static Hexo blog on Azure with custom domain and HTTPS for zero ongoing cost.

Target Architecture

graph LR
User[Browser] --> SWA["Azure Static Web Apps - Free Tier"]
SWA --> CDN["Global CDN - included"]

What should disappear entirely:

Why Azure Static Web Apps

Azure Static Web Apps (SWA) fits this use case particularly well:

No separate CDN.
No Front Door.
No certificate management.
No billing surprises.

Migration Strategy

The most important design decision was simple:

Change as little as possible in the existing workflow.

The Hexo build already worked perfectly.
Only the deployment target needed to change.

Step 1: Create an Azure Static Web App (Free)

In the Azure Portal, create a new Static Web App:

Step 2: Adjust the GitHub Action (Hexo + SWA)

Hexo already produces static output in the public/ directory.
There is no reason to let Azure rebuild anything.

Key changes:

1
2
3
4
5
6
7
8
9
- name: Deploy to Azure Static Web Apps
uses: Azure/static-web-apps-deploy@v1
with:
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN }}
repo_token: ${{ secrets.GITHUB_TOKEN }}
action: "upload"
skip_app_build: true
app_location: "public"
output_location: ""

Step 3: Custom Domain (blog.example.dev)

The blog is served from a subdomain:

blog.example.dev

Azure provides a CNAME target:

1
CNAME  blog  <random>.azurestaticapps.net

Step 4: Custom 404 Page

Azure Static Web Apps supports custom error handling via staticwebapp.config.json. The file needs to live in the projects root.

1
2
3
4
5
6
7
{
"responseOverrides": {
"404": {
"rewrite": "/404.html"
}
}
}

Cleanup: Removing Front Door

Done by a simple delete of all obsolete elements in the Azure Resource Group. The only remaining element is the Static Web App.

Lessons Learned

  1. Azure Front Door is not a CDN replacement.
  2. Static Web Apps should be the default for static sites.
  3. Registrar-level redirects are often the cleanest solution.
  4. Automatic migrations can have financial side effects.

Conclusion

Replacing Azure Front Door with Azure Static Web Apps reduced complexity, removed operational overhead, and brought hosting costs back to zero.
And don’t get me wrong, this is not a rant, but I would have preferred to get warned about upcoming costs of an automatic migration.