共用方式為


使用 TypeScript 函式 API 管理 Azure 資源群組

在本教學課程中,您將使用 API 建立本機 TypeScript Azure 函式應用程式,以管理 Azure 資源群組,並將應用程式部署至 Azure。

特性與功能:

  • 在 Visual Studio Code 中建立本機 TypeScript Azure 函式應用程式專案
  • 在 Visual Studio Code 中建立函式 API 重複使用程式代碼
  • 從 Visual Studio Code 部署至 Azure Functions
  • 使用 Azure CLI 建立服務主體
  • 使用 Visual Studio Code 設定本機和遠端應用程式設定
  • 在本機和遠程環境中使用DefaultAzureCredential進行無密碼連線
  • 使用 Azure 身分識別和 Azure 資源管理 SDK 來管理 Azure 資源
  • 使用本機和雲端 API 在訂用帳戶中建立、刪除及列出資源群組

警告

本教學課程旨在快速採用,因此不會遵循預設的安全需求。 若要深入瞭解此案例與默認目標,請移至 安全性考慮

雖然原始程式碼是以 TypeScript 撰寫,但原始程式碼很簡單。 如果您熟悉使用 async/await 的新式 JavaScript,程式代碼會熟悉您。

必要條件

應用程式架構

應用程式提供下列 API 端點。

方法 URL 描述
POST、DELETE http://localhost:7071/api/resourcegroup 新增或刪除資源群組。 新增時,請包含標記(索引鍵/值組),以便稍後識別群組的用途。
GET http://localhost:7071/api/resourcegroups 列出訂用帳戶中的所有資源群組。
GET http://localhost:7071/api/resources 列出訂用帳戶或資源群組中的所有資源。

雖然這些端點是公用的,但您應該先使用驗證和授權保護您的 API 端點,再部署到您的實時環境。

此應用程式受限於訂用帳戶,因為這是建立服務主體時所指定的範圍。

1.準備您的環境

您必須準備本機和雲端環境,才能使用 Azure 身分識別 SDK。

登入 Azure CLI

在bash終端機中,使用下列命令登入 Azure CLI:

az login

取得您的 Azure 訂用帳戶識別碼

  1. 在bash終端機中,取得您的訂用帳戶,並尋找您想要使用的訂用帳戶標識碼。 下列查詢會傳回依訂用帳戶名稱排序的訂用帳戶標識碼、訂用帳戶名稱和租用戶標識碼。

    az account list --query "sort_by([].{Name:name, SubscriptionId:id, TenantId:tenantId}, &Name)" --output table
    
  2. 將訂用帳戶標識碼複製到先前的臨時檔。 稍後您將需要此設定。

建立 Azure 服務主體

Azure 服務主體可讓您存取 Azure,而不需要使用您的個人用戶認證。 在本教學課程中,服務主體可以在本機和雲端環境中使用。 在企業環境中,您會想要針對每個環境個別的服務主體。

  1. 判斷服務主體 名稱 格式,以便稍後輕鬆找到您的服務主體。 例如,數種格式構想如下:

    • 您的項目和擁有者: resource-management-john-smith
    • 您的部門與日期: IT-2021-September
  2. 在bash終端機中,使用 az ad sp create-for-rbac 建立您的服務主體。 使用您的訂用帳戶 ID 來取代 <SUBSCRIPTION-ID>

    az ad sp create-for-rbac --name YOUR-SERVICE-PRINCIPAL-NAME --role Contributor --scopes /subscriptions/<SUBSCRIPTION-ID>
    
  3. 將整個輸出結果複製到臨時檔。 稍後您將需要這些設定。

    {
      "appId": "YOUR-SERVICE-PRINCIPAL-ID",
      "displayName": "YOUR-SERVICE-PRINCIPAL-NAME",
      "name": "http://YOUR-SERVICE-PRINCIPAL-NAME",
      "password": "YOUR-SERVICE-PRINCIPAL-PASSWORD",
      "tenant": "YOUR-TENANT-ID"
    }
    

