Posted December 16th, 2018
This is a tutorial for absolute beginners.
Whether you're a developer or an operations engineer, it’s a good idea to start wrapping your brain around the fundamental concepts of serverless computing. The technology is still in its infancy, but I believe it will radically shift how many applications are built in the years to come.
In this guide, I’ll walk you through setting up a super basic serverless web application on Azure. Just a simple webform that sends and receives data to and from an Azure Function.
The HTML page for this serverless application will be hosted in an Azure Storage account. Users will visit the webpage and submit a message. The form will trigger an Azure Function that will send a message back to the user. There will be no virtual machines involved. Just code. Hence the term serverless ;)
Here's the good news; you don't need to be an experienced programmer to follow along with this tutorial. I'll show you how to build the resources you'll need in Azure, and I'll give you some sample code to try out.
Sound good? Let's go.
We need to build a handful of Azure resources to support both the front-end and the back-end of the application. We’ll create an Azure Storage account, build an Azure Function, and then deploy and test a simple HTML web page.
Yes, we could automate all of this work, but that's a topic for another post. My goal here is to help you grasp the concept of a serverless web app using a simple example with minimal steps.
However, we will use the Azure CLI as much as possible as we build the infrastructure. I'll try to minimize the steps required in the portal since the UI tends to change frequently.
Fire up the Azure CLI. If you have more than one Azure subscription you should make sure your CLI session is set accordingly. You can get a list of your subscriptions and their id's by running:
az account list --query .[name,id]
If you have more than one subscription, use the output from the above command to scope your CLI session to the desired subscription id using the syntax below:
az account set --subscription <YOUR SUBSCRIPTION ID>
Next, create a resource group to store the resources for the application. If you're not sure what the region names are you can use the "az account list-locations" command. I'm using westus2.
az group create --location <YOUR REGION> --name <YOUR GROUP NAME>
az storage account create \ --location <YOUR REGION> \ --name <YOUR STORAGE ACCOUNT NAME> \ --resource-group <YOUR GROUP NAME> \ --sku Standard_LRS \ --kind StorageV2
Now that the storage account is created, we need to enable static website hosting. As I am writing this article, static website hosting for GPv2 storage accounts is generally available, but we still need to install the storage preview extension to enable it via the CLI. Run the following command to install the extension:
az extension add --name storage-preview
The final step is to enable static website hosting. Make sure to update the --name flag to reflect your storage account name:
az storage blob service-properties update \ --account-name <YOUR STORAGE ACCOUNT NAME> \ --static-website \ --index-document index.html
If you run into problems creating the storage account or enabling static website hosting from the CLI, you can do this work through the Azure portal using the steps outlined in this guide in the Azure documentation.
Here's what you should see in the portal after running the above CLI commands or manually enabling static website hosting:
Notice that the default document is set to index.html. That file doesn't existing yet. We'll deploy it later. Go ahead and record the primary endpoint URL for the static website as shown in Figure 1 becuase we'll need this value in the next step.
Now it's time to create a function app. Think of a function app as a resource that hosts the execution of one or more serverless functions. The way the function app is configured will be unique for each application becuase it controls the underlying OS platform and runtime stack. The function app settings also control the billing model you'll use for your serverless functions.
Take a look at the CLI command below. You can see we'll be using the az functionapp create command to build the function app. The consumption plan location defines where our code will run and how we're billed. Azure Functions consumption plan is billed based on per-second resource consumption and executions and includes a monthly free grant of 1 million requests. Also, pay close attention to the --name flag. Like Azure Storage, the name must be a DNS-compliant globally unique value as it will be used as the host portion of the URL for the function app. We'll set the runtime node. Make sure you update all the values in the example below and then run the command to create the function app.
az functionapp create \ --resource-group <YOUR GROUP NAME> \ --consumption-plan-location <YOUR REGION> \ --name <YOUR FUNCTION APP NAME> \ --storage-account <YOUR STORAGE ACCOUNT NAME> \ --runtime node
After the function app has been created we need to update the Cross-Origin Resource Sharing (CORS) configuration. CORS is a mechanism that tells a web browser connected to one origin (domain) that its OK to access resources on another server.
So, what we need to do is run the az functionapp cors add command as shown below. We'll need to target the previous resource group and function app resources we created, and also define the allowed origin which will be the primary endpoint URL from the Storage Account from Step 1.
az functionapp cors add \ --resource-group <YOUR GROUP NAME> \ --name <YOUR FUNCTION APP NAME> \ --allowed-origins <YOUR STATIC WEBSITE URL>
Once the CORS configuration has been set you'll be able to see the change in the platform features section of the function app in the Azure portal, as shown in Figure 2.
Again, if you run into any problems doing this from the CLI, you can manually create the Function App and add the static website primary endpoint URL to the CORS configuration.
Now that we have a function app, we can create a new function. While the Azure CLI makes it easy to create the function app from the command-line, we need to use other tools to create our functions. One way we could do it is by using the Azure Core Tools, but I'm not going to get into that here. Instead, we'll create the function inside the Azure portal.
Navigate to your function app and highlight Functions. Click the New function button to start the process as shown in Figure 3.
Next, we can select a template for our function. Select the HTTP trigger template as shown in Figure 4.
The last step is to name the function and set the authorization level. Change the name of the function to SayHello and set the authorization level to Anonymous.
After the function has been created you'll see the default code for the HTTP trigger template as shown below in Figure 6.
While you're viewing this code in the Azure portal, you'll see a link at the top of the screen that says Get function URL as shown in Figure 7.
Copy the URL from this screen as we'll need it for the next step.
Now we are ready to configure the HTML page for the serverless application like the one shown in Figure 8.
Check out the snippet from Figure 9:
Here's what you need to know:
Take a look at the code in Figure 10:
Still awake? Good :)
All of this code is included in a single HTML file for the sake of convinience. Grab the Index.html page from GitHub. Don't forget to replace "<YOUR FUNCTION URL GOES HERE>" with the URL of your function that you recorded in the Step 3.
Let's take the index.html file and upload it into our Azure Storage account. Since static website hosting is already enabled for the storage account, we simply need to upload the file/blob to the $web container.
This can be done easily in the portal, but here's how you can do it via the Azure CLI:
az storage blob upload-batch \ --source <YOUR SOURCE FOLDER> \ --destination \$web \ --account-name <YOUR STORAGE ACCOUNT NAME>
Finally, its time to test our serverless application. Navigate to the static website primary endpoint URL to view your application. After filling out and submitting the form, you should see a response similiar to the one in Figure 11.
Isn't that awesome?
You might be wondering how the success message was created on the page. That work is done as part of the response where we call the processResponse() function shown in Figure 12.
What we're doing with this function is checking the HTTP resonse code sent back from the Azure function. Regardless of the result, we use processResponse() to update the output element on the page. We're taking advantage of Bootstrap alerts to add some flare.
Here's what it would look like if there was a problem:
This is a good example of how we can give feedback to users based on the result of a function invoked over HTTP. Obviously we could do client-side validation and more error handling on the back-end but I think you get the idea.
We've only scratched the surface, but I hope this tutorial has given you a little more perspective. Going forward, I'd recomend these resources from Microsoft to learn more about serverless on Azure:
The industry needs skilled workers in cloud computing, serverless application development, containers, and devops. Sign up for my newsletter for access to exclusive training, updates on industry trends, and advice to amplify your business or career.