教程:使用 ARM 模板导入 SQL BACPAC 文件

了解如何使用 Azure SQL 数据库扩展,以通过 Azure 资源管理器模板(ARM 模板)导入 BACPAC 文件。 部署项目包括主模板文件以及完成部署所需的任何文件。 BACPAC 文件是一个项目。

在本教程中,你将创建一个模板来部署逻辑 SQL Server、单个数据库并导入 BACPAC 文件。 要了解如何使用 ARM 模板来部署 Azure 虚拟机扩展,请参阅教程:使用 ARM 模板部署虚拟机扩展

本教程涵盖以下任务:

  • 准备 BACPAC 文件。
  • 打开快速入门模板。
  • 编辑模板。
  • 部署模板。
  • 验证部署。

如果没有 Azure 订阅,请在开始前创建一个试用版订阅

先决条件

若要完成本文,需要做好以下准备:

  • 包含资源管理器工具扩展的 Visual Studio Code 。 请参阅快速入门:使用 Visual Studio Code 创建 ARM 模板

  • 若要增强安全性,请使用为服务器管理员帐户生成的密码。 可以在 PowerShell 或 CLI 中使用本地 Shell 运行以下命令:

    openssl rand -base64 32
    

    若要了解详细信息,请运行 man openssl rand 打开手册页。

    Azure Key Vault 旨在保护加密密钥和其他机密。 有关详细信息,请参阅教程:在 ARM 模板部署中集成 Azure Key Vault。 我们还建议你每三个月更新一次密码。

准备 BACPAC 文件

BACPAC 文件在 GitHub 中共享。 要创建自己的文件,请参阅将 Azure SQL 数据库中的数据库导出到 BACPAC 文件。 如果选择将文件发布到你自己的位置,则必须在教程的后面部分更新模板。

必须先将 BACPAC 文件存储在 Azure 存储帐户中,然后才能使用 ARM 模板导入该文件。 下面的 PowerShell 脚本通过以下步骤准备 BACPAC 文件:

  • 下载 BACPAC 文件。
  • 创建 Azure 存储帐户。
  • 创建存储帐户 Blob 容器。
  • 将 BACPAC 文件上传到该容器。
  • 显示存储帐户密钥、Blob URL、资源组名称和位置。
  1. 在本地计算机上,以管理员权限打开 PowerShell 控制台。 然后,将以下 PowerShell 脚本复制并粘贴到 PowerShell 控制台中。

    # Sign in the Azure China Cloud
    Connect-AzAccount -Environment AzureChinaCloud
    
    $projectName = Read-Host -Prompt "Enter a project name that is used to generate Azure resource names"
    $location = Read-Host -Prompt "Enter the location (i.e. chinaeast)"
    
    $resourceGroupName = "${projectName}rg"
    $storageAccountName = "${projectName}store"
    $containerName = "bacpacfiles"
    $bacpacFileName = "SQLDatabaseExtension.bacpac"
    $bacpacUrl = "https://github.com/Azure/azure-docs-json-samples/raw/master/tutorial-sql-extension/SQLDatabaseExtension.bacpac"
    
    # Download the bacpac file
    Invoke-WebRequest -Uri $bacpacUrl -OutFile "$HOME/$bacpacFileName"
    
    # Create a resource group
    New-AzResourceGroup -Name $resourceGroupName -Location $location
    
    # Create a storage account
    $storageAccount = New-AzStorageAccount -ResourceGroupName $resourceGroupName `
                                           -Name $storageAccountName `
                                           -SkuName Standard_LRS `
                                           -Location $location
    $storageAccountKey = (Get-AzStorageAccountKey -ResourceGroupName $resourceGroupName `
                                                  -Name $storageAccountName).Value[0]
    
    # Create a container
    New-AzStorageContainer -Name $containerName -Context $storageAccount.Context
    
    # Upload the BACPAC file to the container
    Set-AzStorageBlobContent -File $HOME/$bacpacFileName `
                             -Container $containerName `
                             -Blob $bacpacFileName `
                             -Context $storageAccount.Context
    
    Write-Host "The project name:        $projectName `
      The location:            $location `
      The storage account key: $storageAccountKey `
      The BACPAC file URL:     https://$storageAccountName.blob.core.chinacloudapi.cn/$containerName/$bacpacFileName `
      "
    
    Write-Host "Press [ENTER] to continue ..."
    
  2. 保存存储帐户密钥、BACPAC 文件 URL、项目名称和位置。 稍后在本教程中部署模板时,将要使用这些值。

打开快速入门模板

