Lab 07: Access resource secrets more securely across services

Microsoft Azure user interface

Given the dynamic nature of Microsoft cloud tools, you might experience Azure UI changes that occur after this training content’s development. As a result, the lab instructions and lab steps might not align correctly.

Microsoft updates this training course when the community brings needed changes to our attention. However, because cloud updates occur frequently, you might encounter UI changes before this training content updates. If this occurs, adapt to the changes, and then work through them in the labs as needed.

Instructions

Before you start

Sign in to the lab environment

Sign in to your Windows 10 virtual machine (VM) by using the following credentials:

  • Username: Admin
  • Password: Pa55w.rd

Note: Your instructor will provide instructions to connect to the virtual lab environment.

Review the installed applications

Find the taskbar on your Windows 10 desktop. The taskbar contains the icons for the applications that you’ll use in this lab, including:

  • Microsoft Edge
  • File Explorer
  • Windows Terminal
  • Visual Studio Code

Architecture diagram

Architecture diagram depicting a user accessing resource secrets more securely across services.

Exercise 1: Create Azure resources

Task 1: Open the Azure portal

  1. On the taskbar, select the Microsoft Edge icon.

  2. In the open browser window, browse to the Azure portal (https://portal.azure.com), and then sign in with the account you’ll be using for this lab.

    Note: If this is your first time signing in to the Azure portal, you’ll be offered a tour of the portal. Select Get Started to skip the tour and begin using the portal.

Task 2: Create a Storage account

  1. In the Azure portal, use the Search resources, services, and docs text box to search for Storage Accounts, and then in the list of results, select Storage accounts.

  2. On the Storage accounts blade, select + Create.

  3. On the Create a storage account blade, on the Basics tab, perform the following actions, and select Review + create:

    Setting Action
    Subscription drop-down list Retain the default value
    Resource group section Select Create new, enter ConfidentialStack, and then select OK
    Storage account name text box Enter securestor[yourname]
    Region drop-down list Select (US) East US
    Performance section Select the Standard option
    Redundancy drop-down list select Locally-redundant storage (LRS)

    The following screenshot displays the configured settings on the Create a storage account blade.

    Screenshot displaying the configured settings on the Create a storage account blade

  4. On the Review + create tab, review the options that you selected during the previous steps.

  5. Select Create to create the storage account by using your specified configuration.

    Note: Wait for the creation task to complete before you move forward with this lab.

  6. On the Deployment Overview blade, select Go to resource.

  7. On the Storage account blade, in the Security + networking section, select the Access keys link.

  8. In the Access keys section, select Show keys.

  9. Select any one of the keys and record the value in either of the Connection string boxes. You’ll use this value later in this lab.

    Note: It doesn’t matter which connection string you choose. They’re interchangeable.

Task 3: Create an Azure Key Vault

  1. In the Azure portal, use the Search resources, services, and docs text box to search for Key vaults, and then in the list of results, select Key vaults.

  2. On the Key vaults blade, select Create.

  3. On the Create key vault blade, on the Basics tab, perform the following actions, and then select Review + create:

    Setting Action
    Subscription drop-down list Retain the default value.
    Resource group drop-down list Select ConfidentialStack in the list.
    Key vault name text box Enter securevault[yourname].
    Region drop-down list Select East US.
    Pricing tier drop-down list select Standard.

    The following screenshot displays the configured settings on the Create key vault blade.

    Screenshot displaying the configured settings on the Create key vault blade

  4. On the Review + create tab, review the options that you selected during the previous steps.

  5. Select Create to create the key vault by using your specified configuration.

    Note: Wait for the creation task to complete before you move forward with this lab.

Task 4: Create a Function app

  1. In the Azure portal, use the Search resources, services, and docs text box to search for Function App, and then in the list of results, select Function App.

  2. On the Function App blade, select Create.

  3. On the Create Function App blade, on the Basics tab, perform the following actions, and then select Next: Hosting:

    Setting Action
    Subscription drop-down list Retain the default value
    Resource group drop-down list Select ConfidentialStack
    Function App name text box Enter securefunc[yourname]
    Publish section Select Code
    Runtime stack drop-down list Select .NET
    Version drop-down list Select 3.1
    Region drop-down list Select the East US region.

    The following screenshot displays the configured settings in the Create Function App blade.

    Screenshot displaying the configured settings on the Create Function App blade

  4. On the Hosting tab, perform the following actions, and then select Review + create:

    Setting Action
    Storage account drop-down list Select the securestor[yourname] storage account
    Operating System section Select Linux
    Plan type drop-down list Select Consumption (Serverless)

    The following screenshot displays the configured settings on the Hosting tab on the Create Function App blade.

    Screenshot displaying the configured settings on the Hosting tab on the Create Function App blade

  5. On the Review + create tab, review the options that you selected during the previous steps.

  6. Select Create to create the function app by using your specified configuration.

    Note: Wait for the creation task to complete before you move forward with this lab.

Review

In this exercise, you created all the resources that you’ll use in this lab.

Exercise 2: Configure secrets and identities

Task 1: Configure a system-assigned managed service identity

  1. On the Azure portal’s navigation pane, select the Resource groups link.

  2. On the Resource groups blade, select the ConfidentialStack resource group.

  3. On the ConfidentialStack blade, select the securefunc[yourname] function app.

    Note: There will be two resources, a function app and application insights resource, with the same name. Make sure you select the function app resource.

  4. On the Function App blade, select the Identity option from the Settings section.

  5. On the Identity pane, on the System assigned tab, set the Status to On, and then select Save.

  6. Select Yes to confirm the setting.

    Note: Wait for the system-assigned managed identity to be created before you move forward with this lab.

Task 2: Create a Key Vault secret

  1. On the Azure portal’s navigation pane, select the Resource groups link.

  2. On the Resource groups blade, select the ConfidentialStack resource group.

  3. On the ConfidentialStack blade, select the securevault[yourname] key vault.

  4. On the Key Vault blade, select the Secrets link in the Settings section.

  5. On the Secrets pane, select + Generate/Import.

  6. On the Create a secret blade, perform the following actions, and then select Create:

    Setting Action
    Upload options drop-down list Select Manual
    Name text box Enter storagecredentials
    Value text box Enter the storage account connection string that you recorded previously in this lab.
    Content type text box Leave blank.
    Set activation date check box Not selected.
    Set expiration date check box Not selected.
    Enabled option Select Yes.

    The following screenshot displays the configured settings on the Create a secret blade.

    Screenshot displaying the configured settings on the Create a secret blade

    Note: Wait for the secret to be created before you move forward with this lab.

  7. Return to the Secrets pane, and then select the storagecredentials item in the list.

  8. On the Versions pane, select the latest version of the storagecredentials secret.

  9. On the Secret Version pane, perform the following actions:

    1. Select Show secret value to find the value of the secret.

    2. Record the value of the Secret Identifier text box because you’ll use this later in the lab.

    Note: You’re recording the value of the Secret Identifier text box, not the Secret Value text box.

Task 3: Configure a Key Vault access policy

  1. On the Azure portal’s navigation pane, select the Resource groups link.

  2. On the Resource groups blade, select the ConfidentialStack resource group.

  3. On the ConfidentialStack blade, select the securevault[yourname] key vault.

  4. On the Key vault blade, select the Access policies link in the Settings section.

  5. On the Access policies pane, select Add Access Policy.

  6. On the Add access policy blade, perform the following actions, and then select Add:

    Setting Action
    Configure from template drop-down list Leave blank
    Key permissions drop-down list 0 selected
    Secret permissions drop-down list Select the GET permission
    Certificate permissions drop-down list 0 selected
    Select principal link Find and then select the service principal named securefunc[yourname]. The system-assigned managed identity you created previously in this lab will have the same name as the Azure Function resource.
    Authorized application link None selected

    The following screenshot displays the configured settings in the Add access policy blade.

    Screenshot depicting the configured settings on the Add access policy blade.

  7. On the Access policies pane, select Save.

    Note: Wait for your changes to the access policies to save before you continue with this lab.

Task 4: Create a Key Vault-derived application setting

  1. On the Azure portal’s navigation pane, select the Resource groups link.

  2. On the Resource groups blade, select the ConfidentialStack resource group.

  3. On the ConfidentialStack blade, select the securefunc[yourname] function app.

  4. On the Function App blade, select the Configuration option from the Settings section.

  5. On the Configuration pane, on the Application settings tab, select New application setting.

  6. In the Add/Edit application setting pop-up window, in the Name text box, enter StorageConnectionString.

  7. In the Value text box, construct a value by using the following syntax: @Microsoft.KeyVault(SecretUri=*Secret Identifier*)

    Note: You’ll need to build a reference to your Secret Identifier by using the above syntax. For example, if your secret identifier is https://securevaultstudent.vault.azure.net/secrets/storagecredentials/17b41386df3e4191b92f089f5efb4cbf, your value would be @Microsoft.KeyVault(SecretUri=https://securevaultstudent.vault.azure.net/secrets/storagecredentials/17b41386df3e4191b92f089f5efb4cbf).

  8. Leave the deployment slot setting check box set to its default value (not selected), and then select OK to close the pop-up window and to return to the Configuration section.

  9. Select Save to save your settings, and then in the save Changes confirmation pop-up dialog box, select Continue.

    Note: Wait for your application settings to save before you continue with the lab.

Review

In this exercise, you created a system-assigned managed service identity for your function app, and then gave that identity the appropriate permissions to get the value of a secret in your key vault. Finally, you created a secret that you referenced within your function app’s configuration settings.

Exercise 3: Build an Azure Functions app

Task 1: Initialize a function project

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

  2. Run the following command to change the current directory to the Allfiles (F):\Allfiles\Labs\07\Starter\func empty directory:

     cd F:\Allfiles\Labs\07\Starter\func
    

    Note: In Windows Explorer remove the Read-only attribute from F:\Allfiles\Labs\07\Starter\func.gitignore file.

  3. Run the following command to use the Azure Functions Core Tools to create a new local Functions project in the current directory using the dotnet runtime:

     func init --worker-runtime dotnet --force
    

    Note: You can review the documentation to [create a new project][azure-functions-core-tools-new-project] using the Azure Functions Core Tools.

  4. Run the following command to build the .NET Core 3.1 project:

     dotnet build
    

Task 2: Create an HTTP-triggered function

  1. Run the following command to use the Azure Functions Core Tools to create a new function named FileParser using the HTTP trigger template:

     func new --template "HTTP trigger" --name "FileParser"
    

    Note: You can review the documentation to [create a new function][azure-functions-core-tools-new-function] using the Azure Functions Core Tools.

  2. Close the currently running Windows Terminal application.

Task 3: Configure and read an application setting

  1. On the Start screen, select the Visual Studio Code tile.

  2. On the File menu, select Open Folder.

  3. In the File Explorer window that opens, browse to Allfiles (F):\Allfiles\Labs\07\Starter\func, and then select Select Folder.

  4. On the Explorer pane of the Visual Studio Code window, open the local.settings.json file.

  5. Observe the current value of the Values object:

     "Values": {
         "AzureWebJobsStorage": "UseDevelopmentStorage=true",
         "FUNCTIONS_WORKER_RUNTIME": "dotnet"
     }
    
  6. Update the value of the Values object by adding a new setting named StorageConnectionString, and then assigning it a string value of [TEST VALUE]:

     "Values": {
         "AzureWebJobsStorage": "UseDevelopmentStorage=true",
         "FUNCTIONS_WORKER_RUNTIME": "dotnet",
         "StorageConnectionString": "[TEST VALUE]"
     }
    
  7. The local.settings.json file should now include:

     {
         "IsEncrypted": false,
         "Values": {
             "AzureWebJobsStorage": "UseDevelopmentStorage=true",
             "FUNCTIONS_WORKER_RUNTIME": "dotnet",
             "StorageConnectionString": "[TEST VALUE]"
         }
     }
    
  8. Select Save to save your changes to the local.settings.json file.

  9. On the Explorer pane of the Visual Studio Code window, open the FileParser.cs file.

  10. In the code editor, observe the example implementation:

     using System;
     using System.IO;
     using System.Threading.Tasks;
     using Microsoft.AspNetCore.Mvc;
     using Microsoft.Azure.WebJobs;
     using Microsoft.Azure.WebJobs.Extensions.Http;
     using Microsoft.AspNetCore.Http;
     using Microsoft.Extensions.Logging;
     using Newtonsoft.Json;
     namespace func
     {
         public static class FileParser
         {
             [FunctionName("FileParser")]
             public static async Task<IActionResult> Run(
                 [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
                 ILogger log)
             {
                 log.LogInformation("C# HTTP trigger function processed a request.");
                 string name = req.Query["name"];
                 string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
                 dynamic data = JsonConvert.DeserializeObject(requestBody);
                 name = name ?? data?.name;
                 string responseMessage = string.IsNullOrEmpty(name)
                     ? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
                     : $"Hello, {name}. This HTTP triggered function executed successfully.";
                 return new OkObjectResult(responseMessage);
             }
         }
     }
    
  11. Delete all of the content within the FileParser.cs file.

  12. Add the following lines of code to add using directives for the Microsoft.AspNetCore.Mvc, Microsoft.Azure.WebJobs, Microsoft.AspNetCore.Http, System, and System.Threading.Tasks namespaces:

     using Microsoft.AspNetCore.Mvc;
     using Microsoft.Azure.WebJobs;
     using Microsoft.AspNetCore.Http;
     using System;
     using System.Threading.Tasks;
    
  13. Create a new public static class named FileParser:

     public static class FileParser
     { }
    
  14. Observe the FileParser.cs file again, which should now include:

     using Microsoft.AspNetCore.Mvc;
     using Microsoft.Azure.WebJobs;
     using Microsoft.AspNetCore.Http;
     using System;
     using System.Threading.Tasks;
     public static class FileParser
     { }
    
  15. Within the FileParser class, add the following code block to create a new public static asynchronous method named Run. This method returns a variable of type Task<IActionResult> and also takes in a variable of type HttpRequest named request:

     public static async Task<IActionResult> Run(
         HttpRequest request)
     { }
    
  16. Add the following code to append an attribute to the Run method of type FunctionNameAttribute that has its name parameter set to a value of FileParser:

     [FunctionName("FileParser")]
     public static async Task<IActionResult> Run(
         HttpRequest request)
     { }
    
  17. Add the following code to append an attribute to the request parameter of type HttpTriggerAttribute that has its methods parameter array set to a single value of GET:

     [FunctionName("FileParser")]
     public static async Task<IActionResult> Run(
         [HttpTrigger("GET")] HttpRequest request)
     { }
    
  18. Observe the FileParser.cs file again, which should now include:

     using Microsoft.AspNetCore.Mvc;
     using Microsoft.Azure.WebJobs;
     using Microsoft.AspNetCore.Http;
     using System;
     using System.Threading.Tasks;
     public static class FileParser
     {
         [FunctionName("FileParser")]
         public static async Task<IActionResult> Run(
             [HttpTrigger("GET")] HttpRequest request)
         { }
     }
    
  19. In the Run method, enter the following line of code to retrieve the value of the StorageConnectionString application setting by using the Environment.GetEnvironmentVariable method and to store the result in a string variable named connectionString:

     string connectionString = Environment.GetEnvironmentVariable("StorageConnectionString");
    
  20. Enter the following line of code to return the value of the connectionString variable as the HTTP response:

     return new OkObjectResult(connectionString);
    
  21. Observe the FileParser.cs file again, which should now include:

     using Microsoft.AspNetCore.Mvc;
     using Microsoft.Azure.WebJobs;
     using Microsoft.AspNetCore.Http;
     using System;
     using System.Threading.Tasks;
     public static class FileParser
     {
         [FunctionName("FileParser")]
         public static async Task<IActionResult> Run(
             [HttpTrigger("GET")] HttpRequest request)
         {
             string connectionString = Environment.GetEnvironmentVariable("StorageConnectionString");
             return new OkObjectResult(connectionString);
         }
     }
    
  22. Select Save to save your changes to the FileParser.cs file.

Task 4: Validate the local function

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

  2. Run the following command to change the current directory to the Allfiles (F):\Allfiles\Labs\07\Starter\func empty directory:

     cd F:\Allfiles\Labs\07\Starter\func
    
  3. Run the following command to run the function app project:

     func start --build
    

    Note: You can review the documentation to [start the function app project locally][azure-functions-core-tools-start-function] using the Azure Functions Core Tools.

  4. On the taskbar, select the Windows Terminal icon again to open a new instance of the Windows Terminal application. Run the following command to change the current directory to the Allfiles (F):\Allfiles\Labs\07\Starter\func empty directory:

     cd F:\Allfiles\Labs\07\Starter\func
    
  5. When you receive the open command prompt, run the following command to start the httprepl tool, setting the base Uniform Resource Identifier (URI) to http://localhost:7071:

     httprepl http://localhost:7071
    

    Note: An error message is displayed by the httprepl tool. This message occurs because the tool is searching for a Swagger definition file to use to traverse the API. Because your function project doesn’t produce a Swagger definition file, you’ll need to traverse the API manually.

  6. When you receive the tool prompt, run the following command to browse to the relative api directory:

     cd api
    
  7. Run the following command to browse to the relative fileparser directory:

     cd fileparser
    
  8. Run the following command to run the get command:

     get
    
  9. Observe the [TEST VALUE] value of the StorageConnectionString being returned as the result of the HTTP request:

     HTTP/1.1 200 OK
     Content-Type: text/plain; charset=utf-8
     Date: Tue, 01 Sep 2020 23:35:39 GMT
     Server: Kestrel
     Transfer-Encoding: chunked
     [TEST VALUE]
    
  10. Run the following command to exit the httprepl tool:

     exit
    
  11. Close all currently running instances of the Windows Terminal application.

Task 5: Deploy the function using the Azure Functions Core Tools

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

  2. Run the following command to change the current directory to the Allfiles (F):\Allfiles\Labs\07\Starter\func empty directory:

     cd F:\Allfiles\Labs\07\Starter\func
    
  3. Run the following command to sign in to the Azure Command-Line Interface (CLI):

     az login
    
  4. In the Microsoft Edge browser window, enter the email address and password for your Microsoft account, and then select Sign in.

  5. Return to the currently open Windows Terminal window. Wait for the sign-in process to finish.

  6. Run the following command to publish the function app project:

     func azure functionapp publish <function-app-name>
    

    Note: As an example, if your Function App name is securefuncstudent, your command would be func azure functionapp publish securefuncstudent. You can review the documentation to [publish the local function app project][azure-functions-core-tools-publish-azure] using the Azure Functions Core Tools.

  7. Wait for the deployment to finalize before you move forward with the lab.

  8. Close the currently running Windows Terminal application.

Task 6: Test the Key Vault-derived application setting

  1. On the taskbar, select the Microsoft Edge icon, and then select the tab that contains the Azure portal (https://portal.azure.com).

  2. On the Azure portal’s navigation pane, select the Resource groups link.

  3. On the Resource groups blade, select the ConfidentialStack resource group.

  4. On the ConfidentialStack blade, select the securefunc[yourname] function app.

  5. On the Function App blade, select the Functions option in the Functions section.

  6. On the Functions pane, select the existing FileParser function.

  7. On the Function blade, select the Code + Test option in the Developer section.

  8. In the function editor, select Test/Run.

  9. In the pop-up dialog box that displays, in the HTTP method list, select GET.

  10. Select Run to test the function.

  11. Observe the results of the test run. The result should be your Azure Storage connection string.

Review

In this exercise, you used a service identity to read the value of a secret stored in Key Vault and returned that value as the result of a function app.

Exercise 4: Access Azure Blob Storage data

Task 1: Upload a sample storage blob

  1. On the Azure portal’s navigation pane, select the Resource groups link.

  2. On the Resource groups blade, select the ConfidentialStack resource group.

  3. On the ConfidentialStack blade, select the securestor[yourname] storage account.

  4. On the Storage account blade, select the Containers link in the Data storage section.

  5. In the Containers section, select + Container.

  6. In the New container pop-up window, perform the following actions, and then select Create:

    Setting Action
    Name text box Enter drop
    Public access level drop-down list Select Blob (anonymous read access for blobs only).
  7. Return to the Containers section, and then select the newly created drop container.

  8. On the Container blade, select Upload.

  9. In the Upload blob window, perform the following actions, and then select Upload:

    Setting Action
    Files section Select the Folder icon.
    File Explorer window Browse to Allfiles (F):\Allfiles\Labs\07\Starter, select the records.json file, and then select Open.
    Overwrite if files already exist check box Ensure that this check box is selected.

    Note: Wait for the blob to upload before you continue with this lab.

  10. Return to the Container blade, and then select the records.json blob in the list of blobs.

  11. On the Blob blade, find the blob metadata, and then copy the URL for the blob.

  12. On the taskbar, activate the shortcut menu for the Microsoft Edge icon, and then select New window.

  13. In the new browser window, refer to the URL that you copied for the blob.

  14. The JavaScript Object Notation (JSON) contents of the blob should now display. Close the browser window with the JSON contents.

  15. Return to the browser window with the Azure portal, and then close the Blob blade.

  16. Return to the Container blade, and then select Change access level.

  17. In the Change access level pop-up window, perform the following actions:

    1. In the Public access level drop-down list, select Private (no anonymous access).

    2. Select OK.

  18. On the taskbar, activate the shortcut menu for the Microsoft Edge icon, and then select New window.

  19. In the new browser window, refer to the URL that you copied for the blob.

  20. An error message indicating that the resource wasn’t found should now display.

    Note: If the error message doesn’t display, your browser might have cached the file. Select Ctrl+F5 to refresh the page until the error message displays.

Task 2: Pull and configure the Azure SDK for .NET

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

  2. Run the following command to change the current directory to the Allfiles (F):\Allfiles\Labs\07\Starter\func empty directory:

     cd F:\Allfiles\Labs\07\Starter\func
    
  3. Run the following command to add version 12.6.0 of the Azure.Storage.Blobs package from NuGet:

     dotnet add package Azure.Storage.Blobs --version 12.6.0
    

    Note: The Azure.Storage.Blobs NuGet package references the subset of the Azure SDK for .NET required to write code for Azure Blob Storage.

  4. Close the currently running Windows Terminal application.

  5. On the Start screen, select the Visual Studio Code tile.

  6. On the File menu, select Open Folder.

  7. In the File Explorer window that opens, browse to Allfiles (F):\Allfiles\Labs\07\Starter\func, and then select Select Folder.

  8. On the Explorer pane of the Visual Studio Code window, open the FileParser.cs file.

  9. Add a using directive for the Azure.Storage.Blobs namespace:

     using Azure.Storage.Blobs;
    
  10. Observe the FileParser.cs file, which should now include:

     using Azure.Storage.Blobs;
     using Microsoft.AspNetCore.Mvc;
     using Microsoft.Azure.WebJobs;
     using Microsoft.AspNetCore.Http;
     using System;
     using System.Threading.Tasks;
     public static class FileParser
     {
         [FunctionName("FileParser")]
         public static async Task<IActionResult> Run(
             [HttpTrigger("GET")] HttpRequest request)
         {
             string connectionString = Environment.GetEnvironmentVariable("StorageConnectionString");
             return new OkObjectResult(connectionString);
         }
     }
    

Task 3: Write Azure Blob Storage code using the Azure SDK for .NET

  1. Within the Run method of the FileParser class, delete the following line of code:

     return new OkObjectResult(connectionString);
    
  2. Still within the Run method, add the following code block to create a new instance of the BlobClient class by passing in your connectionString variable, a "drop" string value, and a "records.json" string value to the constructor:

     BlobClient blob = new BlobClient(connectionString, "drop", "records.json");
    
  3. Still within the Run method, add the following code block to use the BlobClient.DownloadAsync method to download the contents of the referenced blob asynchronously, and then store the result in a variable named response:

     var response = await blob.DownloadAsync();
    
  4. Still within the Run method, add the following code block to return the value of the various content stored in the content variable by using the FileStreamResult class constructor:

     return new FileStreamResult(response?.Value?.Content, response?.Value?.ContentType);
    
  5. Observe the FileParser.cs file again, which should now include:

     using Azure.Storage.Blobs;
     using Microsoft.AspNetCore.Mvc;
     using Microsoft.Azure.WebJobs;
     using Microsoft.AspNetCore.Http;
     using System;
     using System.Threading.Tasks;
     public static class FileParser
     {
         [FunctionName("FileParser")]
         public static async Task<IActionResult> Run(
             [HttpTrigger("GET")] HttpRequest request)
         {
             string connectionString = Environment.GetEnvironmentVariable("StorageConnectionString");
             BlobClient blob = new BlobClient(connectionString, "drop", "records.json");
             var response = await blob.DownloadAsync();
             return new FileStreamResult(response?.Value?.Content, response?.Value?.ContentType);
         }
     }
    
  6. Select Save to save your changes to the FileParser.cs file.

Task 4: Deploy and validate the Azure Functions app

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

  2. Run the following command to change the current directory to the Allfiles (F):\Allfiles\Labs\07\Starter\func empty directory:

     cd F:\Allfiles\Labs\07\Starter\func
    
  3. Run the following command to sign in to the Azure CLI:

     az login
    
  4. In the Microsoft Edge browser window, enter the email address and password for your Microsoft account, and then select Sign in.

  5. Return to the currently open Windows Terminal window. Wait for the sign-in process to finish.

  6. Run the following command to publish the function app project again:

     func azure functionapp publish <function-app-name>
    

    Note: As an example, if your Function App name is securefuncstudent, your command would be func azure functionapp publish securefuncstudent. You can review the documentation to [publish the local function app project][azure-functions-core-tools-publish-azure] using the Azure Functions Core Tools.

  7. Wait for the deployment to finalize before you move forward with the lab.

  8. Close the currently running Windows Terminal application.

  9. On the taskbar, select the Microsoft Edge icon, and then refer to the Azure portal (https://portal.azure.com).

  10. On the Azure portal’s navigation pane, select the Resource groups link.

  11. On the Resource groups blade, select the ConfidentialStack resource group.

  12. On the ConfidentialStack blade, select the securefunc[yourname] function app.

  13. On the App Service blade, select the Functions option in the Functions section.

  14. On the Functions pane, select the existing FileParser function.

  15. On the Function blade, select the Code + Test option in the Developer section.

  16. In the function editor, select Test/Run.

  17. In the pop-up dialog box that displays, in the HTTP method list, select GET.

  18. Select Run to test the function.

  19. Observe the results of the test run. The output will contain the content of the $/drop/records.json blob stored in your Azure Storage account.

Review

In this exercise, you used C# code to access a storage account, and then downloaded the contents of a blob.

Exercise 5: Clean up your subscription

Task 1: Open Azure Cloud Shell

  1. In the Azure portal, select the Cloud Shell icon Cloud Shell icon to open a new Bash session. If Cloud Shell defaults to a PowerShell session, select PowerShell, and in the drop-down menu, select Bash.

    Note: If this is the first time you’re starting Cloud Shell, when prompted to select either Bash or PowerShell, select PowerShell. When you’re presented with the You have no storage mounted message, select the subscription you’re using in this lab, and then select Create storage.

Task 2: Delete a resource group

  1. On the Cloud Shell pane, run the following command to delete the ConfidentialStack resource group:

     az group delete --name ConfidentialStack --no-wait --yes
    

    Note: The command runs asynchronously (as determined by the –no-wait parameter), so while you’ll be able to run another Azure CLI command immediately afterwards within the same Bash session, it’ll take a few minutes before the resource groups are actually removed.

  2. Close the Cloud Shell pane in the portal.

Task 3: Close the active application

  • Close the currently running Microsoft Edge application.

Review

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