2.在 Visual Studio Code 中建立本機 Azure 函式應用程式

在 Visual Studio Code 中建立 Azure 函式應用程式來管理 Azure 資源群組。

建立函式應用程式

使用 Visual Studio Code 建立本機函式應用程式。

  1. 在bash終端機中,建立並變更為新的目錄:

    mkdir my-function-app && cd my-function-app
    
  2. 在 bash 終端機中,開啟 Visual Studio Code:

    code .
    
  3. 開啟 Visual Studio Code 命令選擇區:Ctrl + Shift + p。

  4. 輸入 Azure Functions: create new project。 使用下表完成提示:

    提示
    選取將包含函式項目的資料夾 選取預設的 (目前) 目錄
    選取語言 選取 [TypeScript]
    選取 TypeScript 程式設計模型 選取 模型 V4 (預覽)
    為專案的第一個函式選取範本 選取 [HTTP 觸發程序]
    建立新的 HTTP 觸發程式 輸入的 resourcegroupsAPI 名稱。
    授權等級 選取 [匿名]。 如果您在本文之後繼續進行此專案,請將授權層級變更為 函式。 深入瞭解 函式層級授權

    會建立專案重複使用,並安裝相依性。

將服務主體設定新增至local.settings.json檔案

  1. ./local.settings.json開啟專案根目錄中的 檔案,並使用下列五個環境變數新增您的 VALUES 區段。

    {
      "IsEncrypted": false,
      "Values": {
        "AzureWebJobsStorage": "",
        "FUNCTIONS_WORKER_RUNTIME": "node",
        "AzureWebJobsFeatureFlags": "EnableWorkerIndexing",
        "AZURE_CLIENT_ID": "REPLACE-WITH-SERVICE-PRINCIPAL-APPID",
        "AZURE_CLIENT_SECRET": "REPLACE-WITH-SERVICE-PRINCIPAL-PASSWORD",
        "AZURE_SUBSCRIPTION_ID":"REPLACE-WITH-SUBSCRIPTION-ID",
        "AZURE_TENANT_ID":"REPLACE-WITH-SERVICE-PRINCIPAL-TENANT",
        "NODE_ENV":"development"
      }
    }
    
  2. 請參閱上一節中的設定以新增值。 這些環境變數是 內容使用 DefaultAzureCredential 的必要環境變數。

    • AZURE_TENANT_IDtenant 來自上述服務主體輸出。
    • AZURE_CLIENT_IDappId 來自上述服務主體輸出。
    • AZURE_CLIENT_SECRETpassword 來自上述服務主體輸出。
  3. 您也需要設定訂用帳戶標識碼。 必須使用 Azure SDK 進行資源管理。

    • AZURE_SUBSCRIPTION_ID:包含資源群組的預設訂用帳戶。

本機 Git 會基於目的忽略local.settings.json檔案,因此您不會不小心將它認可至原始程式碼。

安裝適用於 Azure 身分識別和資源管理的 npm 相依性

在 Visual Studio Code 整合式 Bash 終端機中,安裝 Azure SDK 相依性以進行 Azure 身分識別和資源管理。

npm install @azure/identity @azure/arm-resources

