チュートリアル: Azure Cloud HSM リソースのバックアップと復元

Azure Cloud HSM を使用すると、すべてのキー、バージョン、属性、タグ、ロールの割り当てを保持する方法で、ハードウェア セキュリティ モジュール (HSM) をバックアップおよび復元できます。

このチュートリアルでは、次の操作を行います。

  • Cloud HSM リソースのマネージド ID とストレージ アカウントを作成します。
  • ソース Cloud HSM リソースからバックアップを開始します。
  • 移行先の Cloud HSM リソースへの復元を開始して検証します。

重要

Cloud HSM バックアップを作成すると、HSM 内で派生したキーが保護に役立ちます。 Microsoft には、派生キーの可視性やアクセス権がありません。

前提条件

サポートされていない構成

Azure Cloud HSM では、次の機能はサポートされていません。

  • バックアップをソースの Cloud HSM リソースまたは既にアクティブ化されている任意の Cloud HSM リソースに復元する。 復元するには、任意の優先リージョンで別の非アクティブ化された Cloud HSM リソースを使用します。 それ以外の場合、復元操作は失敗し、移行先の Cloud HSM リソースが機能しません。
  • ストレージ コンテナーの Shared Access Signature (SAS) トークンを使用したバックアップと復元。

マネージド ID を適用してストレージ アカウントを作成する

次のセクションのコードを使用して、Azure Cloud HSM にマネージド ID を適用し、HSM バックアップ用のストレージ アカウントを作成します。

マネージド ID の作成

既存の Azure Cloud HSM リソース グループに新しいユーザー割り当てマネージド ID を作成します。 このチュートリアルでは、マネージド ID の名前として CHSM-MSI を使用し、リソース グループの名前として CHSM-SERVER-RG を使用できます。 CHSM-SERVER-RG は、 Azure Cloud HSM オンボード ガイド がリソース グループの例として使用する名前です。

# Define parameters for the new managed identity
$identity = @{
    Location          = "<location>"                                         
    ResourceName      = "<managed-identity-name>"                                         
    ResourceGroupName = "<resource-group>"
    SubscriptionID    = "<subscription-id>"     
}

# Create a new user-assigned managed identity in the specified resource group and location
New-AzUserAssignedIdentity -Name $identity.ResourceName -ResourceGroupName $identity.ResourceGroupName -Location $identity.Location

マネージド ID を Cloud HSM リソースに適用する

Azure Cloud HSM のバックアップと復元の操作では、ソースと移行先の両方の Cloud HSM リソースにマネージド ID を適用する必要があります。

移行先の Cloud HSM リソースは、 NotActivated 状態である必要があります。

各 Cloud HSM クラスターは、マネージド ID を 1 つだけ持つことができます。 ソースと宛先の両方に同じマネージド ID を使用することも、それぞれに異なるマネージド ID を使用することもできます。 このチュートリアルの例では、移行元と移行先の両方の Cloud HSM リソースに同じマネージド ID を適用します。

# Define the parameters for the source Cloud HSM resource
$sourceCloudHSM = @{
    Location          = "<location>"                              
    Sku               = @{ "family" = "B"; "Name" = "Standard_B1" } 
    ResourceName      = "<source-hsm-name>"                
    ResourceType      = "microsoft.hardwaresecuritymodules/cloudHsmClusters" 
    ResourceGroupName = "<source-resource-group>"             
    Force             = $true                                    
}

# Define the parameters for the destination Cloud HSM resource
$destinationCloudHSM = @{
    Location          = "<location>"                              
    Sku               = @{ "family" = "B"; "Name" = "Standard_B1" } 
    ResourceName      = "<destination-hsm-name>"            
    ResourceType      = "microsoft.hardwaresecuritymodules/cloudHsmClusters" 
    ResourceGroupName = "<destination-resource-group>"             
    Force             = $true                                    
}

# Define the Cloud HSM managed identity patch payload
$chsmMSIPatch = '{
    "Sku": {
        "Family": "B",
        "Name": "Standard_B1"
    },
    "Location": "<location>",    
    "Identity": {
        "type": "UserAssigned",
        "userAssignedIdentities": {
            "/subscriptions/<subscription-id>/resourcegroups/<resource-group>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<managed-identity-name>": {}
        }
    }
}'

