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.
Before We Begin
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.
Step 1. Building the Azure Storage Account
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 \
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> \
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:
Figure 1. Reviewing the static website properties.
Notice that the default document is set to index.html. That file doesn’t exist yet. We’ll deploy it later. Go ahead and record the primary endpoint URL for the static website as shown in Figure 1 because we’ll need this value in the next step.
Step 2. Building the Azure Function App
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 because 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> \
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.
Figure 2. Reviewing the CORS configuration.
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.
Step 3. Creating an Azure Function
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.
Figure 3. Locating the new function button.
Next, we can select a template for our function. Select the HTTP trigger template as shown in Figure 4.
Figure 4. Selecting the HTTP trigger template.
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.
Figure 5. Setting the function name and auth level.
After the function has been created you’ll see the default code for the HTTP trigger template as shown below in Figure 6.
Figure 6. Reviewing the Function App Settings.
- Line 1: You can see the first argument sent to the function is a context object which, among other things, is used for communicating with the Azure Functions runtime. The second argument (req) is the request object that contains the details about what was sent to the function. We’ll be able to use the req object to access the data sent to this function from our web form.
- Line 4: Here we’re using some conditional logic to make sure the request contains a name key within the query string parameters or request body.
- Line 5: If a name was provided with the request, we use the context.res object to send a response. In this case, we send back a “hello” message to the caller.
- Line 11: If a name wasn’t provided, we’ll send back an HTTP 400 error with a message explaining what the problem is.
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.
Figure 7. Copying the function URL.
Copy the URL from this screen as we’ll need it for the next step.
Step 4. Configuring the HTML Front-end
Now we are ready to configure the HTML page for the serverless application like the one shown in Figure 8.
Figure 8. The UI for our serverless app.
Check out the snippet from Figure 9:
Figure 9. The HTML form for the app.
Here’s what you need to know:
- Line 4: There’s an empty output div we can update based on the response from our Azure function. We’ll use this element to provide a success or failure message to the user.
- Line 7: The input field where the user submits their name. Notice that the id is set to name. We’ll grab the value from this input and send it along with the request to our Azure Function.
- Line 9: When the user clicks the submit button we’ll post the form to our Azure function.
Take a look at the code in Figure 10:
- Line 4: We grab the value of the input field in the HTML form.
- Line 5: The Fetch API will be used to facilitate the request/response process. You’ll obviously need to update this line with your own function URL.
- Line 12: The value for the name input will be sent as part of the body of the POST request.
- Line 15: fetch() returns a promise containing the response, and that gets passed to another client-side function called processResponse() which will update the UI.
Still awake? Good :)
All of this code is included in a single HTML file for the sake of convenience. 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 Step 3.
Step 5. Deploying the HTML Front-end
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>
Step 6. Testing the Serverless Web Application
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 similar to the one in Figure 11.
Figure 11. The UI for our serverless app in action.
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.
Figure 12. The processResponse() function.
What we’re doing with this function is checking the HTTP response 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:
Figure 13. The UI for our serverless app when there is an error.
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.
Where to go from here
We’ve only scratched the surface, but I hope this tutorial has given you a little more perspective. Going forward, I’d recommend these resources from Microsoft to learn more about serverless on Azure:
Originally published at mikepfeiffer.io.