Hosting Free Website with Serverless backend on Azure Static Web App

If you are looking for a cost-optimised website deployment (or may be a free web hosting) in Azure then this is for you. 

A couple of years ago I found a technique of hosting static Websites in Azure that costs only a Dollar (I call it One Dollar Deployment). This was using Azure Storage’s static website.

In Build 2020, Microsoft announced Azure Static Web App with a Serverless Backend. This was different than my Azure Storage’s static website. It was fully managed and automated using GitHub actions. I was excited about the possibilities of it but wasn’t happy that it supported GitHub actions only for deployment.

After almost a year, Azure Static Web App started supporting Azure DevOps in Public preview. Now Azure Static Web App is Generally Available (GA) for everyone to use. 

Interestingly enough with the Free tier, you can literally host your static website built in any supported languages with a serverless backend completely Free.

In this article, I’m going to guide you on how to build a Static Website with an Azure Function backend. And deploy the code using Azure DevOps. 

Before we jump into the code, let’s see what is new in Azure Static Web App which is not available in the One Dollar Deployment technique.

What’s New

Unlike hosting a static website in Azure Storage (read One Dollar Deployment), in Azure Static Web App, you get many inbuilt goodies. A few of my favorite features are –

  1. The Website is globally distributed and served by CDN — enhanced performance by default
  2. Full support for root domains — you just need to buy a Domin for your site. (Only this is not free)
  3. Free SSL certificate (for your custom Domain also) — modern browsers won’t flag your site as insecure
  4. Serverless Azure function support — build your backend in your favourite language. C#, Node, JavaScript, etc.  

All the above features are available even on the Free tier.

Price Check

You can find the detailed pricing is here

For demonstration purposes, I’m going to host a basic blog-style Angular website. This site will display a list of blog posts on the home page. The blog data, I’m going to fetch from an Azure Function backend. This is nothing fancy I want, so I’m good with the Free tier. 

Note: If you want to host your business-critical website. Then you may want to consider the Standard tier.

Taking the first step

Before we start coding, we have to create an Azure Static Web App first. I’m going to use Azure Portal to create one for simplicity. 

Create a “Static Web App” resource. 

Give a Name for your app. Select Plan Type Free and Select Other as Deployment details. Honestly, I didn’t like that Azure DevOps is now considered under other category 🙁

Once the resource is created, you will see something like below 

It will generate some random URL for your app. I would have liked it to come from the Name I gave in the previous step. Why a random url? 

Observe the location is Global. Since it will be served from a globally distributed CDN, I think this is why it is shown as Global. Observe the Manage deployment token option. We will use it to setup the Azure DevOps setup in a later stage.

After the creation of the Static Web App resource, you won’t see any Azure Function created by default as a part of the resource creation steps.

You will notice a Functions option in the left navigation blade. 

When I clicked Functions. I didn’t see any option to create the Azure Function from here. I was expecting to create the Azure Function from here at least.

Anyways… this is what we have for now. Don’t worry about the Azure Function creation from here now. In the next sections, you will find a way to do so.

Now the basic Azure resource creation is complete, let’s set up the code repository structure and add some code to start with.

Code repository setup

In my Demo app, I need two folders. One for the static website (Angular website) and another folder for the Azure Function code. 

I’m going to use api folder to house my AzureFunction code and WebSite folder to house my Angular Code. 

Don’t bother about the azure-pipelines.yml file now. I will come there shortly.

Adding Code

Prerequisite — I have used Visual Studio Code (VS Code) for this code setup. If you have Angular development setup in your VS Code then you are good. If you do not have the Azure Function extension installed then please go ahead and do so. 

You do not need the Azure Static Website extension for Azure DevOps deployment. Don’t get confused about the documentation. 

You need to login to your Azure and Azure DevOps account from your VS Code. This is required for continuous deployment to Azure DevOps. 

Adding Angular Code

Go to the WebSite folder and start creating your angular code using familiar Angular CLI commands.

I’m not an expert Angular expert, so I cloned this repository and modified it a bit to hook it up with my Azure Function backend.

Once cloned, your code structure in VS Code will look like this –

If you clone my modified repository then, just change the URL in theconfig.json file to point to the Azure Function endpoint. Copy the URL from Azure portal and replace the localhost URL as https://<static site url>/api