使用 JavaScript 列出訂用帳戶中的所有資源群組

  1. 開啟檔案, ./src/functions/resourcegroups.ts 並以下列內容取代內容:

    import { ResourceGroup } from '@azure/arm-resources';
    import {
      app,
      HttpRequest,
      HttpResponseInit,
      InvocationContext
    } from '@azure/functions';
    import {
      createResourceGroup,
      deleteResourceGroup
    } from '../lib/azure-resource-groups';
    import { processError } from '../lib/error';
    
    export async function resourcegroup(
      request: HttpRequest,
      context: InvocationContext
    ): Promise<HttpResponseInit> {
      try {
        console.log(JSON.stringify(request.query));
        console.log(JSON.stringify(request.params));
    
        const name: string = request.query.get('name');
        const location: string = request.query.get('location');
        console.log(`name: ${name}`);
        console.log(`location: ${location}`);
    
        switch (request.method) {
          case 'POST': // wait for create to complete before returning
            if (!name || !location) {
              return { body: 'Missing required parameters.', status: 400 };
            }
    
            if (request.headers.get('content-type') === 'application/json') {
              // create with tags
    
              const body: Record<string, unknown> =
                (await request.json()) as Record<string, string>;
              const tags: Record<string, string> = body?.tags
                ? (body?.tags as Record<string, string>)
                : null;
              const resourceGroup: ResourceGroup = await createResourceGroup(
                name,
                location,
                tags
              );
              return { jsonBody: resourceGroup, status: 200 };
            } else {
              // create without tags
    
              const resourceGroup: ResourceGroup = await createResourceGroup(
                name,
                location,
                null
              );
              return { jsonBody: resourceGroup, status: 200 };
            }
    
          case 'DELETE': // wait for delete to complete before returning
            if (!name) {
              return { body: 'Missing required parameters.', status: 400 };
            }
            await deleteResourceGroup(name);
            return { status: 204 };
        }
      } catch (err: unknown) {
        return processError(err);
      }
    }
    
    app.http('resourcegroup', {
      methods: ['DELETE', 'POST'],
      authLevel: 'anonymous',
      handler: resourcegroup
    });
    

    此檔案會回應 API 要求, /api/resourcegroups 並傳回訂用帳戶中所有資源群組的清單。

  2. 在名為 libsrc建立子目錄,並在該目錄中建立名為 azure-resource-groups.ts的新檔案。

  3. 將下列程式代碼複製到 ./src/lib/azure-resource-groups.ts 檔案中:

    // Include npm dependencies
    import {
      ResourceGroup, ResourceManagementClient
    } from '@azure/arm-resources';
    import { DefaultAzureCredential } from '@azure/identity';
    import { getSubscriptionId } from './environment-vars';
    
    const subscriptionId = getSubscriptionId();
    
    // Create Azure authentication credentials
    const credentials = new DefaultAzureCredential();
    
    // Create Azure SDK client for Resource Management such as resource groups
    const resourceManagement = new ResourceManagementClient(
      credentials,
      subscriptionId
    );
    
    // all resources groups in subscription
    export const listResourceGroups = async (): Promise<{
      list: ResourceGroup[];
      subscriptionId: string;
    }> => {
      const list: ResourceGroup[] = [];
      for await (const resourceGroup of resourceManagement.resourceGroups.list()) {
        list.push(resourceGroup);
      }
      return {
        subscriptionId,
        list
      };
    };
    export const createResourceGroup = async (
      resourceGroupName: string,
      location: string,
      tags: { [propertyName: string]: string }
    ): Promise<ResourceGroup> => {
      const resourceGroupParameters = {
        location: location,
        tags
      };
    
      return await resourceManagement.resourceGroups.createOrUpdate(
        resourceGroupName,
        resourceGroupParameters
      );
    };
    export const deleteResourceGroup = async (
      resourceGroupName: string
    ): Promise<void> => {
      return await resourceManagement.resourceGroups.beginDeleteAndWait(
        resourceGroupName
      );
    };
    

    此檔案會完成下列作業:

    • 取得訂用帳戶標識碼
    • 建立 DefaultAzureCredential 內容
    • 建立使用資源管理 SDK 所需的 ResourceManagementClient。
    • 取得訂用帳戶中的所有資源群組。
  4. 在名為 environment-vars.ts./src/lib目錄中建立新的檔案,並將下列程式代碼複製到該檔案中。

    export const checkAzureAuth = () => {
      // The following code is only used to check you have environment
      // variables configured. The DefaultAzureCredential reads your
      // environment - it doesn't read these variables.
      const tenantId = process.env['AZURE_TENANT_ID'];
      if (!tenantId)
        throw Error('AZURE_TENANT_ID is missing from environment variables.');
      const clientId = process.env['AZURE_CLIENT_ID'];
      if (!clientId)
        throw Error('AZURE_CLIENT_ID is missing from environment variables.');
      const secret = process.env['AZURE_CLIENT_SECRET'];
      if (!secret)
        throw Error('AZURE_CLIENT_SECRET is missing from environment variables.');
    };
    
    export const getSubscriptionId = (): string => {
      checkAzureAuth();
    
      // Get subscription from environment variables
      const subscriptionId = process.env['AZURE_SUBSCRIPTION_ID'];
      if (!subscriptionId)
        throw Error('Azure Subscription is missing from environment variables.');
      return subscriptionId;
    };
    

    此檔案會先檢查環境變數,再傳回訂用帳戶標識碼。

  5. 在名為 error.ts./src/lib目錄中建立新的檔案,並將下列程式代碼複製到該檔案中。

    export function processError(err: unknown): any {
      if (typeof err === 'string') {
        return { body: err.toUpperCase(), status: 500 };
      } else if (
        err['stack'] &&
        process.env.NODE_ENV.toLowerCase() !== 'production'
      ) {
        return { jsonBody: { stack: err['stack'], message: err['message'] } };
      } else if (err instanceof Error) {
        return { body: err.message, status: 500 };
      } else {
        return { body: JSON.stringify(err) };
      }
    }
    

    此檔案會傳回具有錯誤訊息的 500 錯誤。 如果變數未設定為 productionNODE_ENV則會傳回堆疊。