# Construct the source URI
$sourceURI = "/subscriptions/$($identity.SubscriptionID)/resourceGroups/$($sourceCloudHSM.ResourceGroupName)/providers/Microsoft.HardwareSecurityModules/cloudHsmClusters/$($sourceCloudHSM.ResourceName)?api-version=2025-03-31"

# Construct the destination URI
$destinationURI = "/subscriptions/$($identity.SubscriptionID)/resourceGroups/$($destinationCloudHSM.ResourceGroupName)/providers/Microsoft.HardwareSecurityModules/cloudHsmClusters/$($destinationCloudHSM.ResourceName)?api-version=2025-03-31"

# Invoke the REST method to update the source Cloud HSM resource with the managed identity patch
Invoke-AzRestMethod -Path $sourceURI -Method Put -Payload $chsmMSIPatch

# Invoke the REST method to update the destination Cloud HSM resource with the managed identity patch
Invoke-AzRestMethod -Path $destinationURI -Method Put -Payload $chsmMSIPatch

プライベート仮想ネットワークにストレージ アカウントを作成する

プライベート仮想ネットワーク内でストレージ アカウントと関連する BLOB コンテナーを定義して構成することで、Azure Cloud HSM バックアップ操作のストレージ インフラストラクチャを設定します。

まず、サブスクリプション ID を定義します。 場所、製品レベル、種類など、ストレージ アカウントのパラメーターを指定します。

このプロセスには、新しいリソース グループの作成、指定された仮想ネットワークへのアクセスを制限するためのネットワーク 規則を使用したストレージ アカウントの確立、プライベート エンドポイントによるセキュリティの強化が含まれます。 ストレージ BLOB データ共同作成者ロールは、バックアップ タスクに対する適切なアクセス許可を確保するために、指定された ID に割り当てられます。

次のコードでは、次の例を使用できます。

  • リソース グループの名前には CHSM-BACKUP-RG
  • ストレージ アカウントの名前には chsmbackup00
  • BLOB コンテナーには chsmbackupcontainer00

読み取り/書き込みアクセス権は、ソースと宛先の両方に対して付与されます。

重要

必要な最小限の RBAC ロールは、ストレージ BLOB データ共同作成者です。 パブリック ストレージ アカウントにはパブリック インターネット経由でアクセスできるため、セキュリティを強化するためにストレージ アカウントをプライベート仮想ネットワークの背後に配置します。

# Define the subscription ID
$subscriptionId = "<subscription-id>"

# Define storage account parameters
$storageAccount = @{
    Location          = "<location>"                    
    ResourceGroupName = "<backup-resource-group>" 
    AccountName       = "<storage-account-name>"      # Name of the storage account
    SkuName           = "<storage-sku>"     # Storage account tier (example: Standard_LRS)
    Kind              = "<storage-type>"       #Type of storage account (example: StorageV2)
}

# Define the blob container parameters
$container = @{
    ResourceGroupName  = $storageAccount.ResourceGroupName # Resource group name where the storage account is located
    StorageAccountName = $storageAccount.AccountName      # Name of the storage account
    ContainerName      = "<container-name>"              # Name of the blob container
}

# Define the private endpoint parameters
# Storage accounts are publicly accessible, so put it behind a private virtual network
$privateEndpoint = @{
    Name              = "<private-endpoint-name>"
    VnetName          = "<vnet-name>"  # Name of the existing virtual network
    SubnetName        = "<subnet-name>"  # Name of the existing subnet within the virtual network
    ResourceGroupName = "<resource-group>" # Resource group for private virtual network and subnet (example: CHSM-CLIENT-RG)
}

# Define the role assignment parameters
$roleAssignment = @{
    RoleDefinitionName = "Storage Blob Data Contributor"  # Minimum RBAC role required
    PrincipalId        = "<principal-id>"  # The ID of the managed identity or user to assign the role to
    Scope              = "/subscriptions/$($subscriptionId)/resourceGroups/$($storageAccount.ResourceGroupName)/providers/Microsoft.Storage/storageAccounts/$($storageAccount.AccountName)"
}

