Azure CLI 2.77 で az batch application package create が失敗する原因と対処法

2025年9月ごろから、Azure DevOps などの Hosted Agent で Azure CLI が自動的に 2.77 に上がった環境で、これまで問題なく動いていた az batch application package create が突然失敗し、パイプライン全体が停止するケースが相次ぎました。本記事では、この現象の正体(Azure CLI 2.77 固有のリグレッション)と、いますぐ取れる回避策・恒久対処・将来同じトラブルを避ける設計のポイントを、具体的な YAML 例やコマンド付きで詳しく解説します。

目次

Azure CLI 2.77 で何が起きたのか

Azure Batch にアプリケーション パッケージを登録するために、多くの現場では次のようなコマンドをパイプラインで自動実行しています。

az batch application package create \
  --application-name <appName> \
  --name <batchAccountName> \
  --package-file /path/to/app.zip \
  --resource-group <resourceGroup> \
  --version-name <version>

ところが Azure CLI が 2.77.0 になると、これまで正常に動作していた同じコマンドが、以下のいずれかのパターンで失敗・異常動作するようになりました。Azure CLI の GitHub Issue(#32086)や Microsoft Q&A でも同様の事象が報告されています。

  • 既存バージョンに上書きしようとすると失敗し、ERROR: The specified blob already exists が発生する
  • 新しい --version-name を指定しても、アップロードされた BLOB の中身が ZIP の実体ではなく、ZIP ファイルのパス文字列になってしまう

特に 2 つ目の「ZIP の中身がファイル パス文字列になる」症状は致命的で、ジョブ実行時にアプリケーションが展開できず、Batch プール全体がエラーになってしまいます。Microsoft Q&A の報告でも、Hosted Agent で 2.77 になった直後から同じ現象が再現していることが確認できます。

発生条件と典型的なエラー メッセージ

報告事例と再現テストを整理すると、以下の条件がそろったときに問題が顕在化します。

  • Azure CLI のバージョンが 2.77.0
  • az batch application package create コマンドを使用
  • Azure Batch アカウントの Auto Storage を利用(一般的な構成)
  • Azure DevOps / GitHub Actions などの Hosted Agent、もしくは手元の環境で 2.77.0 を利用

典型的なエラー メッセージは次のとおりです。

ERROR: The specified blob already exists.
RequestId:xxxxxxx
Time:2025-09-09T08:06:02.3395538Z
ErrorCode:BlobAlreadyExists

このエラーを避けるため、--version-name にユニークな値を付けて BLOB の重複を避けると、こんどはアップロードされた BLOB の中身が

D:\a\1\drop\MojitoUpload.zip

のようなファイル パスの文字列だけになってしまう、という二重の不具合が確認されています。

発生パターンの整理

CLI バージョン操作内容結果
2.76.x既存の --version-name に再アップロードBLOB 上書きに成功(従来挙動)
2.77.0既存の --version-name に再アップロードBlobAlreadyExists エラーで失敗
2.77.0新しい --version-name を指定BLOB の中身が ZIP 実体ではなく ZIP ファイルのパス文字列だけになる
2.78.0 以降新規/上書きアップロードどちらも正常にアップロードされる

原因: Azure CLI 2.77 のリグレッション

この現象は、Azure CLI 2.77.0 における リグレッション(後退バグ) として、Azure CLI チームに報告されています。

  • 2.76 以前: 既存バージョンがあっても BLOB の上書きが行える動作
  • 2.77.0: 内部のアップロード処理が変更され、既存 BLOB の扱いとアップロード データの渡し方に問題が入り込んだ
  • 結果として
    • 既存 BLOB に対しては BlobAlreadyExists が返る
    • 新しい BLOB であっても、アップロードされる内容がファイル パス文字列になってしまう

つまり、ユーザー側のスクリプトや ZIP の作り方が悪いわけではなく、Azure CLI 2.77 自体の不具合です。そのため、いくら YAML や PowerShell を見直しても根本的な解決にはつながりません。

恒久対処: Azure CLI 2.78 以降にアップグレード

Azure CLI 2.78.0 のリリース ノートには、Batch セクションで

  • Fix #32086, #32090: az batch application package create: Fix blob not being uploaded

と明記されており、この問題が 2.78.0 で修正されたことが公式にアナウンスされています。

2.78.0 は 2025 年 10 月 14 日付けでリリースされており、このバージョン以降であれば az batch application package create によるアップロードは再び正常に動作します。

ローカル環境でのアップグレード例

ローカル PC に Azure CLI をインストールしている場合は、通常のアップデート手順で 2.78 以上に更新すれば問題は解消します。

  • Windows(MSI インストーラー版): 公式インストーラーで上書きインストール
  • Windows / Linux(pip で入れている場合): pip install --upgrade "azure-cli>=2.78.0" az --version # バージョン確認
  • コンテナーを利用している場合: docker pull mcr.microsoft.com/azure-cli:2.78.0

Azure DevOps Hosted Agent でのアップグレード戦略

Hosted Agent では、イメージにあらかじめインストールされている Azure CLI のバージョンは自動更新されるため、「気付いたら 2.77 になっていた」という状況が起こり得ます。ここで重要なのは、パイプラインの中で明示的に CLI バージョンを固定することです。

一例として、ジョブの冒頭で 2.78 以上をインストールし直す方法があります。

steps:
- task: UsePythonVersion@0
  inputs:
    versionSpec: '3.10'

- script: |
    pip install --quiet "azure-cli>=2.78.0"
    az --version
  displayName: 'Ensure Azure CLI >= 2.78'

- script: |
    az batch application package create \
      --application-name $(appName) \
      --name $(batchName) \
      --package-file $(Pipeline.Workspace)/drop/$(projectName).zip \
      --resource-group $(resourceGroup) \
      --version-name $(Build.BuildNumber)
  displayName: 'Upload Batch Application Package'

このようにジョブ内で Azure CLI を「上書きインストール」することで、Hosted Agent 側の事前インストール バージョンに依存しない、安全なパイプラインを構築できます。

今すぐ運用を復旧するための一時回避策

すぐに CLI 2.78 以上が使えない場合、以下のような一時回避策が考えられます。それぞれのメリット・デメリットを理解したうえで選択してください。

回避策概要ポイント
① CLI を 2.76 にダウングレードパイプライン内で 2.76 を明示的にインストールし、問題のないバージョンに固定する最もシンプルで再現性が高い。CLI 2.77 を事実上スキップする運用
② REST API / SDK でアップロードAzure Batch 管理 REST API や SDK を使ってアプリケーション パッケージを登録するCLI のバグに依存しない。本番向けの堅牢なアプローチ
③ バージョン名を毎回ユニークにする--version-name にビルド番号や日時を含めて Blob 重複を避ける2.77 では「パス文字列がアップロードされる」問題が残るため、2.77 そのものの回避にはならない
④ CLI バージョン & ZIP 内容チェックパイプライン内で CLI バージョンと ZIP の中身を検証し、異常時に早期に失敗させる将来同種のリグレッションが起きたときにも検知しやすくなる

回避策①: Azure CLI を 2.76 にダウングレード

もっとも現実的で導入しやすいのが「問題のない 2.76 に戻す」方法です。Hosted Agent でも、パイプライン内で pip を使って CLI を上書きインストールできます。

steps:
- task: UsePythonVersion@0
  inputs:
    versionSpec: '3.10'

- script: |
    pip install --quiet "azure-cli==2.76.*"
    az --version
  displayName: 'Install Azure CLI 2.76'

- script: |
    az batch application package create \
      --application-name $(appName) \
      --name $(batchName) \
      --package-file $(Pipeline.Workspace)/drop/$(projectName).zip \
      --resource-group $(resourceGroup) \
      --version-name $(Build.BuildNumber)
  displayName: 'Upload Batch Application Package'

ポイントは次の通りです。

  • 毎ジョブ実行時に 2.76 をインストールすることで、Agent イメージ側のバージョン変更に影響されなくなる
  • ビルド時間がわずかに延びるものの、Batch ジョブ全体の安定稼働と比べれば小さいコスト
  • CLI 2.78 以降が十分に展開されたタイミングで、このダウングレード処理を削除すればよい

回避策②: REST API / SDK でアプリケーション パッケージを登録

Azure CLI を使わず、Azure Batch 管理 REST API や SDK で直接パッケージを登録する方法もあります。REST API の Application Package – Create / Activate エンドポイントや、Python SDK の BatchManagementClient.application_package などを利用できます。

フローは概ね次の通りです。

  1. 管理プレーン API で「アプリケーション パッケージ レコード」を作成する
    • このとき、アップロード先を示す storageUrl(SAS 付き URL)が返される
  2. 返された storageUrl に対して、通常の BLOB アップロード(PUT)で ZIP ファイルを送信する
  3. アップロード完了後、パッケージを Activate する API を呼び出して有効化する

Python で行う簡易例(概略)は次のようになります。

from azure.identity import DefaultAzureCredential
from azure.mgmt.batch import BatchManagementClient
from azure.storage.blob import BlobClient
import requests

subscription_id = "<your-subscription-id>"
resource_group  = "<rg-name>"
account_name    = "<batch-account-name>"
app_name        = "<application-name>"
version_name    = "<version>"
zip_path        = "app.zip"

cred = DefaultAzureCredential()
client = BatchManagementClient(cred, subscription_id)

# 1. パッケージ レコードを作成
pkg = client.application_package.create(
    resource_group_name=resource_group,
    account_name=account_name,
    application_name=app_name,
    version_name=version_name,
)

storage_url = pkg.storage_url  # SAS URL

# 2. storageUrl に ZIP をアップロード
with open(zip_path, "rb") as f:
    requests.put(storage_url, data=f)

# 3. パッケージを Activate
client.application_package.activate(
    resource_group_name=resource_group,
    account_name=account_name,
    application_name=app_name,
    version_name=version_name,
    parameters={"format": "zip"},
)

この方法であれば Azure CLI のバグに依存しないため、将来的に CLI の実装が変わっても影響を受けにくく、本番環境向けとしても有力な選択肢になります。

回避策③: バージョン名を毎回ユニークにする(注意点あり)

BlobAlreadyExists エラー自体は、「同じ Blob 名に再アップロードしようとした」ことが原因です。そのため、--version-name を毎回ユニークにすれば、少なくともこのエラーは回避できます。

  • --version-name $(Build.BuildNumber)
  • --version-name $(Date:yyyyMMdd-HHmmss)
  • --version-name $(Build.SourceBranchName)-$(Build.BuildId)

しかし、Azure CLI 2.77 の場合は、「新しいバージョンを作っても BLOB の中身がパス文字列になってしまう」バグが残っているため、2.77 を使い続ける限り、ユニークなバージョン名だけでは根本解決になりません。

したがって、この回避策は「2.76 や 2.78 以降で運用しているが、うっかり同じバージョン名を再利用してしまう」ケースを避けるためのベスト プラクティスとして捉えるのがよいでしょう。

回避策④: パイプラインで CLI バージョンと ZIP 内容を検証

将来また似たようなリグレッションが発生した場合に備え、「CLI バージョン」と「アップロード対象の ZIP の正当性」をパイプラインで常に検証しておくと安心です。

例えば Azure DevOps の Linux Hosted Agent であれば、次のような追加ステップを入れることができます。

- script: |
    echo "Azure CLI version:"
    az --version | head -n 5

    echo "Check package file:"
    ls -l "$(Pipeline.Workspace)/drop/$(projectName).zip"
    unzip -t "$(Pipeline.Workspace)/drop/$(projectName).zip"
  displayName: 'Sanity check CLI & ZIP'

これにより、

  • CLI が意図しないバージョン(例: 2.77)のままになっていないか
  • ZIP が 0 バイトや明らかに小さすぎるサイズではないか
  • 解凍テストが通るか

といったチェックを自動化でき、異常があれば az batch application package create を実行する前にパイプラインを失敗させることができます。

Azure DevOps / GitHub Actions でのバージョン固定パターン

Hosted Agent 環境では、OS やイメージ タグごとに Azure CLI の更新タイミングが異なります。そこで、プラットフォームごとに「CLI バージョンをどう固定するか」を整理しておきます。

環境バージョン固定の例ポイント
Azure DevOps (Ubuntu)pip install "azure-cli==2.76.*" または pip install "azure-cli>=2.78.0"UsePythonVersion タスクで Python を用意してから実行
Azure DevOps (Windows)Powershell スクリプトで pip install azure-cli を実行pip 用 Python は UsePythonVersion などで事前にインストール
GitHub Actionsactions/setup-python で Python を入れた後、pip install azure-cliruns-on: ubuntu-latest など Hosted Runner でも同様に制御可能
コンテナー ベースmcr.microsoft.com/azure-cli:2.76.0 や :2.78.0 を明示Docker イメージ自体にバージョンを固定するため最も再現性が高い

Batch アプリケーション パッケージ運用のベスト プラクティス

今回のようなリグレッションへの対応に加えて、Azure Batch のアプリケーション パッケージを安定運用するうえで、以下のような設計をしておくと安心です。

バージョン命名規則を決めておく

  • appname-YYYYMMDD-HHmmss
  • appname-$(Build.BuildNumber)
  • appname-$(Build.SourceBranchName)-$(Build.BuildId)

など、ビルド番号や日時を含めたルールを決めておくことで、意図しない上書きや混乱を防げます。CLI 2.77 のような特殊なバグがなければ、これだけでも相当な安定性向上につながります。

アプリケーションごとに「安定版」バージョンを決める

ジョブから参照するバージョンを

  • 常に最新(例: CI ビルドごとに更新)
  • リリースごとに固定(例: 1.0.0, 1.1.0)

のどちらに寄せるかを設計し、「どのタイミングで既存バージョンを上書きするか」を決めておくと、今回のような「上書きできなくなって慌てる」状況を減らせます。

管理プレーンとデータプレーンを分離して考える

Azure Batch のアプリケーション パッケージは、「管理プレーン API(パッケージ レコード作成/有効化)」と「ストレージへの BLOB アップロード(データプレーン)」の組み合わせで成り立っています。

  • Azure CLI はこの 2 つをまとめてラップしている
  • REST API / SDK を利用すると、両者を明示的に制御できる

という構造を意識しておくと、CLI に問題が出たときも「最悪 REST / SDK に逃げる」という選択肢をすぐに取れるようになります。

トラブル発生時のチェックリスト

もし今まさに az batch application package create でエラーが出ている場合は、以下のチェックリストに沿って原因を切り分けてみてください。

  1. CLI バージョンの確認
    • az --version を実行し、2.77.0 でないか確認する
    • 2.77.0 であれば、本記事の説明してきたリグレッションに該当する可能性が高い
  2. パッケージ ZIP の確認
    • ビルド成果物のパスが正しいか(スペース・日本語パスなど)
    • サイズが期待通りか / 解凍テストが通るか
  3. Batch アカウントとアプリケーション設定
    • 対象のアプリケーション名・バージョンが正しく指定されているか
    • Auto Storage アカウントが有効か
  4. CLI バージョン固定の有無
    • パイプライン内で明示的に CLI をインストールしているか
    • Hosted Agent のイメージ更新に左右されていないか

まとめ

  • Azure CLI 2.77.0 には、az batch application package create コマンドに関するリグレッションが存在し、BlobAlreadyExists エラーや ZIP の中身がパス文字列になる問題が発生します。
  • Azure CLI 2.78.0 以降でこのバグは公式に修正されているため、可能であれば 2.78 以上へのアップグレードが最も確実な恒久対策です。
  • 今すぐの復旧には、CLI を 2.76 にダウングレードする、あるいは REST API / SDK でアプリケーション パッケージを登録するといった回避策が有効です。
  • Hosted Agent 環境では、パイプライン内で Azure CLI のバージョンを明示的にインストールし、イメージ更新に影響されない構成にしておくことが重要です。
  • バージョン命名規則の整理、管理プレーンとデータプレーンの分離設計、ZIP 内容の検証ステップなどを取り入れることで、今後同様のリグレッションが起きた場合でも影響を最小限にできます。

すでに影響を受けている環境では、まず CLI 2.77.0 が使われていないか を確認し、ダウングレードまたはアップグレードによって安全なバージョンに切り替えたうえで、暫定対処を徐々に外していくのがおすすめです。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次