測試本機函式

  1. 在 Visual Studio Code 整合式終端機中,執行本機專案:

    npm start
    
  2. 等候整合式 bash 終端機顯示執行中函式的 URL。

    當 Azure 函式在本機執行,並在函式應用程式中顯示 API 的本機 URL 時,Visual Studio Code 整合式 Bash 終端機的部分螢幕快照。

  3. 在 Visual Studio Code 中開啟第二個整合式 bash 終端機 Ctrl + Shift + 5,並使用下列 GET cURL 命令來使用 API:

    curl http://localhost:7071/api/resourcegroups
    

    如果您的訂用帳戶中有許多資源群組,您可以透過管線將輸出傳送至檔案,以方便檢閱。

    curl http://localhost:7071/api/resourcegroups > resourcegroups.json
    
  4. 回應包含 subscriptionIdlist 該訂用帳戶中所有資源群組的 。

    {
      "subscriptionId": "ABC123",
      "list": [
            {
              "id": "/subscriptions/ABC123/resourceGroups/vmagelo-cloudshell",
              "name": "jsmith-cloudshell",
              "type": "Microsoft.Resources/resourceGroups",
              "properties": {
                "provisioningState": "Succeeded"
              },
              "location": "westeurope"
            },
            ... REMOVED FOR BREVITY ...
        ]
    }
    

疑難排解

如果您無法完成本文,請檢查下表中是否有問題。 如果您的問題未列在表格中,請在此文件頁面上開啟問題。

問題 修正
應用程式未啟動。 檢閱錯誤。 請確定您已安裝必要的相依性。
應用程式已啟動,但您無法取得 200 回應。 請確定您的 curl 命令是從正確的本機路由要求。
API 傳回 200 回應,但未傳回任何結果。 使用適用於 Azure 資源的 Visual Studio Code 擴充功能來確認您的訂用帳戶具有任何資源群組。 如果您沒有看到任何資源群組,請不要擔心。 本教學課程會新增 API,以在您的訂用帳戶中建立和刪除資源群組。 此 API 會在第一次將原始程式碼部署至 Azure 之後新增,讓您瞭解如何重新部署程式代碼。

