使用 Azure PowerShell 管理资源

将资源部署到 Azure 时,可以灵活选择想要部署的资源类型、资源的位置以及对它们的设置方式。 但是,除了你想要在组织中允许的选项,这种灵活性可能还会开放更多其他选项。 在考虑将资源部署到 Azure 时,你可能想知道以下问题:

  • 如何满足特定国家/地区针对数据所有权制定的法规要求?
  • 如何控制成本?
  • 如何确保用户不会无意中更改关键系统?
  • 如何跟踪资源成本并准确地进行计费?

本文会为你解答这些问题。 具体而言,你需要:

  • 将用户分配到角色并分配角色对应的作用域,这样用户就能具备执行预期操作所需的权限,同时并不会涉及其他操作。
  • 应用策略来对订阅中的资源进行约定。
  • 锁定系统中的关键资源。
  • 标记资源,以便按它们对组织的价值进行跟踪。

本文重点介绍实现管理需要完成的任务。

如果选择在本地安装并使用 PowerShell,请参阅安装 Azure PowerShell 模块。 如果在本地运行 PowerShell,则还需运行 Connect-AzureRmAccount -Environment AzureChinaCloud 以创建与 Azure 的连接。

了解范围

在创建任何项之前,让我们复习一下作用域的概念。 Azure 提供四个级别的管理:管理组、订阅、资源组和资源。 下图显示了一个这些层的示例。

作用域

将在上述任何级别的作用域中应用管理设置。 所选的级别确定应用设置的广泛程度。 较低级别继承较高级别的设置。 将设置应用到订阅时,该设置将应用于订阅中的所有资源组和资源。 将设置应用到资源组时,该设置将应用到资源组及其所有资源。 但是,其他资源组不具有该设置。

通常情况下,最好在较高级别应用关键设置,在较低级别应用特定于项目的要求。 例如,可能想要确保组织的所有资源均已部署到特定区域。 若要完成此要求,请将策略应用到指定允许位置的订阅。 当组织中的其他用户添加新资源组和资源时,会自动强制实施允许的位置。

在本文中,请将所有管理设置应用到资源组,以便在完成后可以轻松地删除这些设置。

让我们创建该资源组。

Set-AzureRmContext -Subscription <subscription-name>
New-AzureRmResourceGroup -Name myResourceGroup -Location ChinaEast

目前,资源组为空。

基于角色的访问控制

你希望确保你的组织中的用户对这些资源具有合适级别的访问权限。 你不希望向用户授予不受限的访问权限,但还需要确保他们可以执行其工作。 使用基于角色的访问控制 (RBAC),你可以管理哪些用户有权在某个范围内完成特定操作。 一个角色定义一组允许的操作。 将角色分配至某一范围,并指定哪些用户在此范围内属于该角色。

规划访问控制策略时,请授予用户完成工作所需的最低权限。 下图显示了分配 RBAC 的建议模式。

作用域

有三个适用于所有资源的角色 - “所有者”、“参与者”和“读取者”。 分配到“所有者”角色的所有帐户都应是严格控制且很少使用的。 只需查看解决方案状态的用户应被授予“读取者”角色。

在订阅级别或资源组级别,大多数用户都被授予特定于资源的角色自定义角色。 这些角色严格定义了允许的操作。 通过将用户分配到这些角色,可以为用户提供必要的访问权限,同时不会让他们得到过多的控制权限。 可以向一个帐户分配多个角色,此用户就能获取各个角色综合的权限。 在资源级别授予访问权限对用户而言通常过于受限,但可能适用于为特定任务设计的自动化流程。

谁能分配角色

