Featured image of post Building a Web App in Azure

Building a Web App in Azure

Discover how to build a cost-effective 3-tier web app using Azure services for hosting, including Static Web Apps and Cosmos DB.

When I first started out with this blog I was looking at various Azure services for hosting. I knew I wanted to use Azure because I use it in my day job and I wanted an opportunity to continue getting more familiar with its different services outside of work.

In an earlier post, Blog Hosting, I explained how I decided to use the Static Web Apps service to host this blog. In the process of looking for a hosting service I found that Azure offers a Free plan for Static Web Apps and this got me wondering, how much of typical 3-tier web app could be built for free, or as close to it as possible, with Azure services?

The Mission

With cost containment as strong driver for building and hosting a web app, I set out to look at what resources would be needed and how much it would cost. The requirements I have on the final solution are that it should:

  • Be free (or as cheap as possible).
  • Be suitable for production workloads.
  • Enjoy a decent level of availability.

By “suitable for production workloads”, this means that any service selected is using a SKU that Microsoft deems suitable for production workloads and is not using any public preview features.

Front End

During the process of hosting my blog I gained some experience with Static Web Apps so this seemed like a reasonable place to start. Looking at the Free plan there’s immediately a problem in that it doesn’t offer an SLA.

Static Web App plans

This means it’s not going to be suitable for a production application, so we’re going to have to stump up some cash and get the Standard plan. Luckily it’s reasonably priced and will cost a little over £7 ($9) per month.

In case there was any doubt, Microsoft even spell it out quite plainly in their documentation:

Free tier is intended for hobby/personal usage and does not come with SLA. It is suitable for those looking to explore Azure Static Web Apps. Standard tier is intended for general purpose production workloads and comes with SLA.

With the Standard plan we can expect an SLA of 99.95% which equates to about 21 mins per month, or 4 hours per year, of downtime.

The other service I considered as a candidate was Azure App Service. App Service offers a Free tier, but that’s not intended for production workloads. For that, we need to go up to at least the Basic tier where costs start at £10 ($13) per month for Linux-based plans, with Windows costing considerably more. For a feature and price comparison of each of the different plans, take a look at the pricing table. As it stands, it looks like Static Web Apps can do what we need it to, and at very budget-friendly price.

API

With Static Web Apps, APIs come in two flavours - Managed or Bring your own. With a managed API you don’t need to manage a separate Azure Functions resource. It’s automatically deployed and managed with the static web app. Managed APIs are available on both the Free and Standard plans but if you upgrade to Standard, you can bring your own API. Bring your own API, and you’re not limited to using Azure Functions, but instead could use API Management, App Service, or Container Apps.

As I don’t have an existing API, I’ll go with the managed API for now. Also, the convenience of not having to manage a separate Function App is appealing, and it comes with some nice features.

Looking at the documentation around the restrictions, Microsoft note that API backends you bring yourself cannot be linked to a Static Web Apps pull request environment.

A Static Web Apps pull request environment is a product of the first class integration that Static Web Apps has with GitHub, where it will deploy your app from a pull request to a preview environment environment for staging. This allows you to review the your changes before promoting to production. It seems like a potentially useful feature, one that I’d rather not lose by not using the managed API.

Database

When it comes to selecting a database, while Azure has several database offerings, my personal preference is usually to use Azure SQL or Cosmos DB. Whether the data I’m working with suits a relational or document model better will be a large part of making the decision.

Having said that, I did stumble across the blog post NoSQL vs. relational: Which database should you use for your app? in which the author makes reference to an announcement of Azure Cosmos DB for PostgreSQL meaning that Cosmos DB can now support both relational and non-relational data.

As we’re just building a proof-of-concept here the choice of database doesn’t matter too much. In the absence of a specific use-case we’ll fall back to using cost as the primary requirement for making a decision here.

If we had a specific use case in which we knew the data requirements, then this guide from Microsoft would have been really helpful:

Database considerations

Azure SQL

Since cost is now our primary concern, I’ll focus on the pricing of each service. Azure SQL has two purchasing models - vCores and Database Transaction Units (DTUs).

Azure SQL purchasing models

The vCore model supports a provisioned tier, where the compute resources are always available, and serverless, where they can be paused during periods of inactivity and brought back when needed. The serverless option is tempting and sounds like it might be cheaper, only paying for compute when needed, but I have read that the startup time after a period of idleness can introduce quite a bit of latency, to the point of causing timeouts and failed database connections.

Under the DTU purchasing model, you purchase a number of DTUs which represents a “blended measure of CPU, memory, reads, and writes”. A DTU bundle contains the compute and storage together in the pricing. This means it can work out cheaper for small-medium size applications, but has the downside that you can’t independently scale compute and storage.