本教程中使用的模板存储在 GitHub 中。

  1. 在 Visual Studio Code 中,选择“文件”>“打开文件”。

  2. 在“文件名”中粘贴以下 URL:

    https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/tutorial-sql-extension/azuredeploy.json
    
  3. 选择“打开”以打开该文件。

    模板中定义了两个资源:

    • Microsoft.Sql/servers
    • Microsoft.SQL.servers/databases

    在自定义模板之前,不妨对其进行一些基本的了解。

  4. 选择“文件”>“另存为”,将该文件的副本保存到名为 azuredeploy.json 的本地计算机。

编辑模板

  1. parameters 部分的末尾添加两个参数,以设置存储帐户密钥和 BACPAC URL。

        "storageAccountKey": {
          "type":"string",
          "metadata":{
            "description": "Specifies the key of the storage account where the BACPAC file is stored."
          }
        },
        "bacpacUrl": {
          "type":"string",
          "metadata":{
            "description": "Specifies the URL of the BACPAC file."
          }
        }
    

    adminPassword 属性的右大括号 (}) 后面添加一个逗号。 要从 Visual Studio Code 设置 JSON 文件的格式,请选择 Shift+Alt+F。

  2. 将两个资源添加到模板中。

    • 若要允许 SQL 数据库扩展导入 BACPAC 文件,必须允许来自 Azure 服务的流量。 部署 SQL 服务器后,防火墙规则将启用“允许 Azure 服务和资源访问此服务器”的设置。

      在服务器定义下添加以下防火墙规则:

      "resources": [
        {
          "type": "firewallrules",
          "apiVersion": "2021-02-01-preview",
          "name": "AllowAllAzureIps",
          "location": "[parameters('location')]",
          "dependsOn": [
            "[parameters('databaseServerName')]"
          ],
          "properties": {
            "startIpAddress": "0.0.0.0",
            "endIpAddress": "0.0.0.0"
          }
        }
      ]
      

      以下示例显示更新的模板:

      包含防火墙定义的模板的屏幕截图。

    • 使用以下 JSON 将 SQL 数据库扩展资源添加到数据库定义:

      "resources": [
        {
          "type": "extensions",
          "apiVersion": "2014-04-01",
          "name": "Import",
          "dependsOn": [
            "[resourceId('Microsoft.Sql/servers/databases', parameters('databaseServerName'), parameters('databaseName'))]"
          ],
          "properties": {
            "storageKeyType": "StorageAccessKey",
            "storageKey": "[parameters('storageAccountKey')]",
            "storageUri": "[parameters('bacpacUrl')]",
            "administratorLogin": "[parameters('adminUser')]",
            "administratorLoginPassword": "[parameters('adminPassword')]",
            "operationMode": "Import"
          }
        }
      ]
      

      以下示例显示更新的模板:

      屏幕截图为具有 SQL 数据库扩展的模板。

      若要了解资源定义,请参阅 API 版本的 SQL 数据库扩展参考。 下面是一些重要元素:

      • dependsOn:必须在创建数据库以后才能创建扩展资源。
      • storageKeyType:指定要使用的存储密钥的类型。 值可以是 StorageAccessKeySharedAccessKey。 在本教程中使用 StorageAccessKey
      • storageKey:指定存储 BACPAC 文件的存储帐户的密钥。 如果存储密钥类型为 SharedAccessKey,则它前面必须是“?”。
      • storageUri:指定存储帐户中存储的 BACPAC 文件的 URL。
      • administratorLogin:SQL 管理员的帐户名称。
      • administratorLoginPassword:SQL 管理员的密码。 若要使用生成的密码,请参阅先决条件