# Create a new resource group with the specified name and location
New-AzResourceGroup -Name $storageAccount.ResourceGroupName -Location $storageAccount.Location -Force

# Create a new storage account in the specified resource group and location
# This command sets up the storage account needed for backup operations
New-AzStorageAccount -ResourceGroupName $storageAccount.ResourceGroupName `
    -Name $storageAccount.AccountName `
    -Location $storageAccount.Location `
    -SkuName $storageAccount.SkuName `
    -Kind $storageAccount.Kind

# Retrieve the storage account key
$storageAccountKey = (Get-AzStorageAccountKey -ResourceGroupName $storageAccount.ResourceGroupName -Name $storageAccount.AccountName)[0].Value

# Create the storage context
$storageAccountContext = New-AzStorageContext -StorageAccountName $storageAccount.AccountName -StorageAccountKey $storageAccountKey

# Create the blob container in the storage account
New-AzStorageContainer -Name $container.ContainerName -Context $storageAccountContext

# Retrieve the virtual network and subnet object
$vnet = Get-AzVirtualNetwork -ResourceGroupName $privateEndpoint.ResourceGroupName -Name $privateEndpoint.VnetName
$subnet = $vnet.Subnets | Where-Object { $_.Name -eq $privateEndpoint.SubnetName }

# Create the private endpoint for the storage account in the existing virtual network
New-AzPrivateEndpoint -ResourceGroupName $storageAccount.ResourceGroupName `
    -Name $privateEndpoint.Name `
    -Location $storageAccount.Location `
    -PrivateLinkServiceConnection @(
        @{
            Name = "$($storageAccount.AccountName)-connection"
            PrivateLinkServiceConnectionState = @{
                Status = "Approved"
                Description = "Private Endpoint Connection"
            }
            PrivateLinkServiceId = "/subscriptions/$subscriptionId/resourceGroups/$($storageAccount.ResourceGroupName)/providers/Microsoft.Storage/storageAccounts/$($storageAccount.AccountName)"
            GroupIds = @("blob")  # Add this parameter with the required group ID
        }
    ) `
    -Subnet $subnet 

# Assign the Storage Blob Data Contributor role to the specified identity
New-AzRoleAssignment -RoleDefinitionName $roleAssignment.RoleDefinitionName `
    -PrincipalId $roleAssignment.PrincipalId `
    -Scope $roleAssignment.Scope

ポータル設定を使用して共有キーアクセスを無効にする

共有キー アクセスを無効にしてセキュリティを強化する:

  1. Azure portal で、Azure ストレージ アカウントに移動します。
  2. [設定]>[構成] を選択します。
  3. [Allow storage account key access](ストレージ アカウント キーのアクセスを許可する)[無効] に設定します。

ソース Cloud HSM リソースからバックアップを開始する

ストレージ コンテナー URI を含む POST 要求をバックアップ API エンドポイントに送信して、ソース Cloud HSM リソースのバックアップを開始します。 応答ヘッダーの URL に GET 要求を送信して、バックアップの進行状況を監視します。

次のスクリプトは、応答からバックアップ ジョブの状態と一意のバックアップ ID を取得して表示します。 状態は、バックアップが開始されたことを確認し、その進行状況を追跡します。

# Define backup properties, including the URI for the Azure Blob Storage container
$backupProperties = ConvertTo-Json @{
    azureStorageBlobContainerUri = "https://$($container.StorageAccountName).blob.core.windows.net/$($container.ContainerName)"
}

# Construct the URI for the backup operation by using the provided parameters
$backupUri = "/subscriptions/$($identity.SubscriptionID)/resourceGroups/$($sourceCloudHSM.ResourceGroupName)/providers/Microsoft.HardwareSecurityModules/cloudHsmClusters/$($sourceCloudHSM.ResourceName)/backup?api-version=2025-03-31"

# Initiate the backup operation by sending a POST request with the backup properties
$response = Invoke-AzRestMethod -Path $backupUri -Method Post -Payload $backupProperties

