Lab: Building a web application on Azure Platform-as-a-Service offerings

Student lab manual

Lab scenario

You are the owner of a startup organization and have been building an image gallery application for people to share great images of food. To get your product to market as quickly as possible, you decided to use Microsoft Azure App Service to host your web applications and APIs. Recently, you realized that the images that are being uploaded to your application are simply too large. Out of concern for storage and bandwidth costs, you decided to use Azure Functions to process images in the background and shrink them down to thumbnails that can be loaded quickly.

Objectives

After you complete this lab, you will be able to:

  • Create various apps by using the Azure App Service.

  • Configure application settings for an app.

  • Deploy apps by using Kudu, the Azure CLI, and zip deployment.

  • Author a function app to process Azure Storage images.

Lab setup

  • Estimated time: 90 minutes

Instructions

Before you start

Sign in to the lab virtual machine

Ensure that you are signed in to your Windows 10 virtual machine by using the following credentials:

  • Username: Admin

  • Password: Pa55w.rd

Review installed applications

Observe the taskbar located at the bottom of your Windows 10 desktop. The taskbar contains the icons for the applications that you will use in this lab:

  • Microsoft Edge

  • File Explorer

  • Windows PowerShell

  • Visual Studio Code

Download the lab files

  1. On the taskbar, select the Windows PowerShell icon.

  2. In the PowerShell command prompt, change the current working directory to the Allfiles (F):\ path:

    cd F:
    
  3. Within the command prompt, enter the following command and press Enter to clone the microsoftlearning/AZ-203-DevelopingSolutionsforMicrosoftAzure project hosted on GitHub into the Allfiles (F):\ drive:

    git clone --depth 1 --no-checkout https://github.com/microsoftlearning/AZ-203-DevelopingSolutionsForMicrosoftAzure .
    
  4. Within the command prompt, enter the following command and press Enter to check out the lab files necessary to complete the AZ-203T02 lab:

    git checkout master -- Allfiles/*
    
  5. Close the currently running Windows PowerShell command prompt application.

Exercise 1: Build a back-end API by using Azure Storage and Web apps

Task 1: Open the Azure portal

  1. Sign in to the Azure portal (portal.azure.com).

  2. If this is your first time signing in to the Azure portal, a dialog box will display offering a tour of the portal. Select Get Started to skip the tour.

Task 2: Create an Azure Storage account

  1. Create a new storage account with the following details:

    • New resource group: ManagedPlatform

    • Name: imgstor[your name in lowercase]

    • Location: (US) East US

    • Performance: Standard

    • Account kind: StorageV2 (general purpose v2)

    • Replication: Locally-redundant storage (LRS)

    • Access tier: Hot

Note: Wait for Azure to finish creating the storage account before you move forward with the lab. You will receive a notification when the account is created.

  1. Access the Access Keys blade of your newly created storage account instance.

  2. Record the value of the Connection string field. You will use this value later in this lab.

Task 3: Upload a sample blob

  1. Access the imgstor* storage account that you created earlier in this lab.

  2. In the Blob service section, select the Containers link.

  3. Create a new container with the following settings:

    • Name: images

    • Public access level: Blob (anonymous read access for blobs only)

  4. Create another new container with the following settings:

    • Name: images-thumbnails

    • Public access level: Blob (anonymous read access for blobs only)

  5. Navigate to the new images container.

  6. Use the Upload button to upload the grilledcheese.jpg file located in the Allfiles (F):\Allfiles\Labs\02\Starter\Images folder on your lab machine.

    Note: It is recommended that you enable the Overwrite if files already exist option.

Task 4: Create a Web app

  1. Create a new Web app with the following details:

    • App name: imgapi[your name in lowercase]

    • Existing resource group: ManagedPlatform

    • Runtime stack: .NET Core 2.1 (LTS)

    • OS: Windows

    • Enable Application Insights: No

    Note: Wait for Azure to finish creating the Web app before you move forward with the lab. You will receive a notification when the app is created.

Task 5: Configure a Web app

  1. Access the imgapi* Web app that you created earlier in this lab.

  2. In the Settings section on the left side of the blade, navigate to the Configuration section.

  3. Create a new application setting by using the following details:

    • Name: StorageConnectionString

    • Value: <Storage Connection String copied earlier in this lab>

    • deployment slot setting: Not selected

  4. Save your changes to the Application settings.

  5. In the Settings section on the left side of the blade, navigate to the Properties section.

  6. In the Properties section, copy the value of the URL field. You will use this value later in the lab.

Task 6: Deploy an ASP.NET Core web application to Web app

  1. Using Visual Studio Code, open the web application located in the Allfiles (F):\Allfiles\Labs\02\Starter\API folder.

  2. Open the Controllers\ImagesController.cs file and observe the code in each of the methods.

  3. Open the Windows PowerShell application.

  4. Sign in to the Azure CLI by using your Microsoft Azure credentials:

    az login
    
  5. List all the apps in your ManagedPlatform resource group:

    az webapp list --resource-group ManagedPlatform
    
  6. Find the apps that have the prefix imgapi*:

    az webapp list --resource-group ManagedPlatform --query "[?starts_with(name, 'imgapi')]"
    
  7. Print only the name of the single app that has the prefix imgapi*:

    az webapp list --resource-group ManagedPlatform --query "[?starts_with(name, 'imgapi')].{Name:name}" --output tsv
    
  8. Change the current directory to the Allfiles (F):\Allfiles\Labs\02\Starter\API directory that contains the lab files:

    cd F:\Labfiles\02\Starter\API\
    
  9. Deploy the api.zip file to the Web app you created earlier in this lab:

    az webapp deployment source config-zip --resource-group ManagedPlatform --src api.zip --name <name-of-your-api-app>
    

    Note: Replace the <name-of-your-api-app> placeholder with the name of the Web app that you created earlier in this lab. You recently queried this app’s name in the previous steps.

  10. Access the imgapi* Web app you created earlier in this lab.

  11. Open the imgapi* Web app in your browser.

  12. The browser will open a new tab that performs a GET request to the root of the website. Observe the JSON array that is returned. This array should contain the URL for your single uploaded image in your Azure Storage account.

Review

In this exercise, you created a Web app in Azure and then deployed your ASP.NET Core web application to the Web app by using the Azure CLI and Kudu’s zip deployment utility.

Exercise 2: Build a front-end web application by using Azure web apps

Task 1: Create web app

  1. In the Azure portal, create a new web app with the following details:

    • App name: imgweb[your name in lowercase]

    • Existing resource group: ManagedPlatform

    • Runtime stack: .NET Core 2.1 (LTS)

    • OS: Windows

    • Enable Application Insights: No

    Note: Wait for Azure to finish creating the web app pbefore you move forward with the lab. You will receive a notification when the app is created.

Task 2: Configure a web app

  1. Access the imgweb* Web App you created in the previous task.

  2. In the Settings section on the left side of the blade, navigate to the Configuration settings.

  3. Create a new application setting using the following details:

    • Name: ApiUrl

    • Value: <Web app URL copied earlier in this lab>

    • deployment slot setting: Not selected

    Note: Make sure you include the protocol (ex. https://) in the URL you copy into the value field for this application setting.

  4. Save your changes to the Application Settings.

Task 3: Deploy an ASP.NET Core web application to Web App

  1. Using Visual Studio Code, open the web application located in the Allfiles (F):\Allfiles\Labs\02\Starter\Web folder.

  2. Open the Pages\Index.cshtml.cs file and observe the code in each of the methods.

  3. Open the Windows PowerShell application.

  4. Sign in to the Azure CLI by using your Microsoft Azure credentials:

    az login
    
  5. List all the apps in your ManagedPlatform resource group:

    az webapp list --resource-group ManagedPlatform
    
  6. Find the apps that have the prefix imgweb*:

    az webapp list --resource-group ManagedPlatform --query "[?starts_with(name, 'imgweb')]"
    
  7. Print only the name of the single app that has the prefix imgweb*:

    az webapp list --resource-group ManagedPlatform --query "[?starts_with(name, 'imgweb')].{Name:name}" --output tsv
    
  8. Change your current directory to the Allfiles (F):\Allfiles\Labs\02\Starter\Web directory that contains the lab files:

    cd F:\Labfiles\02\Starter\Web\
    
  9. Deploy the web.zip file to the web app that you created earlier in this lab:

    az webapp deployment source config-zip --resource-group ManagedPlatform --src web.zip --name <name-of-your-web-app>
    

    Note: Replace the <name-of-your-web-app> placeholder with the name of the web app that you created earlier in this lab. You recently queried this app’s name in the previous steps.

  10. Access the imgweb* web app that you created earlier in this lab.

  11. Open the imgweb* web app in your browser.

  12. Observe that the list of gallery images has been updated with your new image.

    Note: In some rare cases, you might need to refresh your browser window for the new image to appear.

Review

In this exercise, you created an Azure Web App and deployed an existing web application’s code to the resource in the cloud.

Exercise 3: Build a background processing job by using Azure Storage and Azure Functions

Task 1: Create a function app

  1. In the Azure portal, create a new function app with the following details:

    • Existing resource group: ManagedPlatform

    • App name: imgfunc[your name in lowercase]

    • Publish: Code

    • Runtime Stack: .NET Core

    • Region: East US

    • Storage account: imgstor[your name in lowercase here]

    • Operating System: Windows

    • Plan type: App service plan

    • Enable Application Insights: No

      Note: Wait for Azure to finish creating the function app before you move forward with the lab. You will receive a notification when the app is created.

Task 2: Create a .NET Core application setting

  1. Access the imgfunc* Function App that you created earlier in this lab.

  2. Navigate to the Configuration settings located in the Platform features tab.

  3. Create a new application setting by using the following details:

    • Name: DOTNET_SKIP_FIRST_TIME_EXPERIENCE

    • Value: true

      Note: The DOTNET_SKIP_FIRST_TIME_EXPERIENCE application setting tells .NET Core to disable it’s built-in NuGet package caching mechanisms. On a temporary compute instance, this would effectively be a waste of time and cause build issues with your Azure Function.

  4. Save your changes to the Application settings.

Task 3: Author a function to process blobs

  1. On the Azure portal left navigation pane, select Resource groups.

  2. In the Resource groups blade, locate and select the ManagedPlatform resource group that you created earlier in this lab.

  3. In the ManagedPlatform blade, select the imgfunc* function app that you created earlier in this lab.

  4. In the Function App blade, select + New function.

  5. In the New Azure Function quickstart, perform the following actions:

    1. Under the Choose a Development Environment header, select In-Portal.

    2. Select Continue.

    3. Under the Create a Function header, select More templates….

    4. Select Finish and view templates.

    5. In the Templates list, select Azure Blob Storage trigger.

    6. In the Extensions not Installed window, select Install.

      Note: It can take up to two minutes to install the extensions needed to work with Azure Storage blobs. If the portal does not refresh, simply close the Extensions not Installed pop-up window and select Azure Blob Storage trigger again.

    7. Once the installation has succeeded, select Continue.

    8. In the New Function window, in the Name field enter ImageManager.

    9. In the New Function window, in the Path field enter images/{name}.

    10. In the New Function window, in the Storage account connection list, select AzureWebJobsStorage.

    11. In the New Function window, select Create.

  6. On the right side of the function editor, select View files to open the tab.

  7. In the View files tab, select Add.

  8. In the filename dialog that appears, enter function.proj.

  9. In the file editor, insert this configuration content:

    <Project Sdk="Microsoft.NET.Sdk">
        <PropertyGroup>
            <TargetFramework>netstandard2.0</TargetFramework>
        </PropertyGroup>
        <ItemGroup>
            <PackageReference Include="SixLabors.ImageSharp" Version="1.0.0-beta0006" />
        </ItemGroup>
    </Project>
    
  10. In the editor, select Save button to persist your changes to the configuration.

    Note: This .proj file contains the NuGet package reference necessary to import the SixLabors.ImageSharp package.

  11. Back in the View files tab, select the function.json file to view the editor for the function’s configuration.

  12. In the JSON editor, observe the current configuration:

    {
      "bindings": [
        {
          "name": "myBlob",
          "type": "blobTrigger",
          "direction": "in",
          "path": "images/{name}",
          "connection": "AzureWebJobsStorage"
        }
      ],
      "disabled": false
    }
    
  13. Replace the entire contents of the JSON configuration file with the following JSON content:

     {
       "bindings": [
         {
           "name": "inputBlob",
           "type": "blobTrigger",
           "direction": "in",
           "path": "images/{name}",
           "connection": "AzureWebJobsStorage"
         },
         {
           "type": "blob",
           "name": "outputBlob",
           "path": "images-thumbnails/{name}",
           "connection": "AzureWebJobsStorage",
           "direction": "out"
         }
       ]
     }
    
  14. In the JSON editor, select Save button to persist your changes to the configuration.

  15. Back in the View files tab, select the run.csx file to return to the editor for the ImageManager function.

  16. Minimize the View files tab.

    Note: You can minimize the tab by selecting the arrow immediately to the right of the tab header.

  17. In the function editor, observe the example function script:

     public static void Run(Stream myBlob, string name, ILogger log)
     {
         log.LogInformation($"C# Blob trigger function Processed blob\n Name:{name} \n Size: {myBlob.Length} Bytes");
     }
    
  18. Delete all the example code.

  19. Within the editor, copy and paste the following placeholder function:

     using SixLabors.ImageSharp;
     using SixLabors.ImageSharp.PixelFormats;
     using SixLabors.ImageSharp.Processing;
     using SixLabors.ImageSharp.Formats.Jpeg;
     using SixLabors.Primitives;
    
     public static void Run(Stream inputBlob, Stream outputBlob, string name, ILogger log)
     {
     }
    
  20. In the editor, select Save to save the script and compile the code.

  21. Add the following line of code to log information about the function execution:

     log.LogInformation($"C# Blob trigger function Processed blob\n Name:{name} \n Size: {inputBlob.Length} Bytes");
    
  22. Add the following using statement to load the Stream for the input blob into the image library:

     using (Image<Rgba32> image = Image.Load(inputBlob))
     {
     }
    
  23. Add the following lines of code within the using statement to mutate the image by resizing the image and applying a grayscale filter:

     image.Mutate(i => 	
         i.Resize(new ResizeOptions { Size = new Size(250, 250), Mode = ResizeMode.Max }).Grayscale()
     );
    
  24. Add the following line of code to save the new image to the Stream for the output blob:

     image.Save(outputBlob, new JpegEncoder());
    
  25. Your Run method should now resemble the following:

     using SixLabors.ImageSharp;
     using SixLabors.ImageSharp.PixelFormats;
     using SixLabors.ImageSharp.Processing;
     using SixLabors.ImageSharp.Formats.Jpeg;
     using SixLabors.Primitives;
    
     public static void Run(Stream inputBlob, Stream outputBlob, string name, ILogger log)
     {
         log.LogInformation($"C# Blob trigger function Processed blob\n Name:{name} \n Size: {inputBlob.Length} Bytes");
         using (Image<Rgba32> image = Image.Load(inputBlob))
         {
             image.Mutate(i => 	
                 i.Resize(new ResizeOptions { Size = new Size(250, 250), Mode = ResizeMode.Max }).Grayscale()
             );
             image.Save(outputBlob, new JpegEncoder());
         }
     }
    
  26. In the editor, select Save to save the script and compile the code again.

Task 4: Validate the web solution

  1. On the Azure portal left navigation pane, select Resource groups.

  2. In the Resource groups blade, locate and select the ManagedPlatform resource group that you created earlier in this lab.

  3. In the ManagedPlatform blade, select the imgstor* storage account that you created earlier in this lab.

  4. In the Storage Account blade, in the Blob service section on the left side of the blade, select the Containers link.

  5. In the Containers section, select the images container.

  6. In the Container blade, select Upload.

  7. In the Upload blob window that appears, perform the following actions:

    1. In the Files section, select the Folder icon.

    2. In the File Explorer dialog box that opens, go to Allfiles (F):\Allfiles\Labs\02\Starter\Images, select the veggie.jpg file, and then select Open.

    3. Ensure that the Overwrite if files already exist check box is selected.

    4. Select Upload.

  8. Wait for the blob to be uploaded before you continue with this lab.

  9. Close the Container blade.

  10. Back in the Containers section, select the images-thumbnails container.

  11. In the Container blade, observe the newly created veggie.jpg file in the images-thumbnails container.

    Note: It might take one to five minutes for the new image to appear.

  12. In the images-thumbnails container, select the veggie.jpg blob.

  13. In the Blob blade, select the Edit blob tab.

  14. Observe the contents of the blob.

  15. On the left side of the portal, select Resource groups.

  16. In the Resource groups blade, locate and select the ManagedPlatform resource group that you created earlier in this lab.

  17. In the ManagedPlatform blade, select the imgweb* web app that you created earlier in this lab.

  18. In the Web App blade, select Browse.

  19. Observe the list of images in the gallery.

  20. At the top of the Contoso Photo Gallery webpage, locate the Upload a new image section and perform the following actions:

    1. Select Browse.

    2. In the File Explorer dialog box that opens, go to Allfiles (F):\Allfiles\Labs\02\Starter\Images, select the blt.jpg file, and then select Open.

    3. Select the Upload.

  21. At the top of the webpage, locate the Upload a new image section and perform the following actions:

    1. Select Browse.

    2. In the File Explorer dialog box that opens, go to Allfiles (F):\Allfiles\Labs\02\Starter\Images, select the sub.jpg file, and then select Open.

    3. Select Upload.

  22. At the top of the webpage, locate the Upload a new image section and perform the following actions:

    1. Select Browse.

    2. In the File Explorer dialog box that opens, go to Allfiles (F):\Allfiles\Labs\02\Starter\Images, select the burger.jpg file, and then select Open.

    3. Select Upload.

  23. On the Contoso Photo Gallery webpage, observe that the list of gallery images has been updated with your new image.

  24. Observe the list of thumbnails at the top of the page. Refresh your page every minute until your thumbnails have been generated.

Review

In this exercise, you created a background processing job in Azure Functions to handle the computationally intensive task of modifying and resizing images.

Exercise 4: Clean up subscription

Task 1: Open Cloud Shell

  1. At the top of the Azure portal, select the Cloud Shell icon to open a new shell instance.

  2. If the Cloud Shell is not already configured, configure the shell for Bash by using the default settings.

  3. At the bottom of the portal in the Cloud Shell command prompt, type the following command and press Enter to list all resource groups in the subscription:

    az group list
    
  4. Type the following command and press Enter to view a list of possible commands to delete a resource group:

    az group delete --help
    

Task 2: Delete resource groups

  1. Type the following command and press Enter to delete the ManagedPlatform resource group:

    az group delete --name ManagedPlatform --no-wait --yes
    
  2. Close the Cloud Shell pane at the bottom of the portal.

Task 3: Close active applications

  1. Close the currently running Microsoft Edge application.

  2. Close the currently running Visual Studio Code application.

Review

In this exercise, you cleaned up your subscription by removing the resource groups used in this lab.