3.建立雲端式 Azure 函式應用程式

  1. 在 Visual Studio Code 中,選取 Azure 圖示以開啟 Azure Explorer

  2. 選取 + 圖示以在 Azure 雲端中建立新的 Azure 函式應用程式。

    Visual Studio Code 的 Azure Explorer 螢幕快照,其中已醒目提示 Azure 函式應用程式圖示。

  3. 選取 [在 Azure 中建立函數應用程式]

  4. 輸入新函式應用程式的全域唯一 名稱 。 名稱在所有 Azure 函式中都必須是唯一的。 例如: jsmith-rg-management

  5. 選取您在建立本機函式應用程式時選取的相同 Node.js 18+ LTS 執行時間

  6. 選取靠近您的地理位置,例如美國西部 3

  7. 等候建立資源。 您可以觀看 Azure:活動記錄以取得詳細數據

    顯示資源建立狀態的 Visual Studio Code Azure 活動記錄螢幕快照。

4.設定雲端式 Azure 函式應用程式

您必須設定 Azure 應用程式設定,以連線到 Azure 函式應用程式。 在本機,這些設定位於您的 local.settings.json 檔案中。 此程式會將這些值新增至您的雲端應用程式。

  1. 在 Visual Studio Code 的 Azure 總管中,於 [資源] 區段中,展開 [函式應用程式],然後選取您的函式應用程式。

  2. 以滑鼠右鍵按兩下 [ 應用程式設定 ],然後選取 [ 新增設定]。

  3. 使用完全相同的名稱和值,從 中 local.settings.json 新增四個值。

    • AZURE_TENANT_IDtenant 來自上述服務主體輸出。
    • AZURE_CLIENT_IDappId 來自上述服務主體輸出。
    • AZURE_CLIENT_SECRETpassword 來自上述服務主體輸出。
    • AZURE_SUBSCRIPTION_ID:包含資源群組的預設訂用帳戶。
    • AzureWebJobsFeatureFlags:EnableWorkerIndexing

Visual Studio Code 的 Azure 總管部分螢幕快照,其中顯示遠端/雲端函式的應用程式設定。

5.部署 Resource Manager 函式應用程式

在 Visual Studio Code 中部署 Azure 函式應用程式來管理 Azure 資源群組。

使用 Visual Studio Code 擴充功能部署至裝載環境

  1. 在 VS Code 中 local.settings.json ,開啟檔案,使其可見。 這可讓後續步驟更容易複製這些名稱和值。

  2. 選取 Azure 標誌以開啟 Azure Explorer,然後在 [函式] 底下選取要部署應用程式的雲端圖示。

    Visual Studio Code 本機工作區區域的螢幕快照,其中已醒目提示雲端部署圖示。

    或者,您可以使用 Ctrl + Shift + p 開啟命令選擇區,然後輸入 deploy to function app並執行 Azure Functions:部署至函式應用程式命令來部署。

  3. 選取 [部署至函式應用程式]。

  4. 選取您在上一節中建立的函式應用程式名稱。

  5. 當系統詢問您是否確定要部署時,請選取 [ 部署]。

  6. Azure FunctionsVS Code 輸出面板會顯示進度。 部署時,會部署整個 Functions 應用程式,因此會一次部署所有個別函式的變更。

驗證 Functions 應用程式可供瀏覽器使用

  1. 在 Visual Studio Code 中,使用 Azure Functions 總管、展開 Azure 訂用帳戶的節點、展開 Functions 應用程式的節點,然後展開 Functions (只讀) 。 以滑鼠右鍵按下函式名稱,然後選取 [ 複製函式 URL]:

    Visual Studio Code 的 Azure 總管部分螢幕快照,其中顯示複製函式 URL 的位置。

  2. 將 URL 貼到瀏覽器中,然後按 Enter 以從雲端 API 要求資源群組清單。

6.將 API 新增至函式應用程式並重新部署至 Azure

新增下列 API,然後在 Visual Studio Code 中重新部署您的 Azure 函式應用程式:

  • 新增和刪除資源群組
  • 列出資源群組或訂用帳戶中的資源。