# Check the backup job status to confirm that it succeeded
$jobStatus = Invoke-AzRestMethod -Method 'GET' -Uri $response.Headers.Location
$backupStatus = (ConvertFrom-Json $jobStatus.Content).properties.status

# Extract the backup ID from the job status response
$backupID = (ConvertFrom-Json $jobStatus.Content).properties.backupId

# Output the backup status and backup ID
$backupStatus
$backupID

予期される出力: $backupStatusSucceededを返し、 $backupID は開始したバックアップの対応する ID を示します。

移行先の Cloud HSM リソースへの復元を開始する

ストレージ コンテナーの URI やバックアップ ID など、必要な復元プロパティを指定して、移行先の Cloud HSM リソースの復元操作を開始します。

次のスクリプトは、復元 API エンドポイントの正しい URI を作成し、復元を開始するための POST 要求を送信します。 復元の進行状況を監視するには、応答ヘッダーで指定された場所に GET 要求を送信し、復元ジョブの状態を取得して完了を確認します。

$restoreProperties = ConvertTo-Json @{
    "azureStorageBlobContainerUri" = "https://$($container.StorageAccountName).blob.core.windows.net/$($container.ContainerName)"
    "backupId" = "$($backupID)"
}

# Set the URI for the restore API endpoint by using the subscription ID, resource group, and destination server details
$restoreUri = "/subscriptions/$($identity.SubscriptionID)/resourceGroups/$($destinationCloudHSM.ResourceGroupName)/providers/Microsoft.HardwareSecurityModules/cloudHsmClusters/$($destinationCloudHSM.ResourceName)/restore?api-version=2025-03-31"

# Initiate the restore operation by sending a POST request to the restore API endpoint with the defined properties
$response = Invoke-AzRestMethod -Path $restoreUri -Method Post -Payload $restoreProperties 

# Check the status of the restore job by sending a GET request to the location provided in the response headers
$jobStatus = Invoke-AzRestMethod -Method 'GET' -Uri $response.Headers.Location

# Extract and display the status of the restore job
(ConvertFrom-Json $jobStatus.Content).properties.status

予期される出力: $jobStatusSucceededを返す必要があります。

移行先の Cloud HSM リソースへの復元を検証する

しばらくすると、復元操作は Succeededを示し、移行先の Cloud HSM リソースに Activeのアクティブ化状態が表示されます。 復元操作を実行した移行先の Cloud HSM リソースに接続すると、 azcloudhsm_mgmt_utilgetClusterInfo を実行すると、3 つのノードすべてがアクティブで使用可能として表示されます。

重要

管理仮想マシンから Azure Cloud HSM に接続する場合は、クライアント構成ファイルと管理構成ファイル (azcloudhsm_resource.cfg) の両方を更新して、復元を実行した適切な移行先の Cloud HSM リソースをポイントします。

  1. 次のいずれかのコマンドを実行して、 azcloudhsm_mgmt_util を開始します。

    Linux:

    cd /usr/local/bin/AzureCloudHSM-ClientSDK-* 
    sudo ./azcloudhsm_mgmt_util ./azcloudhsm_resource.cfg
    

    ウィンドウズ:

    cd azcloudhsm_mgmt_util 
    .\azcloudhsm_mgmt_util.exe .\azcloudhsm_resource.cfg
    
  2. 管理ツール内では、プロンプトが cloudmgmtされます。 クラスター情報を一覧表示するには、次のコマンドを実行します。

    getClusterInfo  
    

    予想される出力: getClusterInfo は、3 つのノードすべてが Azure Cloud HSM クラスターで使用できるようになったことを確認する必要があります。

  3. 管理ツールを閉じ、Azure Cloud HSM ツール (azcloudhsm_util) を開きます。 CUとしてサインインし、findKey コマンドを実行します。

    重要

    キー ハンドルは動的であるため、変更される可能性があります。 ただし、キー ID は変更されません。

    Linux:

    ./azcloudhsm_util  
    loginHSM -u CU -s cu1 -p user1234
    findKey
    

    ウィンドウズ:

    azcloudhsm_util.exe
    loginHSM -u CU -s cu1 -p user1234  
    findKey