作为管理员,您可以锁定 Azure 订阅、资源组或资源,以保护它们免受用户的意外删除和修改。 锁会替代任何用户权限。
可以设置锁来防止删除或修改。 在该门户中,这些锁被称为「删除」和「只读」。 在命令行中,这些锁称为 CanNotDelete 和 ReadOnly。
- CanNotDelete 表示已获授权的用户可以读取和修改某个资源,但不能删除该资源。
- ReadOnly 表示已获授权的用户可以读取某个资源,但不能删除或更新该资源。 应用此锁类似于将所有已获授权的用户限制于使用“读取者”角色提供的权限。
与基于角色的访问控制 (RBAC) 不同,你可以使用管理锁对所有用户和角色应用限制。 若要了解如何设置用户和角色的权限,请参阅 Azure RBAC。
锁继承
在父范围应用锁时,该范围内所有资源都会继承相同的锁。 即使是以后添加的资源也会继承同一父锁。 继承链中限制性最大的锁优先。
扩展资源 会继承它们所应用的目标资源的锁定。 例如,Microsoft.Insights/diagnosticSettings 是扩展资源类型。 如果将诊断设置应用于存储 Blob 并锁定存储帐户,则无法删除诊断设置。 此继承是合理的,因为诊断设置的完整资源 ID 为:
/subscriptions/{sub-id}/resourceGroups/{rg-name}/providers/Microsoft.Storage/storageAccounts/{storage-name}/blobServices/default/providers/microsoft.insights/diagnosticSettings/{setting-name}"
锁定资源的资源 ID 必须与以下格式匹配:
/subscriptions/{sub-id}/resourceGroups/{rg-name}/providers/Microsoft.Storage/storageAccounts/{storage-name}
如果你对某个资源拥有“删除”锁并尝试删除其资源组,该功能会阻止整个删除操作。 即使资源组或资源组中的其他资源已解锁,也不会发生删除操作。 无法进行部分删除。
当您取消Azure订阅时:
- 资源锁不会阻止取消该订阅。
- Azure通过停用而不是立即删除的方式来保留资源。
- Azure仅在等待期过后永久删除资源。
了解锁的作用域
注意事项
锁仅适用于 Azure 控制平面的操作,而不适用于数据平面的操作。
Azure 控制平面的操作请求将被转到 https://management.chinacloudapi.cn。 Azure数据平面的操作转向您的服务实例,例如 https://myaccount.blob.core.chinacloudapi.cn/。 有关详细信息,请参阅 Azure 控制平面和数据平面。 若要发现哪些操作使用控制平面 URL,请参阅 Azure REST API。
这种差别意味着,锁可以防止资源遭到更改,但不限制资源执行其功能的方式。 例如,SQL 数据库逻辑服务器上的 ReadOnly 锁可防止删除或修改。 它允许在服务器数据库中创建、更新或删除数据。 数据平面操作支持数据事务。 这些请求不会转到 https://management.chinacloudapi.cn。
应用锁之前的注意事项
应用锁可能会导致意外结果。 某些看似没有修改资源的操作需要被阻止的操作。 锁定可防止 POST 方法将数据发送到 Azure Resource Manager API。 阻止的操作的一些常见示例包括:
storage 帐户的只读锁阻止用户列出帐户密钥。 POST 请求处理 Azure Storage List Keys 操作,以保护对帐户密钥的访问。 帐户密钥提供对存储帐户中数据的完整访问权限。 为存储帐户配置只读锁定时,没有帐户密钥的用户需要使用 Microsoft Entra 凭据来访问 blob 或队列数据。 只读锁还阻止分配被指定为存储帐户或数据容器(Blob 容器或队列)的 Azure RBAC 角色。
在存储账户上的只读锁定,可以保护针对存储账户或数据容器(Blob 容器或队列)的 RBAC 分配的作用域。
storage 帐户上的只读锁阻止创建 blob 容器。
storage 帐户上的只读锁阻止创建blob容器。 但是,可以通过控制平面和数据平面在存储帐户上创建操作。 只读锁仅阻止控制平面创建请求,但用户仍可以通过数据平面对资源执行有效的创建操作。
存储帐户上的只读锁或防删除锁无法保护其数据不被删除或修改。 它也不能保护 Blob、队列、表或文件中的数据。
存储帐户 API 公开 数据平面 和 控制平面 操作。 如果请求使用 数据平面操作,存储帐户上的锁不会保护该存储帐户中的 blob、队列、表或文件数据。 但是,如果请求使用 控制平面 操作,锁将保护这些资源。
例如,如果请求使用 文件共享 - 删除,一种控制平面操作,则删除将失败。 如果请求使用Delete Share,作为数据平面操作,删除操作将成功完成。 我们建议使用控制平面操作。
在网络安全组(NSG)上的只读锁可防止创建相应的 NSG 流日志。 NSG 上的无法删除锁不会阻止创建或修改相应的 NSG 流日志。
App Service 资源的只读锁可防止 Visual Studio 服务器资源管理器显示资源的文件,因为进行该交互需要写入访问。
包含
App Service 计划 的资源组 的只读锁可防止您< c2>向上或向外扩展该计划。包含虚拟机的资源组上的 read-only 锁将阻止所有用户启动或重启该虚拟机。 这些操作需要 POST 方法请求。
资源组上的只读锁可防止将现有资源移入或移出资源组。 但是,可以将具有只读锁 的资源 移到另一个资源组。
包含自动化帐户的资源组上的只读锁会阻止所有运行手册的启动。 这些操作需要 POST 方法请求。
对 资源 或 资源组 的不可删除锁会阻止删除 Azure RBAC 分配。
在资源组上设置一个无法删除锁可以防止 Resource Manager 在历史记录中自动删除部署。 如果部署历史达到 800 次,则后续的部署将失败。
当由 Azure 备份服务 创建的 资源组 上存在 不可删除 锁时,备份将失败。 该服务最多支持 18 个还原点。 锁定后,备份服务无法清理还原点。 有关详细信息,请参阅 常见问题解答-备份 Azure 虚拟机。
在包含 Azure Machine Learning 工作区的 资源组 上设置的 cannot-delete 锁定会阻止 Azure Machine Learning 计算群集的自动缩放功能正常运作。 使用该锁,自动缩放功能将无法删除未使用的节点。 解决方案使用的资源多于工作负载所需的资源。
Log Analytics 工作区上的只读锁会阻止启用“用户和实体行为分析(UEBA)”。
Log Analytics 工作区上的不可删除的锁定不会阻止 数据清除操作。 而是从用户中删除 Data Purger 角色。
订阅的只读锁会阻止Azure Advisor正常工作。 顾问无法存储其查询的结果。
应用程序网关上的只读锁会阻止您获取其后端运行状况。 该操作使用 POST 方法,但被一个只读锁定阻止。
Azure Kubernetes Service(AKS)群集上的只读锁限制通过门户访问群集资源的方式。 只读锁可防止在Azure portal中使用 AKS 群集的 Kubernetes 资源部分来选择群集资源。 这些操作需要通过 POST 方法请求进行身份验证。
在受 Site Recovery 保护的 Virtual Machine 上,无法删除锁定会在您移除保护或禁用复制时阻止删除与 Site Recovery 相关的某些资源链接。 如果以后计划再次保护虚拟机,请先删除锁定,然后再禁用保护。 如果不删除锁,则需要执行某些步骤来清理过时的链接,然后才能保护虚拟机。 有关详细信息,请参阅 排查 Azure 到 Azure 虚拟机复制错误。
对于 PostgreSQL,虚拟网络不应在虚拟网络或子网级别设置任何资源锁,因为锁可能会干扰网络和域名系统的操作。 在virtual network中创建服务器之前,请确保从virtual network和所有子网中删除任何删除或只读锁。 创建服务器后,可以重新应用锁。
谁可以创建或删除锁
若要创建或删除管理锁,需要具有Microsoft.Authorization/*或Microsoft.Authorization/locks/*权限。 被分配到 Owner 和 用户访问管理员 角色的用户具有所需的访问权限。 某些特定的内置角色也授予此访问权限。 可以创建拥有所需权限的自定义角色。
托管应用程序和锁
某些 Azure 服务使用 托管应用程序实现这些服务,Azure Databricks 是一个例子。 在这种情况下,该服务将创建两个资源组。 其中一个资源组是包含服务概述的已解锁资源组。 另一个是包含服务基础结构的已锁定资源组。
如果尝试删除基础结构资源组,将会收到一条错误消息,指出资源组已锁定。 如果你尝试删除基础结构资源组的锁,将会收到一条错误消息,指出无法删除该锁,因为它由系统应用程序拥有。
应该删除服务,这样也会删除基础结构资源组。
对于托管应用程序,请选择你部署的服务。
请注意,该服务包含一个托管资源组的链接。 该资源组包含基础结构且已锁定。 只能间接删除它。
若要删除服务的所有内容(包括锁定的基础结构资源组),请选择该服务对应的“删除”。
配置锁具
Azure portal
在左侧导航面板中,订阅锁定功能的名称为“资源锁”,而资源组锁定功能的名称为“锁”。
在要锁定的资源、资源组或订阅的“设置”边栏选项卡中,选择“锁定”。
要添加锁,请选择“添加”。 如果您想在父级创建锁,请选择父级。 当前选定的资源将从父级继承锁。 例如,可以锁定资源组,以便向其所有资源应用锁。
为该锁提供名称和锁级别。 (可选)可以添加注释来描述该锁。
要删除锁,请选择“删除”按钮。
模板
使用 Resource Manager 模板(ARM 模板)或 Bicep 文件部署锁时,您需要了解部署范围与锁定范围是如何协同工作的。 若要在部署范围内应用锁定,例如锁定资源组或订阅时,请不要设置 scope 属性。 锁定部署范围内的资源时,请在锁定对象上设置 scope 属性。
以下模板会将锁应用于资源组。 请注意,锁资源没有 scope 属性,因为锁范围与部署范围匹配。 在资源组级别部署此模板。
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
},
"resources": [
{
"type": "Microsoft.Authorization/locks",
"apiVersion": "2016-09-01",
"name": "rgLock",
"properties": {
"level": "CanNotDelete",
"notes": "Resource group should not be deleted."
}
}
]
}
若要创建资源组并将其锁定,请在订阅级别部署上述模板。
{
"$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"rgName": {
"type": "string"
},
"rgLocation": {
"type": "string"
}
},
"variables": {},
"resources": [
{
"type": "Microsoft.Resources/resourceGroups",
"apiVersion": "2021-04-01",
"name": "[parameters('rgName')]",
"location": "[parameters('rgLocation')]",
"properties": {}
},
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2021-04-01",
"name": "lockDeployment",
"resourceGroup": "[parameters('rgName')]",
"dependsOn": [
"[resourceId('Microsoft.Resources/resourceGroups/', parameters('rgName'))]"
],
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {},
"variables": {},
"resources": [
{
"type": "Microsoft.Authorization/locks",
"apiVersion": "2016-09-01",
"name": "rgLock",
"properties": {
"level": "CanNotDelete",
"notes": "Resource group and its resources should not be deleted."
}
}
],
"outputs": {}
}
}
}
],
"outputs": {}
}
对资源组中的资源应用锁时,请添加 scope 属性。 将 scope 设置为要锁定的资源的名称。
以下示例演示了一个模板,用于创建一个应用服务计划、一个网站,以及在该网站上的锁。 锁的范围设置为网站。
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"hostingPlanName": {
"type": "string"
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]"
}
},
"variables": {
"siteName": "[concat('ExampleSite', uniqueString(resourceGroup().id))]"
},
"resources": [
{
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2020-12-01",
"name": "[parameters('hostingPlanName')]",
"location": "[parameters('location')]",
"sku": {
"tier": "Free",
"name": "f1",
"capacity": 0
},
"properties": {
"targetWorkerCount": 1
}
},
{
"type": "Microsoft.Web/sites",
"apiVersion": "2020-12-01",
"name": "[variables('siteName')]",
"location": "[parameters('location')]",
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', parameters('hostingPlanName'))]"
],
"properties": {
"serverFarmId": "[parameters('hostingPlanName')]"
}
},
{
"type": "Microsoft.Authorization/locks",
"apiVersion": "2016-09-01",
"name": "siteLock",
"scope": "[concat('Microsoft.Web/sites/', variables('siteName'))]",
"dependsOn": [
"[resourceId('Microsoft.Web/sites', variables('siteName'))]"
],
"properties": {
"level": "CanNotDelete",
"notes": "Site should not be deleted."
}
}
]
}
Azure PowerShell
使用Azure PowerShell通过 New-AzResourceLock 命令锁定已部署的资源。
若要锁定资源,请提供资源的名称、资源类型和资源组名称。
New-AzResourceLock -LockLevel CanNotDelete -LockName LockSite -ResourceName examplesite -ResourceType Microsoft.Web/sites -ResourceGroupName exampleresourcegroup
若要锁定资源组,请提供资源组名称。
New-AzResourceLock -LockName LockGroup -LockLevel CanNotDelete -ResourceGroupName exampleresourcegroup
若要获取有关某个锁的信息,请使用 Get-AzResourceLock。 若要获取订阅中的所有锁,请使用:
Get-AzResourceLock
若要获取某个资源的所有锁,请使用:
Get-AzResourceLock -ResourceName examplesite -ResourceType Microsoft.Web/sites -ResourceGroupName exampleresourcegroup
若要获取某个资源组的所有锁,请使用:
Get-AzResourceLock -ResourceGroupName exampleresourcegroup
若要删除某个资源的锁,请使用:
$lockId = (Get-AzResourceLock -ResourceGroupName exampleresourcegroup -ResourceName examplesite -ResourceType Microsoft.Web/sites).LockId
Remove-AzResourceLock -LockId $lockId
若要删除某个资源组的锁,请使用:
$lockId = (Get-AzResourceLock -ResourceGroupName exampleresourcegroup).LockId
Remove-AzResourceLock -LockId $lockId
Azure CLI
若要使用Azure CLI锁定已部署的资源,请使用 az lock create 命令。
若要锁定资源,请提供资源名称、资源类型和资源组名称。
az lock create --name LockSite --lock-type CanNotDelete --resource-group exampleresourcegroup --resource-name examplesite --resource-type Microsoft.Web/sites
若要锁定资源组,请提供资源组名称。
az lock create --name LockGroup --lock-type CanNotDelete --resource-group exampleresourcegroup
若要获取有关锁的信息,请使用 az lock list。 若要获取订阅中的所有锁,请使用:
az lock list
若要获取某个资源的所有锁,请使用:
az lock list --resource-group exampleresourcegroup --resource-name examplesite --namespace Microsoft.Web --resource-type sites --parent ""
若要获取某个资源组的所有锁,请使用:
az lock list --resource-group exampleresourcegroup
若要删除某个资源的锁,请使用:
lockid=$(az lock show --name LockSite --resource-group exampleresourcegroup --resource-type Microsoft.Web/sites --resource-name examplesite --output tsv --query id)
az lock delete --ids $lockid
若要删除某个资源组的锁,请使用:
lockid=$(az lock show --name LockSite --resource-group exampleresourcegroup --output tsv --query id)
az lock delete --ids $lockid
Python
若要使用 Python 锁定已部署的资源,请使用 ManagementLockClient.management_locks.create_or_update_at_resource_group_level 命令。
若要锁定资源,请提供资源名称、资源类型和资源组名称。
import os
from azure.identity import AzureCliCredential
from azure.mgmt.resource import ManagementLockClient
credential = AzureCliCredential()
subscription_id = os.environ["AZURE_SUBSCRIPTION_ID"]
lock_client = ManagementLockClient(credential, subscription_id)
lock_result = lock_client.management_locks.create_or_update_at_resource_level(
"exampleGroup",
"Microsoft.Web",
"",
"sites",
"examplesite",
"lockSite",
{
"level": "CanNotDelete"
}
)
若要锁定某个资源组,请提供该资源组的名称。
import os
from azure.identity import AzureCliCredential
from azure.mgmt.resource import ManagementLockClient
credential = AzureCliCredential()
subscription_id = os.environ["AZURE_SUBSCRIPTION_ID"]
lock_client = ManagementLockClient(credential, subscription_id)
lock_result = lock_client.management_locks.create_or_update_at_resource_group_level(
"exampleGroup",
"lockGroup",
{
"level": "CanNotDelete"
}
)
若要获取有关订阅中所有锁的信息,请使用 ManagementLockClient.management_locks.get。
若要获取订阅中的所有锁,请使用:
import os
from azure.identity import AzureCliCredential
from azure.mgmt.resource import ManagementLockClient
credential = AzureCliCredential()
subscription_id = os.environ["AZURE_SUBSCRIPTION_ID"]
lock_client = ManagementLockClient(credential, subscription_id)
lock_result = lock_client.management_locks.list_at_subscription_level()
for lock in lock_result:
print(f"Lock name: {lock.name}")
print(f"Lock level: {lock.level}")
print(f"Lock notes: {lock.notes}")
若要获取某个资源的锁,请使用:
import os
from azure.identity import AzureCliCredential
from azure.mgmt.resource import ManagementLockClient
credential = AzureCliCredential()
subscription_id = os.environ["AZURE_SUBSCRIPTION_ID"]
lock_client = ManagementLockClient(credential, subscription_id)
lock_result = lock_client.management_locks.get_at_resource_level(
"exampleGroup",
"Microsoft.Web",
"",
"sites",
"examplesite",
"lockSite"
)
print(f"Lock ID: {lock_result.id}")
print(f"Lock Name: {lock_result.name}")
print(f"Lock Level: {lock_result.level}")
若要获取资源组的锁,请使用以下代码:
import os
from azure.identity import AzureCliCredential
from azure.mgmt.resource import ManagementLockClient
credential = AzureCliCredential()
subscription_id = os.environ["AZURE_SUBSCRIPTION_ID"]
lock_client = ManagementLockClient(credential, subscription_id)
lock_result = lock_client.management_locks.get_at_resource_group_level(
"exampleGroup",
"lockGroup"
)
print(f"Lock ID: {lock_result.id}")
print(f"Lock Level: {lock_result.level}")
若要删除某个资源的锁,请使用:
import os
from azure.identity import AzureCliCredential
from azure.mgmt.resource import ManagementLockClient
credential = AzureCliCredential()
subscription_id = os.environ["AZURE_SUBSCRIPTION_ID"]
lock_client = ManagementLockClient(credential, subscription_id)
lock_client.management_locks.delete_at_resource_level(
"exampleGroup",
"Microsoft.Web",
"",
"sites",
"examplesite",
"lockSite"
)
若要删除某个资源组的锁,请使用:
import os
from azure.identity import AzureCliCredential
from azure.mgmt.resource import ManagementLockClient
credential = AzureCliCredential()
subscription_id = os.environ["AZURE_SUBSCRIPTION_ID"]
lock_client = ManagementLockClient(credential, subscription_id)
lock_client.management_locks.delete_at_resource_group_level("exampleGroup", "lockGroup")
REST API
可以使用 管理锁的 REST API锁定已部署的资源。 可以使用 REST API 创建和删除锁,以及检索有关现有锁的信息。
若要创建一个锁,请运行:
PUT https://management.chinacloudapi.cn/{scope}/providers/Microsoft.Authorization/locks/{lock-name}?api-version={api-version}
范围可以是订阅、资源组或资源。 锁名称可以是想要使用的任意名称。 对于 API 版本,请使用 2016-09-01。
在请求中,请包含用于指定锁属性的 JSON 对象。
{
"properties": {
"level": "CanNotDelete",
"notes": "Optional text notes."
}
}
后续步骤
- 若要了解如何以逻辑方式组织资源,请参阅使用标记来组织Azure资源和管理层次结构。
- 可以通过自定义策略在您的订阅中应用限制和规则。 有关详细信息,请参阅 什么是 Azure Policy?