在本教學課程中,您已使用一個 API 建立本機函式應用程式,以列出訂用帳戶的資源群組,並將該應用程式部署至 Azure。 身為 Azure 開發人員,您可能會想要在程式自動化管線中建立或刪除資源群組。

為您的函式應用程式建立資源群組 API

使用適用於 Azure Functions 的 Visual Studio Code 擴充功能,將 TypeScript 檔案新增至函式應用程式,以建立和刪除資源群組。

  1. 開啟 Visual Studio Code 命令選擇區:Ctrl + Shift + p。

  2. 輸入 Azure Functions: Create Function ,然後按 Enter 鍵以開始程式。

  3. 使用下表建立 /api/resourcegroup API:

    提示
    選取函式的範本 HTTP 觸發程序
    提供函式名稱 resourcegroup
    授權等級 選取 [匿名]。 如果您繼續執行此專案,請將授權層級變更為 函式。 深入瞭解 函式層級授權
  4. 開啟 , ./src/functions/resourcegroup.ts 並以下列原始程式碼取代整個檔案。

    import { ResourceGroup } from '@azure/arm-resources';
    import {
      app,
      HttpRequest,
      HttpResponseInit,
      InvocationContext
    } from '@azure/functions';
    import {
      createResourceGroup,
      deleteResourceGroup
    } from '../lib/azure-resource-groups';
    import { processError } from '../lib/error';
    
    export async function resourcegroup(
      request: HttpRequest,
      context: InvocationContext
    ): Promise<HttpResponseInit> {
      try {
        console.log(JSON.stringify(request.query));
        console.log(JSON.stringify(request.params));
    
        const name: string = request.query.get('name');
        const location: string = request.query.get('location');
        console.log(`name: ${name}`);
        console.log(`location: ${location}`);
    
        switch (request.method) {
          case 'POST': // wait for create to complete before returning
            if (!name || !location) {
              return { body: 'Missing required parameters.', status: 400 };
            }
    
            if (request.headers.get('content-type') === 'application/json') {
              // create with tags
    
              const body: Record<string, unknown> =
                (await request.json()) as Record<string, string>;
              const tags: Record<string, string> = body?.tags
                ? (body?.tags as Record<string, string>)
                : null;
              const resourceGroup: ResourceGroup = await createResourceGroup(
                name,
                location,
                tags
              );
              return { jsonBody: resourceGroup, status: 200 };
            } else {
              // create without tags
    
              const resourceGroup: ResourceGroup = await createResourceGroup(
                name,
                location,
                null
              );
              return { jsonBody: resourceGroup, status: 200 };
            }
    
          case 'DELETE': // wait for delete to complete before returning
            if (!name) {
              return { body: 'Missing required parameters.', status: 400 };
            }
            await deleteResourceGroup(name);
            return { status: 204 };
        }
      } catch (err: unknown) {
        return processError(err);
      }
    }
    
    app.http('resourcegroup', {
      methods: ['DELETE', 'POST'],
      authLevel: 'anonymous',
      handler: resourcegroup
    });
    
  5. 檔案 ./src/lib/azure-resource-groups.ts 已經包含要新增和刪除資源群組的程序代碼。

為您的函式應用程式建立資源 API

