在 Azure Stack Hub 上安装 Azure CLI

可以使用 Windows 或 Linux 计算机安装 Azure CLI 以管理 Azure Stack Hub。 本文将指导你完成安装和设置 Azure CLI 的步骤。

安装 Azure CLI

  1. 登录到开发工作站并安装 CLI。 Azure Stack Hub 需要 Azure CLI 2.0 版或更高版本。

    重要

    由于 CVE 会影响 Azure CLI 2.40.0 之前的版本,因此不再建议在 Azure Stack Hub 中对 AD FS 使用 Azure CLI 2.29.2。 可以更新到 Azure CLI 2.40.0 或更高版本。 但是,AD FS 客户在使用与 Microsoft Graph 终结点交互的 Azure CLI 命令时可能会遇到问题。 这是因为 AD FS 不支持 Microsoft Graph。 有关 Microsoft Graph 问题的解决方法,请参阅一般已知问题部分。

  2. 可以使用安装 Azure CLI 一文中所述的步骤安装 CLI。

  3. 若要验证安装是否成功,请打开终端或命令提示符窗口,并运行以下命令:

    az --version
    

    应会看到 Azure CLI 的版本,以及计算机上安装的其他依赖库。

    Azure CLI on Azure Stack Hub Python location

  4. 记下 CLI 的 Python 位置。

添加证书

为断开连接的集成系统和 ASDK 导出然后导入 Azure Stack Hub 证书。 对于已连接的集成系统,证书是公开签名的,不需要执行此步骤。 有关说明,请参阅在 Azure Stack 开发工具包中为 Azure CLI 设置证书

使用 Azure CLI 进行连接

如果使用 Microsoft Entra ID 作为标识管理服务,并在 Windows 计算机上使用 CLI,可以参考本部分完成 CLI 设置过程。

