Azure AI Search(旧 Azure Cognitive Search)を削除しようとして「LockedSPLResourceFound / ConflictError」で失敗する場合、原因は管理ロックではなく Shared Private Link(SPL)リソースの残骸であることが多いです。ポータルで見えないSPLの特定から、REST API/CLIでの削除、再発防止の片付け順までまとめます。
削除できない症状:LockedSPLResourceFound が出る
今回のケースでは、Azure AI Search サービス aifoundry-poc-search-220bfb78(リソースグループ:TestResourceGroup)を削除しようとすると、次のようなエラーで削除が止まります。
(ConflictError) Unable to delete Search Service...
LockedSPLResourceFound: Unable to verify management locks on Resource
'/subscriptions/.../providers/Microsoft.DocumentDB/databaseAccounts/aifoundry-poc-cosmos-220bfb78'.
If you still want to delete the search service, manually delete the SPL resource first and try again.
すでに以下を試しても解決しない、という状況が典型です。
- ポータルの「ロック(CanNotDelete / ReadOnly)」を確認したが、ロックが見つからない
- Azure Resource Graph で隠れたロックや孤立リソースを探したが見つからない
- Azure CLI でも削除を試したが同じエラーで失敗する
結論:原因は「管理ロック」ではなく Shared Private Link(SPL)リソース
エラーメッセージの “locks” は、Azure の管理ロック(CanNotDelete / ReadOnly)を指しているように見えますが、実務的には「Shared Private Link(SPL)関連の後始末ができない」ことを示している場合が多いです。特に、Search と Cosmos DB などを Private Link でつないだ検証後に起きやすいパターンです。
今回のエラーに Cosmos DB アカウント aifoundry-poc-cosmos-220bfb78(Microsoft.DocumentDB/databaseAccounts)が出ているので、Search サービス側に作られた Shared Private Link リソースが、Cosmos DB へのひも付け情報として残存している可能性が極めて高いです。
| 見えている現象 | 実際に起きていること | 最初にやるべきこと |
|---|---|---|
| ロックを探しても見つからない | 管理ロックではなく、SPL の削除処理が完了できず Search の削除がブロックされている | Search サービス配下の sharedPrivateLinkResources を列挙する |
| 対象リソースが既に消えているのにエラーが出る | SPL が「孤立」して参照だけが残っている(または承認・削除フローが中断した) | ポータルで見えなければ REST API で SPL を直接削除する |
| ConflictError が出る | 削除時にターゲット側 Resource Provider に到達してメタデータ更新が必要だが、ロック等で拒否されることがある | ターゲット(Cosmos DB など)のロック/権限/状態を確認し、SPL を先に消す |
Shared Private Link(SPL)とは何か:Private Endpoint とどう違う?
Shared Private Link(SPL)は、Azure AI Search が Storage / Cosmos DB / Key Vault などの PaaS に対して、Search 側が管理する Private Endpoint 経由で安全に「アウトバウンド接続」するための仕組みです。ポイントは、単に“リンク情報”があるだけでなく、裏側で Private Endpoint や DNS マッピングの作成・削除も伴うことです。
検索サービスの「インバウンド(クライアントから Search へのアクセス)」に使う Private Endpoint と混同しやすいので、整理しておきます。
| 観点 | Search サービス自体の Private Endpoint | Shared Private Link(SPL) |
|---|---|---|
| 用途 | クライアント → Search へのプライベート接続(インバウンド) | Search → Storage/Cosmos/KeyVault 等へのプライベート接続(アウトバウンド) |
| 管理主体 | 通常は利用者(VNet/Private Endpoint を自分で作成) | Search が作成・管理(専用の Private Endpoint / DNS を伴う) |
| 削除時の落とし穴 | PE を消してから Search を消す、などの依存順序 | SPL が残ると Search の削除がブロックされる |
つまり、Search サービスを消す前に、Search 配下の SPL(Shared Private Link リソース)を “空” にするのが鉄則です。
なぜ Search サービスの削除がブロックされるのか
Shared Private Link の削除は、Search サービスが要求を受けて Azure Resource Manager(ARM)が裏側の実作業を行う、非同期の削除フローです。削除が成功すると、バックエンドの Private Endpoint と DNS マッピングも消え、一覧(List)からも消えます。
ただし削除の途中で、ターゲット(今回なら Cosmos DB)側の Resource Provider に対して、Private Endpoint 接続情報の除去などの更新が必要になる場合があります。この時、ターゲット側にロックがある、または参照が孤立して整合が取れない、といった理由で処理が失敗すると、Search サービスの削除まで連鎖して止まることがあります。
解決までの全体像
やることはシンプルで、順番がすべてです。
- Search サービス配下に残っている Shared Private Link(SPL)を特定する
- 特定した SPL を削除する(ポータルで見えなければ REST API / CLI / PowerShell)
- SPL が空になったことを確認してから、Search サービスを削除する
Microsoft 側の案内でも、LockedSPLResourceFound が出る場合は「SPL を先に削除してから Search を削除する」ことが明示されています。
手順:SPL を特定する(ポータルで見える場合)
まずは最短ルートとして、ポータルで確認します。
- 対象の Azure AI Search(
aifoundry-poc-search-220bfb78)を開く - Networking(ネットワーク)へ移動
- Shared private access / Shared private link resources(表示名は環境により差)を開く
- 一覧に出てくる Shared Private Link を削除する
「削除できない」エラーの文面通り、ここで SPL が残っている限り Search の削除は通りません。
注意:ポータルに何も表示されないのにエラーが出るケースがあり、今回のような「孤立した SPL」がそれに該当します。その場合は次の CLI/REST の手順に進みます。
手順:SPL を特定する(Azure CLI で列挙する)
ポータルで見えない/確証を持ちたい場合は、Search サービス配下の Shared Private Link リソースを CLI で列挙します。
列挙コマンド(推奨:service サブコマンド)
az search service shared-private-link-resource list \
--resource-group TestResourceGroup \
--search-service-name aifoundry-poc-search-220bfb78 \
--output table
このコマンドで “残っている SPL の名前” を特定できます。
(補足)別系統のコマンド表記が出てくることがある
環境や情報源によっては、次の形式で紹介されていることがあります。
az search shared-private-link-resource list \
--resource-group TestResourceGroup \
--service-name aifoundry-poc-search-220bfb78
いずれも目的は同じで、「Search サービス配下の shared private link resources を列挙する」ことです。手元の CLI で az search --help を見て、存在する方を使ってください。
出力のどこを見るか(重要プロパティ)
SPL の実体は Microsoft.Search/searchServices/sharedPrivateLinkResources という子リソースで、典型的に次のプロパティを持ちます。
| 項目 | 意味 | 今回のチェック観点 |
|---|---|---|
name | SPL リソース名 | 削除時に必要(この値を指定して delete) |
properties.privateLinkResourceId | 接続先リソースの ARM ID | .../Microsoft.DocumentDB/databaseAccounts/aifoundry-poc-cosmos-220bfb78 を指していないか |
properties.groupId | ターゲット側のグループ | Cosmos DB for NoSQL の場合は Sql が出ることが多い |
properties.provisioningState | 作成/削除の状態 | Succeeded / Failed 以外だと削除できないことがある |
properties.status | 承認状態 | Pending のまま放置されていないか |
REST API のサンプル応答にも、groupId や privateLinkResourceId が含まれることが示されています。
手順:SPL を削除する(Azure CLI)
特定した SPL を削除します。SPL が複数ある場合は、Search 配下の SPL をすべて削除してください(1つ残っているだけで Search の削除が詰まります)。
単体削除
az search service shared-private-link-resource delete \
--resource-group TestResourceGroup \
--search-service-name aifoundry-poc-search-220bfb78 \
--name <sharedPrivateLinkResourceName> \
--yes
削除は非同期になり得るため、実行直後に一覧から消えないことがあります。
削除完了待ち(推奨)
az search service shared-private-link-resource wait \
--resource-group TestResourceGroup \
--search-service-name aifoundry-poc-search-220bfb78 \
--name <sharedPrivateLinkResourceName> \
--deleted
「消したつもりで残っていた」を防ぐため、待ち(wait)を挟むと事故率が下がります。
複数ある場合:まとめて削除する(例:Bash)
for spl in $(az search service shared-private-link-resource list \
-g TestResourceGroup \
--search-service-name aifoundry-poc-search-220bfb78 \
--query "[].name" -o tsv); do
az search service shared-private-link-resource delete \
-g TestResourceGroup \
--search-service-name aifoundry-poc-search-220bfb78 \
-n $spl -y
done
手順:SPL を削除する(REST API / az rest で“見えないSPL”を消す)
ポータルに出てこない孤立 SPL は、Search 管理 REST API で直接たたくのが確実です。ここでは az rest を使って、認証やトークン周りの面倒を減らします。
一覧取得(List By Service)
az rest --method get --url \
"https://management.azure.com/subscriptions/<subscriptionId>/resourceGroups/TestResourceGroup/providers/Microsoft.Search/searchServices/aifoundry-poc-search-220bfb78/sharedPrivateLinkResources?api-version=2025-05-01"
応答の value 配列に SPL が並び、name と properties.privateLinkResourceId を見れば、どのターゲット(Cosmos DB など)につながっているかが分かります。
削除(Delete)
az rest --method delete --url \
"https://management.azure.com/subscriptions/<subscriptionId>/resourceGroups/TestResourceGroup/providers/Microsoft.Search/searchServices/aifoundry-poc-search-220bfb78/sharedPrivateLinkResources/<sharedPrivateLinkResourceName>?api-version=2025-05-01"
成功時は 202 Accepted(非同期)になることがあり、その場合は Azure-AsyncOperation などの URL がレスポンスヘッダーに返ることがあります。
API バージョンについて:本記事では例として 2025-05-01 を使っていますが、環境によって利用可能なバージョンは変わり得ます。テンプレート参照では複数の API バージョンが列挙されているため、運用に合わせて選んでください。
手順:SPL を削除する(PowerShell)
PowerShell を使う場合は、SPL を削除する専用コマンドレットが用意されています。
Remove-AzSearchSharedPrivateLinkResource \
-ResourceGroupName TestResourceGroup \
-ServiceName aifoundry-poc-search-220bfb78 \
-Name <spl-name> \
-Force
スクリプトで整備しておくと、検証環境の片付けが一段楽になります。
手順:Azure AI Search サービスを削除する
SPL が “空” になったら、改めて Search サービス本体を削除します。
az search service delete \
--name aifoundry-poc-search-220bfb78 \
--resource-group TestResourceGroup \
--yes
LockedSPLResourceFound が出ていた環境でも、SPL を先に削除できていれば、この削除は通る可能性が非常に高いです。実際に Microsoft Q&A でも、SPL 削除後に Search サービス削除が成功したことが報告されています。
状態がややこしいときの判断基準:provisioningState と status
「削除がいつまでも終わらない」「削除ボタンが押せない」場合、SPL の状態が削除可能なフェーズに入っていないことがあります。特に Updating / Incomplete / Deleting のまま長時間止まるケースです。
| 項目 | よく出る値 | 意味(ざっくり) | 実務の動き |
|---|---|---|---|
provisioningState | Succeeded | 作成が完了して、承認待ち/利用可能 | 削除してOK(ただし削除は非同期) |
provisioningState | Failed | 作成/削除が失敗した状態 | 原因修正後に削除 or 作り直し |
provisioningState | Updating / Incomplete | 処理中(稀に長時間ハング) | 数時間待つ/別名で作り直し/状態が Failed になってから消す |
status | Pending | ターゲット側の承認待ち | 放置すると後で“孤立”しやすい。使わないなら早めに削除 |
Microsoft のトラブルシュートでは、非終端状態の SPL は削除できないことがある、稀に最大 8 時間程度状態が遷移しないことがある、といった挙動が整理されています。
削除がまだ失敗する場合の追加トラブルシュート
ターゲット(Cosmos DB 側)にロックがある/権限が足りない
SPL の削除や Search の削除の途中で、ARM がターゲット側に到達し、Private Endpoint のメタデータを外す必要があることがあります。ターゲット側にロックがある(またはロック確認・変更の権限がない)と、Conflict で止まることがあります。
この場合の方針は次のいずれかです。
- ターゲットリソース(Cosmos DB アカウントやそのリソースグループ/サブスクリプション)にロックがないか再確認し、あれば解除する
- 権限が分かれている組織では、ターゲット側の管理者に依頼して解除してもらう
- まず Search 側の SPL を削除できる状態にしてから、Search を削除する(本記事の順番)
ポータルでは見えないが、REST では見える(孤立 SPL)
「Networking に何もないのに削除できない」パターンは、Q&A でも複数報告があります。こういうときは、REST の List → Delete が最短です。
「削除中」のまま長時間終わらない
Shared Private Link の削除はバックエンドの Private Endpoint / DNS も絡むため、短時間で終わるのが通常ですが、長時間かかる例も示されています。まずは CLI の wait や、数十分〜数時間の猶予を取り、状態遷移を確認してください。
再発防止:検証環境の片付け順序を決めておく
POC や検証で Search + Cosmos DB + Private Link を組み合わせると、リソースの削除順序がバラついた瞬間に “孤立した構成” が生まれがちです。おすすめの削除順をテンプレ化しておくと、次回のハマりが激減します。
| 推奨順 | 削除/解除対象 | 理由 |
|---|---|---|
| 最初 | Search 配下の Shared Private Link(SPL)を全削除 | SPL が残ると Search サービス削除がブロックされる |
| 次 | ターゲット側の Private Endpoint 接続(承認/拒否/残骸の整理) | ターゲット側に残る接続情報が、SPL 削除の失敗要因になることがある |
| 次 | Search サービス本体を削除 | SPL が空なら削除が通りやすい |
| 最後 | Cosmos DB / Storage / Key Vault など、周辺リソースを削除 | 参照先を先に消すと “孤立 SPL” を作りやすい |
“片付け” を人力でやるのがつらい場合は、削除前に SPL を列挙して全削除する処理だけでもスクリプト化しておくと、LockedSPLResourceFound をほぼ回避できます。
まとめ:LockedSPLResourceFound は「SPL を先に消して」の合図
- LockedSPLResourceFound は管理ロックの話に見えて、実態は Shared Private Link(SPL)起因の削除ブロックであることが多い
- ポータルで見えない場合でも、Search 配下の
sharedPrivateLinkResourcesは REST/CLI で列挙できる - SPL を削除 →(必要なら完了待ち)→ Search サービス削除の順番で解決できるケースが多い
今回の aifoundry-poc-search-220bfb78 のように「ロックはないのに消せない」状況では、まず SPL を疑うのが最短ルートです。

コメント