以下示例显示已完成的模板:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "databaseServerName": {
      "type": "string",
      "defaultValue": "[concat('server-', uniqueString(resourceGroup().id, deployment().name))]",
      "metadata": {
        "description": "Specifies the name for the SQL server"
      }
    },
    "databaseName": {
      "type": "string",
      "defaultValue": "[concat('db-', uniqueString(resourceGroup().id, deployment().name), '-1')]",
      "metadata": {
        "description": "Specifies the name for the SQL database under the SQL server"
      }
    },
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]",
      "metadata": {
        "description": "Specifies the location for server and database"
      }
    },
    "adminUser": {
      "type": "string",
      "metadata": {
        "description": "Specifies the username for admin"
      }
    },
    "adminPassword": {
      "type": "securestring",
      "metadata": {
        "description": "Specifies the password for admin"
      }
    },
    "storageAccountKey": {
      "type": "string",
      "metadata": {
        "description": "Specifies the key of the storage account where the BACPAC file is stored."
      }
    },
    "bacpacUrl": {
      "type": "string",
      "metadata": {
        "description": "Specifies the URL of the BACPAC file."
      }
    }
  },
  "resources": [
    {
      "type": "Microsoft.Sql/servers",
      "apiVersion": "2021-02-01-preview",
      "name": "[parameters('databaseServerName')]",
      "location": "[parameters('location')]",
      "properties": {
        "administratorLogin": "[parameters('adminUser')]",
        "administratorLoginPassword": "[parameters('adminPassword')]",
        "version": "12.0"
      },
      "resources": [
        {
          "type": "firewallrules",
          "apiVersion": "2021-02-01-preview",
          "name": "AllowAllAzureIps",
          "location": "[parameters('location')]",
          "dependsOn": [
            "[parameters('databaseServerName')]"
          ],
          "properties": {
            "startIpAddress": "0.0.0.0",
            "endIpAddress": "0.0.0.0"
          }
        }
      ]
    },
    {
      "type": "Microsoft.Sql/servers/databases",
      "apiVersion": "2021-02-01-preview",
      "name": "[concat(string(parameters('databaseServerName')), '/', string(parameters('databaseName')))]",
      "location": "[parameters('location')]",
      "dependsOn": [
        "[concat('Microsoft.Sql/servers/', parameters('databaseServerName'))]"
      ],
      "resources": [
        {
          "type": "extensions",
          "apiVersion": "2014-04-01",
          "name": "Import",
          "dependsOn": [
            "[resourceId('Microsoft.Sql/servers/databases', parameters('databaseServerName'), parameters('databaseName'))]"
          ],
          "properties": {
            "storageKeyType": "StorageAccessKey",
            "storageKey": "[parameters('storageAccountKey')]",
            "storageUri": "[parameters('bacpacUrl')]",
            "administratorLogin": "[parameters('adminUser')]",
            "administratorLoginPassword": "[parameters('adminPassword')]",
            "operationMode": "Import"
          }
        }
      ]
    }
  ]
}

部署模板

使用准备 BACPAC 文件时所用的项目名称和位置。 所有资源将放到同一个资源组,这也便于你删除资源。

  1. 检查并验证我们在前面的步骤中保存到本地计算机的 azuredeploy.json 文件。

  2. 若要部署模板,请将以下脚本复制并粘贴到 Shell 窗口中。

    $projectName = Read-Host -Prompt "Enter the same project name that is used earlier"
    $location = Read-Host -Prompt "Enter the location (i.e. chinaeast)"
    $adminUsername = Read-Host -Prompt "Enter the SQL admin username"
    $adminPassword = Read-Host -Prompt "Enter the admin password" -AsSecureString
    $storageAccountKey = Read-Host -Prompt "Enter the storage account key"
    $bacpacUrl = Read-Host -Prompt "Enter the URL of the BACPAC file"
    $resourceGroupName = "${projectName}rg"
    
    New-AzResourceGroupDeployment `
        -ResourceGroupName $resourceGroupName `
        -adminUser $adminUsername `
        -adminPassword $adminPassword `
        -TemplateFile "$HOME/azuredeploy.json" `
        -storageAccountKey $storageAccountKey `
        -bacpacUrl $bacpacUrl
    
    Write-Host "Press [ENTER] to continue ..."
    

验证部署

若要从客户端计算机访问服务器,需要添加防火墙规则。 由于网络地址转换 (NAT) 的原因,客户端的 IP 地址以及用于连接到服务器的 IP 地址可能不同。 有关详细信息,请参阅创建和管理 IP 防火墙规则

例如,登录到查询编辑器时,会显示一条消息,指出不允许所用的 IP 地址。 由于执行了 NAT,该地址不同于客户端的 IP 地址。 请选择该消息中的链接,为 IP 地址添加防火墙规则。 完成后,可以从服务器的“防火墙和虚拟网络”设置中删除 IP 地址。

在 Azure 门户上的资源组中选择数据库。 选择“查询编辑器(预览版)”,然后输入管理员凭据。 此时你会看到两个表已导入到该数据库中。

屏幕截图为 Azure 门户中的 Query 编辑器(预览版)。

清理资源

不再需要部署的 Azure 资源时,请删除资源组。 将会删除该资源组、存储帐户、SQL 服务器和 SQL 数据库。

  1. 在 Azure 门户中的搜索框内输入“资源组”。
  2. 在“按名称筛选”字段中输入资源组名称。
  3. 选择资源组名称。
  4. 选择“删除资源组”。
  5. 若要确认删除,请输入资源组名称,然后选择“删除”。

后续步骤

在本教程中,你部署了服务器和数据库,并导入了 BACPAC 文件。 若要了解如何排查模板部署问题,请参阅: