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

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

在本教程中,你将:

  • 使用托管身份,并配置基于角色的访问控制权限
  • 使用示例 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 Shellhttps://portal.azure.com

创建容器应用

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

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

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

    LOCATION="<azure-region>"
    

    注释

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

    LOCATION="westus"
    

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

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

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

  3. 创建具有资源组名称的 RESOURCE_GROUP_NAME 变量。 对于本教程,我们建议msdocs-dab-*。 本教程中多次使用此值。

    RESOURCE_GROUP_NAME="msdocs-dab$SUFFIX"    
    
  4. 使用 az group create. 创建一个新的资源组。

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

    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. 使用 mcr.microsoft.com/azure-databases/data-api-builder DAB 容器映像和 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. 创建一 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. 使用 角色再次分配给托管标识。 此分配允许托管标识从 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. 为 Azure SQL Server 实例创建具有唯一生成名称的变量 SQL_SERVER_NAME 。 你将在本部分后面使用此变量。

    SQL_SERVER_NAME="srvr$SUFFIX"
    
  2. 使用 创建新的 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在名为的 Azure SQL Server 中创建adventureworks。 将数据库配置为使用 AdventureWorksLT 示例数据。

    az sql db create \
      --resource-group $RESOURCE_GROUP_NAME \
      --server $SQL_SERVER_NAME \
      --name "adventureworks" \
      --sample-name "AdventureWorksLT"
    
  5. 为 Azure SQL Server 实例中的 SQL_CONNECTION_STRING 数据库创建一个包含连接字符串的名为 adventureworks 的变量。 使用 来构造服务器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. 为 Azure 容器注册表实例创建具有唯一生成名称的变量 CONTAINER_REGISTRY_NAME 。 你将在本部分后面使用此变量。

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

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

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

    • 安装 DAB CLI

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

    • 创建一个映射到 Product 表的名为 SalesLT.Product 的实体。

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

    FROM mcr.microsoft.com/dotnet/sdk:8.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 创建一个名为 conn-string 的机密,其中包含 Azure SQL 连接字符串。

    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

后续步骤