Using the pricing calculator I plugged in some values for Azure SQL to get an idea of cost.

A single database using provisioned compute, for 730 hours (a full month), costs around £350 ($430). A single database using serverless compute, with 5 hours (just an arbitrary figure for illustration) of compute comes in at £7 ($3). So if you don’t need the database to be always available and can tolerate the latency serverless brings then it will be a much cheaper option.

A Single Database on the DTU model, running on the Basic tier (and all other values left as their defaults) comes in at just under £5 ($6) per month, with an SLA of 99.99%. The Basic tier does, however, limit us to 2GB of storage. Once we outgrow that we’ll need to upgrade to the Standard tier with prices starting at £14 ($18) per month.

It’s great to see there’s a lot of flexibility in the purchasing options and that if you’re starting out small, perhaps just testing out an idea, you can keep costs low, knowing that if you need to scale up there’s options for later on.

Cosmos DB

When it comes to cost Cosmos DB has an ace up its sleeve in the form of the free tier. With the free tier the first 1000 RU/s and 25GB of storage are free. The catch: you only get one of these per subscription.

Free tier lasts indefinitely for the lifetime of the account and it comes with all the benefits and features of a regular Azure Cosmos DB account. These benefits include unlimited storage and throughput (RU/s), SLAs, high availability, turnkey global distribution in all Azure regions, and more.

If you haven’t already claimed the free tier on your subscription, you should have the option to apply the discount when you create a Cosmos DB resource. As you can see in the screenshot Microsoft estimates the value of this discount to be about $64 per month, which is a big incentive on a tight budget.

Cosmos DB free tier

This offers an SLA of 99.99% in a single region without availability zones.

SQL vs Cosmos

For this particular project as there’s no specific use case, there’s no wrong choice. Cost is the primary focus here and it’s really hard to ignore the Cosmos DB free tier. For now, we’ll use Cosmos DB.

Database connection

The use of Static Web Apps does add an interesting dimension with its database connection feature. This enables you to connect to the database from the application without writing any server-side code. Based on the Data API Builder, the service provides a REST or GraphQL API straight into your database, saving you from having to write the server-side code you would normally have to write to interact with a database.

The service is currently in public preview so we can’t use it for production workloads right now, but we’ll look at it more detail later to see if it’s feature potentially worth using once it’s generally available.

Identity Management

In this application we’re building we’re going to want users. They are going to want to be able to do all the things users do. Like sign up, verify their email address, sign in and reset their passwords. Azure AD B2C is just the service for this.

In terms of pricing, it’s based on a model of something called the monthly active user (MAU). An MAU is defined as:

A user that authenticates at least once within a given month is counted as one MAU. Customers aren’t charged for a MAU’s subsequent authentications during the month, nor for inactive users. Authentications may include:

  • Active, interactive sign in by the user. For example, sign-up or sign in, self-service password reset, or any type of user flow or custom policy.
  • Passive, non-interactive sign in such as single sign-on (SSO), or any type of token acquisition. For example, authorization code flow, token refresh, or resource owner password credentials flow.

Azure AD B2C offers 50,000 MAUs free every month. This should be more than enough for a small-scale application, before we have to start paying.

It offers an SLA of 99.99%, which is on par with Cosmos DB and slightly better than Static Web Apps.

Gaining support for the usage of Azure AD B2C is another reason for needing to use the Static Web Apps Standard plan. The Free plan only supports Azure AD (now called Entra ID) and GitHub.

Monitoring

We’re going to want to collect logs and other metrics related to the application for analysis to understand more about our users or just for troubleshooting. For this we’re going to be using Application Insights. There’s no charge for the Application Insights resource itself, we’re only billed by the amount of data ingested. For an small application like this it shouldn’t generate too much data, but if we scaled it up, App Insights does support the setting of a daily cap on the amount of data Application Insights will accept, or you can use sampling to reduce the amount of data collected by App Insights.

Conclusion

It does seem that it’s possible to host a 3-tier web application, capable of running a production workload, on a pretty small budget.

Component Azure Service Price
Front End & API Static Web App £7/per app/month
Database Cosmos DB Free
Identity Management Azure AD B2C Free

Of course, those free services are only free while our usage remains within the allowances for each service, which should be sufficient for a small application. If we want to try out an idea we can get it up and running with very little cost, but then if it finds success and grows, we can scale the infrastructure behind it to handle the additional workload.

The overall design of our 3-tier application with a front end, API and database is starting to look something like this:

A design of the solution

Now we’ve got something that vaguely resembles a plan, let’s build.