教程:使用 Azure CLI 将数据 API 生成器部署到 Azure 容器应用

数据 API 生成器可以快速部署到 Azure 服务(如 Azure 容器应用)作为应用程序堆栈的一部分。 在本教程中,在将数据 API 生成器部署到 Azure 时,使用 Azure CLI 自动执行常见任务。 首先,使用数据 API 生成器生成容器映像,并将其存储在Azure 容器注册表中。 然后,使用后备Azure SQL数据库将容器映像部署到 Azure 容器应用。 整个教程使用托管标识对每个组件进行身份验证。

在本教程中,你将了解:

  • 使用基于角色的访问控制权限Create托管标识
  • 使用示例 AdventureWorksLT 数据集部署Azure SQL
  • 在 Azure 容器注册表 中暂存容器映像
  • 使用数据 API 生成器容器映像部署 Azure 容器应用

如果没有 Azure 订阅,请在开始之前创建一个免费帐户

先决条件

  • Azure 订阅
  • Azure Cloud Shell
    • Azure Cloud Shell 是一个可通过浏览器使用的交互式 shell 环境。 使用此 shell 及其预安装的命令运行本文中的代码,而无需在本地环境中安装任何内容。 若要启动 Azure Cloud Shell,请执行以下操作:
      • 在本文中的代码或命令块中选择“ 试用 ”。 选择“试用”不会自动将代码或命令复制到Cloud Shell。
      • 转到 https://shell.azure.com,或选择“启动Cloud Shell”。
      • Azure 门户 () 的菜单栏中选择Cloud Shell https://portal.azure.com

Create容器应用

首先,使用系统分配的托管标识创建 Azure 容器应用实例。 此标识最终被授予访问Azure SQL和Azure 容器注册表的基于角色的访问控制权限。

  1. Create一个通用SUFFIX变量,用于本教程后面的多个资源名称。

    let SUFFIX=$RANDOM*$RANDOM
    
  2. Create一个LOCATION变量,其中包含在本教程中选择使用的 Azure 区域。

    LOCATION="<azure-region>"
    

    注意

    例如,如果要部署到 美国西部 区域,可以使用此脚本。

    LOCATION="westus"
    

    有关当前订阅支持的区域的列表,请使用 az account list-locations

    az account list-locations --query "[].{Name:displayName,Slug:name}" --output table
    

    有关详细信息,请参阅 Azure 区域

  3. 使用资源组名称Create名为 RESOURCE_GROUP_NAME 的变量。 对于本教程,建议使用 msdocs-dab-*。 在本教程中,将多次使用此值。

    RESOURCE_GROUP_NAME="msdocs-dab$SUFFIX"    
    
  4. 使用 az group createCreate新的资源组。

    az group create \
      --name $RESOURCE_GROUP_NAME \
      --location $LOCATION \
      --tag "source=msdocs-dab-tutorial"
    
  5. Create名为 API_CONTAINER_NAMECONTAINER_ENV_NAME 的变量,以及为 Azure 容器应用实例生成的唯一名称。 你将在整个教程中使用这些变量。

    API_CONTAINER_NAME="api$SUFFIX"
    CONTAINER_ENV_NAME="env$SUFFIX"
    
  6. 使用 az containerapp env create 创建新的 Azure 容器应用环境。

    az containerapp env create \ 
      --resource-group $RESOURCE_GROUP_NAME \
      --name $CONTAINER_ENV_NAME \
      --logs-destination none \
      --location $LOCATION
    
  7. 使用 Create新的容器应用mcr.microsoft.com/azure-databases/data-api-builderDAB 容器映像和 az containerapp create 命令。 此容器应用成功运行,但未连接到任何数据库。

    az containerapp create \ 
      --resource-group $RESOURCE_GROUP_NAME \
      --environment $CONTAINER_ENV_NAME \
      --name $API_CONTAINER_NAME \
      --image "mcr.microsoft.com/azure-databases/data-api-builder" \
      --ingress "external" \
      --target-port "5000" \
      --system-assigned
    
  8. 使用 az identity show 获取托管标识的主体标识符,并将值存储在名为 的MANAGED_IDENTITY_PRINCIPAL_ID变量中。

    MANAGED_IDENTITY_PRINCIPAL_ID=$( \
      az containerapp show \ 
        --resource-group $RESOURCE_GROUP_NAME \
        --name $API_CONTAINER_NAME \
        --query "identity.principalId" \
        --output "tsv" \
    )
    

    提示

    始终可以检查此命令的输出。

    echo $MANAGED_IDENTITY_PRINCIPAL_ID
    

分配权限

现在,向系统分配的托管标识分配从Azure SQL和Azure 容器注册表读取数据的权限。 此外,为标识分配写入Azure 容器注册表的权限。

  1. Create名为 的RESOURCE_GROUP_ID变量来存储资源组的标识符。 使用 az group show获取标识符。 在本教程中,将多次使用此变量。

    RESOURCE_GROUP_ID=$( \
      az group show \
        --name $RESOURCE_GROUP_NAME \
        --query "id" \
        --output "tsv" \
    )
    

    提示

    始终可以检查此命令的输出。

    echo $RESOURCE_GROUP_ID
    
  2. 使用 az role assignment createAcrPush 角色分配给帐户,以便可以将容器推送到Azure 容器注册表。

    CURRENT_USER_PRINCIPAL_ID=$( \
      az ad signed-in-user show \
        --query "id" \
        --output "tsv" \
    )
    
    # AcrPush
    az role assignment create \
      --assignee $CURRENT_USER_PRINCIPAL_ID \
      --role "8311e382-0749-4cb8-b61a-304f252e45ec" \
      --scope $RESOURCE_GROUP_ID
    
  3. 再次使用 az role assignment createAcrPull 角色分配给托管标识。 此分配允许托管标识从Azure 容器注册表拉取容器映像。 托管标识最终将分配给 Azure 容器应用实例。

    # AcrPull    
    az role assignment create \
      --assignee $MANAGED_IDENTITY_PRINCIPAL_ID \
      --role "7f951dda-4ed3-4680-a7ca-43fe172d538d" \
      --scope $RESOURCE_GROUP_ID
    

部署数据库

接下来,在 Azure SQL 服务中部署新的服务器和数据库。 数据库使用 AdventureWorksLT 示例数据集。

  1. Create名为 的SQL_SERVER_NAME变量,该变量具有Azure SQL服务器实例的唯一生成名称。 本部分稍后将使用此变量。

    SQL_SERVER_NAME="srvr$SUFFIX"
    
  2. 使用 az sql server createCreate新的 Azure SQL 服务器资源。 将托管标识配置为此服务器的管理员。

    az sql server create \
      --resource-group $RESOURCE_GROUP_NAME \
      --name $SQL_SERVER_NAME \
      --location $LOCATION \
      --enable-ad-only-auth \
      --external-admin-principal-type "User" \
      --external-admin-name $API_CONTAINER_NAME \
      --external-admin-sid $MANAGED_IDENTITY_PRINCIPAL_ID
    
  3. 使用 az sql server firewall-rule create 创建防火墙规则以允许从 Azure 服务进行访问。

    az sql server firewall-rule create \
      --resource-group $RESOURCE_GROUP_NAME \
      --server $SQL_SERVER_NAME \
      --name "AllowAzure" \
      --start-ip-address "0.0.0.0" \
      --end-ip-address "0.0.0.0"
    
  4. 使用 az sql db create 在名为 adventureworks的Azure SQL服务器中创建数据库。 将数据库配置为使用 AdventureWorksLT 示例数据。

    az sql db create \
      --resource-group $RESOURCE_GROUP_NAME \
      --server $SQL_SERVER_NAME \
      --name "adventureworks" \
      --sample-name "AdventureWorksLT"
    
  5. Create名为 SQL_CONNECTION_STRING 的变量,adventureworks其中包含Azure SQL服务器实例中数据库的连接字符串。 使用 az sql server show使用 服务器的完全限定域名构造连接字符串。 本教程稍后将使用此变量。

    SQL_SERVER_ENDPOINT=$( \
      az sql server show \
        --resource-group $RESOURCE_GROUP_NAME \
        --name $SQL_SERVER_NAME \
        --query "fullyQualifiedDomainName" \
        --output "tsv" \
    )
    
    SQL_CONNECTION_STRING="Server=$SQL_SERVER_ENDPOINT;Database=adventureworks;Encrypt=true;Authentication=Active Directory Default;"
    

    提示

    始终可以检查此命令的输出。

    echo $SQL_CONNECTION_STRING
    

生成容器映像