连接到 Azure Stack Hub

  1. 如果使用的是 ASDK,请信任 Azure Stack Hub CA 根证书。 有关说明,请参阅信任证书

  2. 运行 az cloud register 命令注册 Azure Stack Hub 环境。

  3. 注册环境。 在运行 az cloud register 时使用以下参数:

    示例 说明
    环境名称 AzureStackUser 对于用户环境,请使用 AzureStackUser。 如果你是操作员,请指定 AzureStackAdmin
    资源管理器终结点 https://management.contoso.partner.onmschina.cn ASDK 中的 ResourceManagerUrl 为:https://management.local.azurestack.external/集成系统中的 ResourceManagerUrl 为:https://management.<region>.<fqdn>/ 如果对集成系统终结点有疑问,请与云操作员联系。
    存储终结点 local.contoso.partner.onmschina.cn local.azurestack.external 适用于 ASDK。 对于集成系统,请使用适用于系统的终结点。
    KeyVault 后缀 .vault.contoso.partner.onmschina.cn .vault.local.azurestack.external 适用于 ASDK。 对于集成系统,请使用适用于系统的终结点。
    终结点 active directory graph 资源 ID https://graph.chinacloudapi.cn/ Active Directory 资源 ID。
    az cloud register `
        -n <environmentname> `
        --endpoint-resource-manager "https://management.<region>.<fqdn>" `
        --suffix-storage-endpoint "<fqdn>" `
        --suffix-keyvault-dns ".vault.<fqdn>" 
    

    可以在 Azure CLI 参考文档中找到 register 命令的参考。

  4. 使用以下命令设置活动环境。

    az cloud set -n <environmentname>
    
  5. 将环境配置更新为使用 Azure Stack Hub 特定的 API 版本配置文件。 若要更新配置,请运行以下命令:

    az cloud update --profile 2020-09-01-hybrid
    
  6. 使用 az login 命令登录到 Azure Stack Hub 环境。

    可以使用用户凭据或云运营商提供的服务主体 (SPN) 登录到 Azure Stack Hub 环境。

    • 以用户身份登录:

      可以直接在 az login 命令中指定用户名和密码,或使用浏览器进行身份验证。 如果帐户已启用多重身份验证,则必须采用后者:

      az login -u "user@contoso.partner.onmschina.cn" -p 'Password123!' --tenant contoso.partner.onmschina.cn
      

      注意

      如果用户帐户已启用多重身份验证,请使用 az login 命令,但不提供 -u 参数。 运行此命令会提供一个 URL 以及身份验证时必须使用的代码。

    • 以服务主体身份登录:

      在登录之前,请通过 Azure 门户或 CLI 创建一个服务主体,并为其分配角色。 接下来,使用以下命令登录:

      az login `
        --tenant <Azure Active Directory Tenant name. `
                  For example: myazurestack.partner.onmschina.cn> `
      --service-principal `
        -u <Application Id of the Service Principal> `
        -p <Key generated for the Service Principal>
      
  7. 验证环境是否设置正确,以及环境是否为活动云。

        az cloud list --output table
    

应当看到环境被列出,并且“IsActive”为 true。 例如:

IsActive    Name               Profile
----------  -----------------  -----------------
False       AzureCloud         2020-09-01-hybrid
False       AzureChinaCloud    latest
False       AzureUSGovernment  latest
False       AzureGermanCloud   latest
True        AzureStackUser     2020-09-01-hybrid

测试连接

完成所有设置后,使用 CLI 在 Azure Stack Hub 中创建资源。 例如,可以创建应用的资源组并添加 VM。 使用以下命令创建名为“MyResourceGroup”的资源组:

az group create -n MyResourceGroup -l local

如果成功创建了资源组,则上述命令会输出新建资源的以下属性:

{
  "id": "/subscriptions/84edee99-XXXX-4f5c-b646-5cdab9759a03/resourceGroups/RGCL11",
  "location": "local",
  "name": "RGCLI1",
  " properties ": {
    "provisioningState": "Succeeded"
  },
  "tags ": null
}

一般已知问题

大多数问题的一般解决方法是使用 az rest 命令(该命令使用当前 Azure Stack 上下文),对出现问题的关联命令发出 REST API 调用。 以下问题列表中的解决方法通常可以针对其他 Azure CLI 问题进行调整,只要这些问题是由 Azure CLI 而不是 Azure Stack Hub 资源提供程序或其他 Azure Stack Hub 服务引起的。

Microsoft Graph 问题

这些是 Azure Stack Hub 的 Azure CLI 2.40.0 或更高版本的已知 Microsoft Graph 问题。 这主要影响 ADFS 环境,因为它不支持 Microsoft Graph。

  • az keyvault create 与 Microsoft Graph 交互。 下面是 ADFS 的示例解决方法。 该解决方法主要使用 Azure AD Graph(不是 Microsoft Graph)来检索用户信息,例如 objectId

    # First, sign into Azure CLI account you want to create the Key Vault from.
    # TODO: change the principal name to name of principal you want to create the key vault with.
    $principalNameLike = "CloudUser*"
    # TODO: change location to your preference.
    $location = "local"
    $aadGraph = az cloud show --query endpoints.activeDirectoryGraphResourceId --output tsv
    $tenantId = az account show --query tenantId --output tsv
    if ($aadGraph[-1] -ne '/')
    {
        $aadGraph += '/'
    }
    $userObject = az rest --method get --url "${aadGraph}${tenantId}/users?api-version=1.6" `
        | ConvertFrom-Json `
        | Select-Object -ExpandProperty value `
        | Where-Object {$_.userPrincipalName -like $principalNameLike}
    $body = '{
      "location": "' + $location + '",
      "properties": {
        "tenantId": "' + $tenantId + '",
        "sku": {
          "family": "A",
          "name": "standard"
        },
        "accessPolicies": [
          {
            "tenantId": "' + $tenantId + '",
            "objectId": "' + $userObject.objectId + '",
            "permissions": {
              "keys": [
                "get",
                "create",
                "delete",
                "list",
                "update",
                "import",
                "backup",
                "restore",
                "recover"
              ],
              "secrets": [
                "get",
                "list",
                "set",
                "delete",
                "backup",
                "restore",
                "recover"
              ],
              "certificates": [
                "get",
                "list",
                "delete",
                "create",
                "import",
                "update",
                "managecontacts",
                "getissuers",
                "listissuers",
                "setissuers",
                "deleteissuers",
                "manageissuers",
                "recover"
              ],
              "storage": [
                "get",
                "list",
                "delete",
                "set",
                "update",
                "regeneratekey",
                "setsas",
                "listsas",
                "getsas",
                "deletesas"
              ]
            }
          }
        ],
        "enabledForDeployment": true,
        "enabledForTemplateDeployment": true
      }
    }'
    $body | Out-File -FilePath (Join-Path -Path "." -ChildPath "body.json")
    $resourceGroupName = "testrg123"
    az group create -n $resourceGroupName -l $location
    $armEndpoint = az cloud show --query endpoints.resourceManager --output tsv
    if ($armEndpoint[-1] -ne '/')
    {
        $armEndpoint += '/'
    }
    $subscriptionId = az account show --query id --output tsv
    $keyVaultName = "testkv123"
    az rest --method put --url "${armEndpoint}subscriptions/${subscriptionId}/resourceGroups/${resourceGroupName}/providers/Microsoft.KeyVault/vaults/${keyVaultName}?api-version=2016-10-01" --body `@body.json
    # OPTIONAL: test access to the Key Vault.
    # az keyvault secret set --name MySecretName --vault-name $keyVaultName --value MySecret
    

    有关密钥保管库 REST API 的详细信息,请参阅密钥保管库 REST API 参考

其他问题

以下问题不限于 Azure CLI 的特定版本或版本范围。

  • 由于旧的 API 问题,适用于 Azure Stack Hub 的 Azure CLI 目前不支持 az role assignment create。 Microsoft Entra ID 或 ADFS 都需要以下解决方法。
    # First, sign into account with access to the resource that is being given access or a role to another user.
    # TODO: change the principal name to name of principal you want to assign the role to.
    $principalNameLike = "CloudUser*"
    # TODO: change role name to your preference.
    $roleName = "Owner"
    # TODO: change location to your preference.
    $location = "local"
    $aadGraph = az cloud show --query endpoints.activeDirectoryGraphResourceId --output tsv
    $tenantId = az account show --query tenantId --output tsv
    if ($aadGraph[-1] -ne '/')
    {
        $aadGraph += '/'
    }
    $userObject = az rest --method get --url "${aadGraph}${tenantId}/users?api-version=1.6" `
        | ConvertFrom-Json `
        | Select-Object -ExpandProperty value `
        | Where-Object {$_.userPrincipalName -like $principalNameLike}
    $roleDefinitionId = az role definition list --query "[?roleName=='${roleName}'].id" --output tsv
    $body = @{
        properties = @{
            roleDefinitionId = $roleDefinitionId
            principalId = $userObject.objectId
        }
    }
    $body | ConvertTo-Json | Out-File -FilePath (Join-Path -Path "." -ChildPath "body.json")
    $resourceGroupName = "testrg123"
    az group create -n $resourceGroupName -l $location
    $armEndpoint = az cloud show --query endpoints.resourceManager --output tsv
    if ($armEndpoint[-1] -ne '/')
    {
        $armEndpoint += '/'
    }
    $scope =  az group show --name $resourceGroupName --query id --output tsv
    $guid = (New-Guid).ToString()
    az rest --method put --url "${armEndpoint}${scope}/providers/Microsoft.Authorization/roleAssignments/${guid}?api-version=2015-07-01" --body `@body.json
    # OPTIONAL: test access to the resource group, or use the portal.
    # az login -u <assigned user name> -p <assigned user password> --tenant $tenantId
    # Test a resource creation command in the resource group:
    # az network dns zone create -g $resourceGroupName -n "www.mysite.com"
    
    有关角色分配 REST API 的详细信息,请参阅角色分配一文

后续步骤