リソースをロックしてインフラストラクチャを保護する

管理者であれば、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 は、待機期間が経過した後にのみ、リソースを完全に削除します。

ロックのスコープについて

Note

ロックは、コントロール プレーンの Azure 操作にのみ適用され、データ プレーンの操作には適用されません。

Azure コントロール プレーンの操作は、https://management.azure.com に移動します。 Azure データ プレーン操作は、https://myaccount.blob.core.windows.net/ などのサービス インスタンスに移動します。 「Azure コントロール プレーンとデータ プレーン」を参照してください。 コントロール プレーンの URL が使用される操作を確認するには、Azure REST API に関するページを参照してください。

この区別は、ロックによりリソースが変更から保護されることを意味しますが、リソースがその機能を実行する方法を制限するものではありません。 たとえば、SQL Database の論理サーバーの ReadOnly ロックは、削除や変更から保護します。 これにより、サーバー データベースのデータを作成、更新、削除できます。 データ プレーン操作により、データ トランザクションが可能になります。 これらの要求は https://management.azure.com に移動しません。

ロック適用前の考慮事項

ロックを適用すると、予期しない結果が起こることがあります。 リソースを変更しないように見える操作でも、ブロックされたアクションを必要とするものがあります。 ロックにより、POST メソッドで Azure Resource Manager (ARM) API にデータを送信できなくなります。 ブロックされた操作の一般的な例を次に示します。

  • 読み取り専用ロックをストレージ アカウントに対して設定すると、ユーザーがアカウント キーを一覧表示できなくなります。 POST 要求は、Azure Storage リスト キー操作を処理して、アカウント キーへのアクセスを保護します。 アカウント キーは、ストレージ アカウント内のデータへの完全なアクセスを提供します。 ストレージ アカウントに対して読み取り専用ロックが設定されている場合、アカウント キーを持っていないユーザーは、BLOB またはキュー データへのアクセスに Microsoft Entra 資格情報を使用する必要があります。 読み取り専用ロックによって、ストレージ アカウントまたはデータ コンテナー (BLOB コンテナーまたはキュー) にスコープが設定されている Azure RBAC ロールの割り当てもできなくなります。

  • ストレージ アカウントの読み取り専用ロックは、ストレージ アカウントまたはデータ コンテナー (BLOB コンテナーまたはキュー) を対象にした RBAC の割り当てを保護します。

  • ストレージ アカウントの読み取り専用ロックにより、BLOB コンテナーが作成できなくなります。

  • ストレージ アカウントの読み取り専用ロックや削除不可ロックにより、そのデータの削除や変更ができなくなることはありません。 また、BLOB、キュー、テーブル、ファイルのデータも保護されません。

  • ストレージ アカウント API は、データ プレーンコントロール プレーンの操作を公開します。 要求でデータ プレーン操作が使用されている場合、ストレージ アカウントのロックでは、そのストレージ アカウント内の BLOB、キュー、テーブル、またはファイル データは保護されません。 しかし、要求でコントロール プレーン操作が使用されている場合は、ロックによってそれらのリソースが保護されます。

    たとえば、要求でコントロール プレーンの操作である [ファイル共有] - [削除] が使用されている場合、削除は失敗します。 要求が、データ プレーン操作である [共有の削除] を使用している場合、削除は成功します。 コントロール プレーン操作を使用することをお勧めします。

  • ネットワーク セキュリティ グループ (NSG) の読み取り専用ロックを使用すると、対応する NSG フロー ログを作成できなくなります。 ネットワーク セキュリティ グループ (NSG) の削除不可ロックを使用すると、対応する NSG フロー ログを作成または変更できなくなります。

  • 読み取り専用ロックを App Service リソースに設定すると、Visual Studio のサーバー エクスプローラーの操作には書き込みアクセスが必要となるため、Visual Studio のサーバー エクスプローラーはリソース用のファイルを表示できなくなります。

  • App Service プランを含むリソース グループに対する読み取り専用ロックを設定すると、プランのスケールアップやスケールアウトはできません。

  • 読み取り専用ロックを、仮想マシンを含むリソース グループに設定すると、どのユーザーも仮想マシンを起動したり、再起動したりできなくなります。 これらの操作では、POST 要求が必要です。

  • リソース グループに対する読み取り専用ロックを使用すると、既存のリソースをリソース グループ内またはリソース グループ外に移動できなくなります。

  • Automation アカウントを含むリソース グループの読み取り専用ロックでは、すべての Runbook が起動できません。 これらの操作では、POST 要求が必要です。

  • リソースまたはリソース グループのロックを削除できないと、Azure RBAC の割り当てを削除できません。

  • 削除不可ロックをリソース グループに設定すると、Azure Resource Manager が履歴内のデプロイを自動的に削除できなくなります。 履歴内のデプロイが 800 に達した場合、デプロイは失敗します。

  • Azure Backup サービスによって作成されたリソース グループに削除不可のロックを設定した場合、バックアップは失敗するようになります。 このサービスでは、最大 18 個の復元ポイントがサポートされています。 ロックされている場合、バックアップ サービスは復元ポイントをクリーンアップできません。 詳細については、「よく寄せられる質問 - Azure VM のバックアップ」を参照してください。

  • Azure Machine Learning ワークスペースを含むリソース グループの削除負荷ロックがあると、Azure Machine Learning コンピューティング クラスターの自動スケーリングが正しく機能しなくなります。 このロックを使用すると、自動スケーリングは未使用のノードを削除できません。 ソリューションは、ワークロードに必要なリソースよりも多くのリソースを消費します。

  • Log Analytics ワークスペースの読み取り専用ロックにより、ユーザーとエンティティの動作分析 (UEBA) が有効になりません。

  • Log Analytics ワークスペースの削除不可ロックでは、データ消去操作を回避できません。 代わりに、ユーザーからデータの消去ロールを削除してください。

  • サブスクリプションに読み取り専用ロックを設定すると、Azure Advisor が正常に機能しなくなります。 Advisor は、クエリの結果を格納できません。

  • Application Gateway に読み取り専用のロックがかかっていると、アプリケーション ゲートウェイのバックエンドのヘルスを取得できません。 この操作では POST メソッドを使いますが、読み取り専用ロックによりブロックされます。

  • Azure Kubernetes Service (AKS) クラスターの読み取り専用ロックでは、ポータルを介してクラスター リソースにアクセスする方法が制限されます。 読み取り専用ロックにより、Azure portal で AKS クラスターの Kubernetes リソース セクションを使って、クラスター リソースを選択できなくなります。 これらの操作には、認証のための POST メソッド要求が必要です。

  • Site Recovery によって保護されている仮想マシンに削除不可のロックがある場合、保護を削除しても、またはレプリケーションを無効にしても、Site Recovery に関連する特定のリソース リンクが適切に削除されません。 後で VM を再度保護する予定の場合は、保護を無効にする前にロックを削除する必要があります。 ロックを削除しない場合、VM を保護するには、特定の手順に従って古いリンクを事前にクリーンアップする必要があります。 詳細については、「Azure VM レプリケーションのトラブルシューティング」を参照してください。