Now npm install and dong serve to be sure that the UI code is running. You won’t get blog post data yet. We have to build the Azure Function and deploy it for that.

Adding Azure Function App

For my blog post data, I’m going to create an Azure Function with HttpTrigger and use it as the backend data source. To create a brand-new azure function code, follow the below steps. (Ignore if you are happy with the cloned code)

  1. Open command pallet using the F1 key
  2. Type and Chose Azure Function: Create New Project… 
  3. Now browse the api folder
  4. Select language C# (you can choose any other supported language)
  5. Select runtime — .NET Core 3
  6. Select HttpTrigger as the template
  7. Give a Name and Namespace to your function and select Anonymous and hit enter

This will create your Azure Function code. Your code structure will look like below 

At this time your basic code setup is complete. Next, we have to prepare for Code Deployment using Azure DevOps.

Continuous deployment with Azure DevOps

A build pipeline is needed to deploy the code (Angular + Azure Function together) to the Azure Static Web App resource we have created earlier. 

In Azure DevOps, there is no standard template yet for Static Web App deployment. For now, select the Starter pipeline

Copy the below code and paste it into your pipeline definition file.

trigger:
- main

pool:
  vmImage: ubuntu-latest

steps:
  - checkout: self
    submodules: true
  - task: [email protected]
    inputs:
      app_location: '/WebSite'
      api_location: '/api'
      output_location: 'dist/WebSite'
    env:
      azure_static_web_apps_api_token: $(deployment_token)

app_location is your Angular code path. api_location is your Azure Function code location. output_location is your Angular code build folder

Now we have to connect this pipeline to the Azure Static Web App resource so that the code changes can be pushed. To do so — create a pipeline variable with Name deployment_token. Next copy the Deployment token from the Azure portal and paste it in the Value section.

This will complete your build pipeline setup. This pipeline will run automatically every time you push some changes to the repository.

I would love to have a mechanism to control this behavior, what if I do not want to deploy after every commit?

On a successful run, it will push your Angular Code and Azure Function code to the Static Web App resource.

At the time of writing this article, I have encountered many confusing build error messages. I have opened a GitHub issue for the same.

The Outcome

On successful build of the code repository, it will now create an Azure Function and deploy your Angular code. 

To check your Azure Function, navigate to the Functions from the left navigation blade. You will see your Azure Function here now. 

It doesn’t appear instantly. I had to wait for 5–10 seconds for it to show up. 

In the Free tier, it’s a managed Azure function which is why I think I don’t see any other option here on this page, unlike any other standard Azure Function App. This won’t even create any separate Azure Function resource under your resource group.

I couldn’t find any way to check my static files generated in Angular build on Azure Portal, unlike Azure Storage’s static website.

After the deployment completion, to test the web app just hit the application’s URL.

Testing the app

To see your Azure Function HttpTrigger is returning any data or not? just hit the application URL https//<staticweballurl>/api/StaticWebAppBackend 

If it returns a json response then you are good to go

To test the Angular website just type in or copy-paste the static website URL from Azure Portal. The website should look something like below –

It will start showing data coming from the Azure Function backend which we have used as the backend API.

This completes building and deploying Angular Static Web App with Azure Function backend in Azure Static Web App.

Until this, it’s all free. If you want to configure your own domain name with this website, then you can do so easily. Buy a domain name and follow this article to configure. This will give you a free SSL certified also as a bonus.

Wrap up

In my opinion, this is a great way of deploying a Static website with a Serverless backend in a very cost-effective manner. In fact, freely for many small use cases. 

I understand this is a managed service from Microsoft, and promoting everything as code. However, I would love to see some more granular control for the developers. Such as exploring the static files, Azure function’s storage account, a configuration panel for the Azure Function, etc. in the Azure Portal. For some reason, it still feels like a black box to me ;). I am yet to test this with a production-grade application with advanced authentication scenarios in a Standard pricing tier. Also, would love to see how is everyone in the community is using this offering for their use cases.

I’m happy with the capability it’s bringing to the table. If you are looking to quickly hosting your modern static website with API backend freely, then look no further. Azure Static Web App Free tier is the answer for you.