As DevOps continues to blur the lines between traditional IT operations and development, platforms and tools are rapidly evolving to embrace the new paradigm. While the use of containers explodes throughout global enterprises, another technology has been rapidly gaining momentum. On Amazon AWS it’s referred to as AWS Lambda, on Azure its name is Azure Functions, and in the Node.js world a popular option is webtask.io.

The technology is referred to as “serverless” and is the ultimate abstraction of concerns like scale, elasticity, and resiliency that empowers the developer to focus on one thing: code. It’s often easier to understand when you see it in action, so this post will focus on creating a completely functional Angular app with absolutely no provisioning of servers.

To follow along you’ll need an Azure subscription. If you don’t have one there is a free $200 credit available (in the U.S.) as of when I wrote this article. After you have your account, create a new resource group and give it a name. This example uses “ServerlessAngular.”

A resource group is simply a container for related resources. Groups make it easy to see an aggregate cost of services, they can be created and destroyed in a single step, and are a common security boundary in the Azure world. Once the resource group is provisioned, add a resource to it. Use the add button, type “function” in the search box and choose “Function App.”

Now you can pick what the name of your function app is, choose the subscription it will bill against, assign it to a resource group, pick a location, and associate it with a storage account. Here are some of the options I chose to create the app with the name “angularsvc.”

Function apps need storage, so tap the “Storage Account” option and use an existing account or create a new one. In this example, I create one called “angularsvcstorage” to make it clear what the storage is for.

After you hit the create button, it may take a few seconds to several minutes to provision the assets for the function app. These include a service plan for the app, the storage, and the app itself. After everything is created, click on the function app itself to begin coding.

There are a few starter examples to choose from, but for this demo, you’ll select, “Create your own custom function.” You can choose a language, scenario, and template to start with. I picked “JavaScript” for “Core” and selected “HttpTrigger-JavaScript.”

A function app may have multiple functions. For this example, we’ll name the function “xIterate” and open it for anonymous consumption.

The app I’m using for this example is based on an Angular and TypeScript workshop I gave at DevNexus. The module “55-Docker” contains a sample app with an Angular project and a Node.js service that I adapted from containers for this serverless example. The app generates a bifurcation diagram. Here is the code for the function:

Next, edit the iterations.service.ts file to implement the service. Use the function URL you created earlier. The service generates several values for “r,” calls the API to get the “x” iteration values, then publishes them as tuples back to the subscriber. Be sure to update the URL for the service to match your own.

You’ll see the app loads but then nothing happens. If you open the console, it will be riddled with errors like this:

The problem is that Cross-Origin Resource Sharing (CORS) hasn’t been configured for the function, so for security reasons, the browser is blocking requests to the Azure app function from the localhost domain. To fix this, open the function app back up in the Azure Portal, tap “Function app settings” in the lower left and choose “Configure CORS.”

Add http://localhost:4200 to the list of allowed domains, save it, then refresh your browser. If all goes well, you should see something like this:

That’s great – now you have a serverless API, but what about the website itself? Fortunately, the Angular app itself is completely clientside so it can be exported as a static site. Let’s configure Azure Blob Storage to host the website assets. Add a new resource to the existing resource group. Search for “blob” and choose the “Storage account” option.

Give it a name like “ngweb,” choose “Standard,” pick a replication level (I chose the default), and pick a region.

Once this storage is provisioned, tap on “Blobs” for the blob service. The blob service is segmented into named containers, so create a container to host the assets. I named mine “bifurc” for the app. The access type is “Blob.”

After the container is provisioned, you can choose “container properties” to get the URL of the container. Copy that down. In your Angular project, generate an optimized production build:

ng build --prod --aot

This will build the static assets for your application in the “dist” folder. Open dist/index.html and edit the file to update the base URL. This should point to your container (the final slash is important):

<base href="https://ngweb.blob.core.windows.net/bifurc/">

Back in the Azure portal, the container provides an “upload” option to upload assets. Upload all of the files in “dist” as “block blob” until your container looks something like this:

You can either navigate to the container URL you saved earlier or click on index.html and copy its URL. You should see the app try to load, but it will fail. CORS strikes again! Head back over to the function service and add the blob storage domain (just the domain, the path is not necessary) to the list of allowed servers. For this example, I added https://ngweb.blob.core.windows.net/.

Eureka!

At this point, you should have a working application. If you want to host this for production and give it a more user-friendly name, you can use a CNAME entry in DNS to point a custom domain name to blob storage.

Of course, this demonstration only scratched the surface of what is possible. You can build authentication and authorization into Azure Functions, securely store secrets like database credentials, trigger functions based on resource changes (such as running one when a SQL table is updated or a file is uploaded into blob storage) and much more.

In just minutes developers can now provision a highly elastic, scalable, and resilient web application without having to worry about how it is load-balanced. Your boss will give you extra points for saving cash because the functions and blobs are charged based on usage – no more ongoing costs to keep a VM running when it isn’t being used. All of these resources support deployment from a continuous deployment pipeline and in Azure you can create an automation script to generate a template for building out multiple environments like Dev, QA, Staging, and Production.