誰がロックを作成または削除できるか

管理ロックを作成または削除するには、Microsoft.Authorization/* または Microsoft.Authorization/locks/* アクションにアクセスする必要があります。 所有者ユーザー アクセス管理者ロールに割り当てられているユーザーには、必要なアクセス権があります。 一部の特殊な組み込みロールにも、このアクセスが許可されます。 必要な権限を含むカスタム ロールを作成することができます。

マネージド アプリケーションとロック

Azure Databricks などの一部の Azure サービスでは、マネージド アプリケーションを使用してサービスが実装されています。 その場合、サービスで 2 つのリソース グループが作成されます。 1 つは、サービスの概要を含むロック解除されたリソース グループです。 もう 1 つは、サービスのインフラストラクチャを含むロックされたリソース グループです。

インフラストラクチャのリソース グループを削除しようとすると、リソース グループがロックされていることを示すエラーが表示されます。 インフラストラクチャのリソース グループのロックを削除しようとすると、システム アプリケーションによって所有されているためロックを削除できないことを示すエラーが表示されます。

代わりに、サービスを削除すると、インフラストラクチャのリソース グループも削除されます。

マネージド アプリケーションには、デプロイしたサービスを選びます。

Screenshot of the Azure portal with an instance of Azure Databricks selected.

サービスにマネージド リソース グループへのリンクが含まれることに注意してください。 そのリソース グループがインフラストラクチャを保持しており、ロックされています。 この場合、間接的にしか削除できません。

Screenshot displaying the Managed Resource Group link in the Azure portal.

ロックされているインフラストラクチャ リソース グループを含め、サービスのすべてのものを削除するには、サービスの [削除] を選びます。

Screenshot of the Azure portal with the Delete option for the selected service.

ロックの構成

ポータル

左側のナビゲーション パネルでは、サブスクリプション ロック機能の名前は [リソース ロック] で、リソース グループ ロック機能の名前は [ロック] です。

  1. ロックを適用するリソース、リソース グループ、またはサブスクリプションの [設定] ブレードで、 [ロック]を選択します。

    Select lock.

  2. ロックを追加するには、[追加] を選択します。 親レベルでロックを作成する場合は、親を選択します。 現在選択されているリソースは、ロックを親から継承します。 たとえば、リソース グループをロックすることで、グループのリソースすべてにロックを適用することができます。

    Add lock.

  3. ロックに名前とロック レベルを指定します。 必要に応じて、ロックについて説明したメモを追加することができます。

    Set lock.

  4. ロックを削除するには、 [削除] ボタンを選択します。

    Delete lock.

Template

ARM テンプレートまたは Bicep ファイルを使ってロックをデプロイする場合、デプロイ スコープとロック スコープがどのように連携するかを理解することをお勧めします。 リソース グループやサブスクリプションのロックなど、デプロイ スコープでロックを適用する場合、スコープ プロパティを設定解除されたままにします。 デプロイ スコープ内のリソースをロックする場合は、ロックのスコープ プロパティを設定します。

次のテンプレートは、リソース グループにロックを適用します。 ロック スコープがデプロイ スコープと一致するため、ロック リソースにスコープ プロパティがないことに注意してください。 このテンプレートを、リソース グループ レベルでデプロイします。

{
  "$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": {}
}

リソース グループ内のリソースにロックを適用する場合は、スコープ プロパティを追加します。 スコープを、ロックするリソースの名前に設定します。

次の例では、App Service プラン、Web サイト、および Web サイトに対するロックを作成するテンプレートを示します。 ロックのスコープは、Web サイトに設定されています。

{
  "$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.azure.com/{scope}/providers/Microsoft.Authorization/locks/{lock-name}?api-version={api-version}

スコープには、サブスクリプション、リソース グループ、またはリソースを使用できます。 ロック名は、任意の名前を指定できます。 API バージョンには、2016-09-01 を使用します。

要求に、ロックのプロパティを指定する JSON オブジェクトを含めます。

{
  "properties": {
  "level": "CanNotDelete",
  "notes": "Optional text notes."
  }
}

次のステップ