接下来,使用 Dockerfile 生成容器映像。 然后将该容器映像部署到新创建的 Azure 容器注册表 实例。

  1. Create名为 的CONTAINER_REGISTRY_NAME变量,该变量具有Azure 容器注册表实例的唯一生成名称。 本部分稍后将使用此变量。

    CONTAINER_REGISTRY_NAME="reg$SUFFIX"
    
  2. 使用 az acr createCreate新的 Azure 容器注册表 实例。

    az acr create \
      --resource-group $RESOURCE_GROUP_NAME \
      --name $CONTAINER_REGISTRY_NAME \
      --sku "Standard" \
      --location $LOCATION \
      --admin-enabled false
    
  3. Create名为 Dockerfile的多阶段 Dockerfile。 在 文件中,执行这些步骤。

    • 使用 mcr.microsoft.com/dotnet/sdk 容器映像作为生成阶段的基础

    • 安装 DAB CLI

    • 使用 DATABASE_CONNECTION_STRING 环境变量作为连接字符串,) mssql (SQL 数据库连接Create配置文件。

    • Create映射到表的名为 ProductSalesLT.Product实体。

    • 将配置文件复制到最终 mcr.microsoft.com/azure-databases/data-api-builder 容器映像。

    FROM mcr.microsoft.com/dotnet/sdk:6.0-cbl-mariner2.0 AS build
    
    WORKDIR /config
    
    RUN dotnet new tool-manifest
    
    RUN dotnet tool install Microsoft.DataApiBuilder
    
    RUN dotnet tool run dab -- init --database-type "mssql" --connection-string "@env('DATABASE_CONNECTION_STRING')"
    
    RUN dotnet tool run dab -- add Product --source "SalesLT.Product" --permissions "anonymous:read"
    
    FROM mcr.microsoft.com/azure-databases/data-api-builder
    
    COPY --from=build /config /App
    
  4. 使用 az acr build生成 Dockerfile 作为Azure 容器注册表任务。

    az acr build \
      --registry $CONTAINER_REGISTRY_NAME \
      --image adventureworkslt-dab:latest \
      --image adventureworkslt-dab:{{.Run.ID}} \
      --file Dockerfile \
      .
    
  5. 使用 az acr show 获取容器注册表的终结点,并将其存储在名为 的 CONTAINER_REGISTRY_LOGIN_SERVER变量中。

    CONTAINER_REGISTRY_LOGIN_SERVER=$( \
      az acr show \
        --resource-group $RESOURCE_GROUP_NAME \
        --name $CONTAINER_REGISTRY_NAME \
        --query "loginServer" \
        --output "tsv" \
    )
    

    提示

    始终可以检查此命令的输出。

    echo $CONTAINER_REGISTRY_LOGIN_SERVER
    

部署容器映像

最后,使用新的自定义容器映像和凭据更新 Azure 容器应用。 测试正在运行的应用程序以验证其与数据库的连接。

  1. 使用 将容器应用配置为使用 az containerapp registry set容器注册表。

    az containerapp registry set \
      --resource-group $RESOURCE_GROUP_NAME \
      --name $API_CONTAINER_NAME \
      --server $CONTAINER_REGISTRY_LOGIN_SERVER \
      --identity "system"
    
  2. 使用 az containerapp secret set 创建具有 Azure SQL 连接字符串的名为 conn-string 的机密。

    az containerapp secret set \
      --resource-group $RESOURCE_GROUP_NAME \
      --name $API_CONTAINER_NAME \
      --secrets conn-string="$SQL_CONNECTION_STRING"
    

    重要

    此连接字符串不包含任何用户名或密码。 连接字符串使用托管标识访问Azure SQL数据库。 这样可以安全地将连接字符串用作主机中的机密。

  3. 使用 az containerapp update使用 使用新的自定义容器映像更新容器应用。 将 DATABASE_CONNECTION_STRING 环境变量设置为从以前创建的机密中 conn-string 读取。

    az containerapp update \
      --resource-group $RESOURCE_GROUP_NAME \
      --name $API_CONTAINER_NAME \
      --image "$CONTAINER_REGISTRY_LOGIN_SERVER/adventureworkslt-dab:latest" \
      --set-env-vars DATABASE_CONNECTION_STRING=secretref:conn-string
    
  4. 使用 az containerapp show在正在运行的容器应用中检索最新修订的完全限定域名。 将该值存储在名为 的 APPLICATION_URL变量中。

    APPLICATION_URL=$( \
      az containerapp show \
        --resource-group $RESOURCE_GROUP_NAME \
        --name $API_CONTAINER_NAME \
        --query "properties.latestRevisionFqdn" \
        --output "tsv" \
    )
    

    提示

    始终可以检查此命令的输出。

    echo $APPLICATION_URL
    
  5. 导航到 URL 并测试 Product REST API。

    echo "https://$APPLICATION_URL/api/Product"
    

    警告

    部署可能需要长达一分钟的时间。 如果未看到成功的响应,请等待并刷新浏览器。

清理资源

不再需要示例应用程序或资源时,请删除相应的部署和所有资源。

az group delete \
  --name $RESOURCE_GROUP_NAME

后续步骤