若要创建和删除角色分配,用户必须具有 Microsoft.Authorization/roleAssignments/* 访问权限。 此访问权限是通过“所有者”或“用户访问”管理员角色授权的。

分配角色

在本文中,请部署一个虚拟机及其相关的虚拟网络。 若要管理虚拟机解决方案,可以使用三种特定于资源的角色来进行通常所需的访问:

通常情况下,与其向单个用户分配角色,不如为需要进行相似操作的用户创建一个 Azure Active Directory 组, 然后向该组分配相应的角色。 为了简单起见,本文创建一个没有成员的 Azure Active Directory 组。 仍然可以为该组分配一个负责某个范围的角色。

以下示例创建一个组,然后为其分配了资源组的“虚拟机参与者”角色。 若要运行 New-AzureAdGroup 命令,必须下载 Azure AD PowerShell 模块

$adgroup = New-AzureADGroup -DisplayName VMDemoContributors `
  -MailNickName vmDemoGroup `
  -MailEnabled $false `
  -SecurityEnabled $true
New-AzureRmRoleAssignment -ObjectId $adgroup.ObjectId `
  -ResourceGroupName myResourceGroup `
  -RoleDefinitionName "Virtual Machine Contributor"

通常情况下,请对网络参与者存储帐户参与者重复执行此过程,确保分配用户来管理已部署的资源。 在本文中,可以跳过这些步骤。

Azure Policy

Azure Policy 可帮助确保订阅中的所有资源符合企业标准。 订阅已经有多个策略定义。 若要查看可用的策略定义,请使用:

(Get-AzureRmPolicyDefinition).Properties | Format-Table displayName, policyType

可以看到现有的策略定义。 策略类型为“内置”或“自定义”。 在这些定义中查找所述条件正是你要分配的条件的定义。 在本文中,分配的策略要符合以下条件:

  • 限制所有资源的位置
  • 限制虚拟机的 SKU
  • 审核不使用托管磁盘的虚拟机
$locations ="chinaeast", "chinaeast2"
$skus = "Standard_DS1_v2", "Standard_E2s_v2"

$rg = Get-AzureRmResourceGroup -Name myResourceGroup

$locationDefinition = Get-AzureRmPolicyDefinition | where-object {$_.properties.displayname -eq "Allowed locations"}
$skuDefinition = Get-AzureRmPolicyDefinition | where-object {$_.properties.displayname -eq "Allowed virtual machine SKUs"}
$auditDefinition = Get-AzureRmPolicyDefinition | where-object {$_.properties.displayname -eq "Audit VMs that do not use managed disks"}

New-AzureRMPolicyAssignment -Name "Set permitted locations" `
  -Scope $rg.ResourceId `
  -PolicyDefinition $locationDefinition `
  -listOfAllowedLocations $locations
New-AzureRMPolicyAssignment -Name "Set permitted VM SKUs" `
  -Scope $rg.ResourceId `
  -PolicyDefinition $skuDefinition `
  -listOfAllowedSKUs $skus
New-AzureRMPolicyAssignment -Name "Audit unmanaged disks" `
  -Scope $rg.ResourceId `
  -PolicyDefinition $auditDefinition

部署虚拟机

分配角色和策略以后,即可部署解决方案。 默认大小为 Standard_DS1_v2,这是允许的 SKU 之一。 运行此步骤时,会提示输入凭据。 输入的值将配置为用于虚拟机的用户名和密码。

New-AzureRmVm -ResourceGroupName "myResourceGroup" `
     -Name "myVM" `
     -Location "China East" `
     -VirtualNetworkName "myVnet" `
     -SubnetName "mySubnet" `
     -SecurityGroupName "myNetworkSecurityGroup" `
     -PublicIpAddressName "myPublicIpAddress" `
     -OpenPorts 80,3389

部署完成后,可以对解决方案应用更多的管理设置。

锁定资源

资源锁可以防止组织中的用户意外删除或修改重要资源。 与基于角色的访问控制不同,资源锁对所有用户和角色应用限制。

可以将锁定级别设置为 CanNotDeleteReadOnly。 在门户中,锁定级别分别显示为“删除”和“只读”。

  • CanNotDelete 味着经授权的用户仍可读取和修改资源,但不能删除资源。
  • ReadOnly 意味着经授权的用户可以读取资源,但不能删除或更新资源。 应用此锁类似于将所有经授权的用户限制于“读者”角色授予的权限。

Tip

应用 ReadOnly 锁时请小心。 某些看起来像读取操作的操作实际需要其他操作。 例如,存储帐户上的 ReadOnly 锁将阻止所有用户列出密钥。 列出密钥操作通过 POST 请求进行处理,因为返回的密钥可用于写入操作。 应用服务资源上的 ReadOnly 锁将阻止 Visual Studio 服务器资源管理器显示资源文件,因为该交互需要写访问权限。

在父范围应用锁时,该范围内所有资源都会继承相同的锁。 即使是之后添加的资源也会从父作用域继承该锁。 继承中限制性最强的锁优先执行。

Resource Manager 锁仅适用于管理平面内发生的操作,包括发送到 https://management.chinacloudapi.cn的操作。 锁不会限制资源处理其自己的功能的方式。 资源更改将受到限制,但资源操作不受限制。 例如,SQL 数据库上的 ReadOnly 锁会阻止你删除或修改数据库。 它不会阻止你在数据库中创建、更新或删除数据。 允许数据事务,因为这些操作不会发送到 https://management.chinacloudapi.cn

谁可以在组织中创建或删除锁

若要创建或删除管理锁,必须有权执行 Microsoft.Authorization/locks/* 操作。 在内置角色中,只有“所有者”和“用户访问管理员”有权执行这些操作。

锁定资源

若要锁定虚拟机和网络安全组,请使用:

New-AzureRmResourceLock -LockLevel CanNotDelete `
  -LockName LockVM `
  -ResourceName myVM `
  -ResourceType Microsoft.Compute/virtualMachines `
  -ResourceGroupName myResourceGroup
New-AzureRmResourceLock -LockLevel CanNotDelete `
  -LockName LockNSG `
  -ResourceName myNetworkSecurityGroup `
  -ResourceType Microsoft.Network/networkSecurityGroups `
  -ResourceGroupName myResourceGroup

只有在明确解除锁定以后,才能删除虚拟机。 该步骤显示在清理资源中。

标记资源

可将标记应用于 Azure 资源,以便按类别在逻辑上对它们进行组织。 每个标记包含一个名称和一个值。 例如,可以对生产中的所有资源应用名称“Environment”和值“Production”。

应用标记以后,即可使用该标记名称和值检索订阅中的所有资源。 使用标记可以从不同资源组中检索相关资源。 需要为计费或管理目的组织资源时,此方法可能很有用。

以下限制适用于标记:

  • 每个资源或资源组最多可以有 15 个标记名称值对。 此限制仅适用于直接应用到资源组或资源的标记。 资源组可以包含多个资源,这些资源每个都有 15 个标记名称值对。 如果有超过 15 个需要与资源关联的值,请将 JSON 字符串用于标记值。 JSON 字符串可以包含多个应用于单个标记名称的值。 本文介绍了一个将 JSON 字符串分配给标记的示例。
  • 标记名称不能超过 512 个字符,标记值不能超过 256 个字符。 对于存储帐户,标记名称不能超过 128 个字符,标记值不能超过 256 个字符。
  • 应用于资源组的标记不会被该资源组中的资源继承。
  • 不能将标记应用到云服务等经典资源。
  • 标记名称不能包含以下字符:<>%&\?/

标记资源

若要为资源组添加两个标记,请使用 Set-AzureRmResourceGroup 命令:

Set-AzureRmResourceGroup -Name myResourceGroup -Tag @{ Dept="IT"; Environment="Test" }

让我们假设要添加第三个标记。 每次将标记应用到某个资源或资源组时,都会覆盖该资源或资源组中的现有标记。 若要添加新标记而不会丢失现有标记,必须检索现有标记、添加新标记,并重新应用标记集合:

# Get existing tags and add a new tag
$tags = (Get-AzureRmResourceGroup -Name myResourceGroup).Tags
$tags.Add("Project", "Documentation")

# Reapply the updated set of tags 
Set-AzureRmResourceGroup -Tag $tags -Name myResourceGroup

资源不从资源组继承标记。 目前,资源组有三个标记,但资源没有任何标记。 要将资源组中的所有标记应用于其资源,并且保留资源上不重复的现有标记,请使用以下脚本:

# Get the resource group
$group = Get-AzureRmResourceGroup myResourceGroup

if ($group.Tags -ne $null) {
    # Get the resources in the resource group
    $resources = Get-AzureRmResource -ResourceGroupName $group.ResourceGroupName

    # Loop through each resource
    foreach ($r in $resources)
    {
        # Get the tags for this resource
        $resourcetags = (Get-AzureRmResource -ResourceId $r.ResourceId).Tags

        # If the resource has existing tags, add new ones
        if ($resourcetags)
        {
            foreach ($key in $group.Tags.Keys)
            {
                if (-not($resourcetags.ContainsKey($key)))
                {
                    $resourcetags.Add($key, $group.Tags[$key])
                }
            }

            # Reapply the updated tags to the resource 
            Set-AzureRmResource -Tag $resourcetags -ResourceId $r.ResourceId -Force
        }
        else
        {
            Set-AzureRmResource -Tag $group.Tags -ResourceId $r.ResourceId -Force
        }
    }
}

或者,可以将资源组中的标记应用于资源而不保留现有标记:

# Get the resource group
$g = Get-AzureRmResourceGroup -Name myResourceGroup

# Find all the resources in the resource group, and for each resource apply the tags from the resource group
Get-AzureRmResource -ResourceGroupName $g.ResourceGroupName | ForEach-Object {Set-AzureRmResource -ResourceId $_.ResourceId -Tag $g.Tags -Force }

若要将几个值组合到单个标记中,请使用 JSON 字符串。

Set-AzureRmResourceGroup -Name myResourceGroup -Tag @{ CostCenter="{`"Dept`":`"IT`",`"Environment`":`"Test`"}" }

若要删除所有标记,请传递一个空哈希表。

Set-AzureRmResourceGroup -Name myResourceGroup -Tag @{ }

若要将标记应用到虚拟机,请使用:

$r = Get-AzureRmResource -ResourceName myVM `
  -ResourceGroupName myResourceGroup `
  -ResourceType Microsoft.Compute/virtualMachines
Set-AzureRmResource -Tag @{ Dept="IT"; Environment="Test"; Project="Documentation" } -ResourceId $r.ResourceId -Force

按标记查找资源

若要使用标记名称和值来查找资源,请使用:

(Find-AzureRmResource -TagName Environment -TagValue Test).Name

可以将返回的值用于管理任务,例如停止带有某个标记值的所有虚拟机。

Find-AzureRmResource -TagName Environment -TagValue Test | Where-Object {$_.ResourceType -eq "Microsoft.Compute/virtualMachines"} | Stop-AzureRmVM

清理资源

在解除锁定之前,不能删除锁定的网络安全组。 若要解除锁定,请使用:

Remove-AzureRmResourceLock -LockName LockVM `
  -ResourceName myVM `
  -ResourceType Microsoft.Compute/virtualMachines `
  -ResourceGroupName myResourceGroup
Remove-AzureRmResourceLock -LockName LockNSG `
  -ResourceName myNetworkSecurityGroup `
  -ResourceType Microsoft.Network/networkSecurityGroups `
  -ResourceGroupName myResourceGroup

如果不再需要资源组、VM 和所有相关的资源,可以使用 Remove-AzureRmResourceGroup 命令将其删除。

Remove-AzureRmResourceGroup -Name myResourceGroup

后续步骤