使用適用於 Azure Functions 的 Visual Studio Code 擴充功能,將 TypeScript 檔案新增至函式應用程式,以列出資源群組中的資源。

  1. 開啟 Visual Studio Code 命令選擇區:Ctrl + Shift + p。

  2. 輸入 Azure Functions: Create Function ,然後按 Enter 鍵以開始程式。

  3. 使用下表來建立 /api/resources API:

    提示
    選取函式的範本 HTTP 觸發程序
    提供函式名稱 resources
    授權等級 選取 [匿名]。 如果您繼續執行此專案,請將授權層級變更為 函式。 深入瞭解 函式層級授權
  4. 開啟 , ./src/functions/resources.ts 並以下列原始程式碼取代整個檔案。

    import {
      app,
      HttpRequest,
      HttpResponseInit,
      InvocationContext
    } from '@azure/functions';
    import {
      listResourceByResourceGroup, listResourceBySubscription
    } from '../lib/azure-resource';
    import { processError } from '../lib/error';
    
    export async function resources(
      request: HttpRequest,
      context: InvocationContext
    ): Promise<HttpResponseInit> {
      try {
        const resourceGroupName: string = request.query.get('resourceGroupName');
        context.log(`resourceGroupName: '${resourceGroupName}'`);
    
        if (resourceGroupName) {
          const resourcesByName = await listResourceByResourceGroup(
            resourceGroupName
          );
          return { jsonBody: resourcesByName };
        } else {
          const resourcesBySubscription = await listResourceBySubscription();
          return { jsonBody: resourcesBySubscription };
        }
      } catch (err: unknown) {
        return processError(err);
      }
    }
    app.http('resources', {
      methods: ['GET'],
      authLevel: 'anonymous',
      handler: resources
    });
    
  5. 建立檔案, ./src/lib/azure-resource.ts 並將下列程式代碼複製到其中,以列出資源群組中的資源。

    // Include npm dependencies
    import { Resource, ResourceManagementClient } from '@azure/arm-resources';
    import { DefaultAzureCredential } from '@azure/identity';
    import { getSubscriptionId } from './environment-vars';
    
    const subscriptionId = getSubscriptionId();
    
    // Create Azure authentication credentials
    const credentials = new DefaultAzureCredential();
    
    // Create Azure SDK client for Resource Management such as resource groups
    const resourceManagement = new ResourceManagementClient(
      credentials,
      subscriptionId
    );
    
    // all resources groups in subscription
    export const listResourceBySubscription = async (): Promise<{
      list: Resource[];
      subscriptionId: string;
    }> => {
      const list: Resource[] = [];
    
      for await (const resource of resourceManagement.resources.list()) {
        list.push(resource);
      }
    
      return {
        subscriptionId,
        list
      };
    };
    // all resources groups in resource group
    export const listResourceByResourceGroup = async (
      resourceGroupName: string
    ): Promise<{
      list: Resource[];
      subscriptionId: string;
      resourceGroupName: string;
    }> => {
      const list: Resource[] = [];
    
      for await (const resource of resourceManagement.resources.listByResourceGroup(
        resourceGroupName
      )) {
        list.push(resource);
      }
    
      return {
        subscriptionId,
        resourceGroupName,
        list
      };
    };
    

啟動本機函式應用程式並測試新的 API

  1. 在 Visual Studio Code 整合式終端機中,執行本機專案:

    npm start
    
  2. 等候整合式 bash 終端機顯示執行中函式的 URL。

    當 Azure 函式在本機執行,並在函式應用程式中顯示 API 的本機 URL 時,Visual Studio Code 整合式 Bash 終端機的部分螢幕快照。

  3. 在不同的整合式 bash 終端機中使用下列 curl 命令來呼叫您的 API,以將資源群組新增至您的訂用帳戶。 變更資源群組的名稱,以使用您自己的命名慣例。

    curl -X POST 'http://localhost:7071/api/resourcegroup?name=my-test-1&location=westus'
    
    curl -X POST 'http://localhost:7071/api/resourcegroup?name=my-test-1&location=westus' \
      -H 'content-type: application/json' \
      -d '{"tags": {"a":"b"}}'
    
  4. 使用下列 curl 命令來查看訂用帳戶中列出的新資源群組。

    curl http://localhost:7071/api/resource-groups
    
  5. 使用下列 curl 命令來刪除您剛才新增的資源群組。

    curl -X DELETE 'http://localhost:7071/api/resourcegroup?name=my-test-1' \
      -H 'Content-Type: application/json'
    

使用新的 API 將函式應用程式重新部署至 Azure

  1. 在 VS Code 中,使用 Ctrl + Shift + p 開啟 [命令選擇區],輸入 deploy to function app並執行 [Azure Functions:部署至函式應用程式] 命令來部署。

  2. 從應用程式清單中選取您的函式應用程式。

  3. 從彈出視窗中選取 [部署 ]。

  4. 等到部署完成為止。

使用瀏覽器驗證函式 API

使用先前的 cURL 命令,將 localhost 位址取代為您的 Azure 函式資源名稱, http://localhost:7071 例如 https://myfunction.azurewebsites.net

7.檢視和查詢函式應用程式記錄

在 Azure 入口網站 中檢視和查詢 Azure 函式應用程式記錄。

查詢您的 Azure 函式記錄

使用 Azure 入口網站 來檢視和查詢函式記錄。

  1. 在 VS Code 中,選取 Azure 標誌以開啟 Azure Explorer,然後在 [Functions] 底下,以滑鼠右鍵按兩下您的函式應用程式,然後選取 [在入口網站中開啟]。

    這會開啟 Azure 函式 Azure 入口網站。

  2. 從 [設定] 中 選取 [Application Insights ],然後選取 [ 檢視 Application Insights 數據]。

    顯示功能表選項的瀏覽器螢幕快照。從 [設定] 中選取 [Application Insights],然後選取 [檢視 Application Insights 數據]。

    此連結會帶您前往使用 VS Code 建立 Azure 函式時為您建立的個別計量資源。

  3. 在 [監視] 區段中選取 [ 記錄 ]。 如果出現 [ 查詢 ] 彈出視窗,請選取 快顯右上角的 X 以關閉它。

  4. 在 [架構和篩選] 窗格中的 [數據表] 索引標籤上,按兩下追蹤數據表。

    這會在查詢視窗中輸入 Kusto 查詢traces

  5. 編輯查詢以搜尋 API 呼叫:

    traces 
    | where message startswith "Executing "
    
  6. 選取執行

    如果記錄檔未顯示任何結果,可能是因為 HTTP 要求與 Azure Function 與 Kusto 中的記錄可用性之間有幾分鐘的延遲。 請稍候幾分鐘,然後再次執行查詢。

    顯示追蹤數據表 Azure 入口網站 Kusto 查詢結果的瀏覽器螢幕快照。

    因為當您建立 Azure 函式應用程式時,已為您新增 Application Insights 資源,因此您不需要執行任何額外的動作來取得此記錄資訊:

    • 函式應用程式已為您新增ApplicationInsights
    • 查詢工具包含在 Azure 入口網站 中。
    • 您可以選取 traces ,而不必學習撰寫 Kusto 查詢 ,以從您的記錄取得最低資訊。

8.清除 Azure 資源

刪除資源群組

  1. 在 VS Code 中,選取 Azure 標誌以開啟 Azure Explorer,然後在 [Functions] 底下,以滑鼠右鍵按兩下您的函式應用程式,然後選取 [在入口網站中開啟]。這會開啟 Azure 函式 Azure 入口網站。

  2. 在 [概觀]段中,尋找並選取資源組名。 此動作會帶您前往 Azure 入口網站 中的資源群組。

  3. 資源群組頁面會列出與此教學課程相關聯的所有資源。

  4. 在頂端功能表中,選取 [刪除資源群組]

  5. 在側邊功能表中,輸入資源群組的名稱,然後選取 [ 刪除]。

刪除服務主體

若要刪除服務主體,請執行下列命令。 將取代 <YOUR-SERVICE-PRINCIPAL-NAME> 為您的服務主體名稱。

az ad sp delete --id <YOUR-SERVICE-PRINCIPAL-NAME>

範例指令碼

安全性考量

此解決方案作為初學者教學課程,不會示範預設的安全做法。 這是刻意可讓您成功部署解決方案。 成功部署后的下一個步驟是保護資源。 此解決方案會使用三個 Azure 服務,每個服務都有自己的安全性功能和預設設定的考慮:

下一步