Azure Developer CLI(azd)の Extension FrameworkはGAとなり、独自コマンド、ライフサイクル処理、デプロイ前の検証、MCPツールなどを、azd本体を改造せずに追加できる正式な拡張基盤になりました。
実務で重要なのは、単に拡張をインストールするだけではありません。拡張側のextension.yamlで機能と対応するazdバージョンを宣言し、利用するプロジェクト側のazure.yamlで必要な拡張とバージョン制約を管理します。さらに、用途に応じてOfficial、Private、Development、Nightlyの配布経路を使い分けます。
この仕組みを使えば、個人のローカルスクリプトとして管理していた処理を、複数プロジェクトで再利用できるチーム共通の開発ワークフローへ発展させられます。なお、GAになったのは拡張フレームワークであり、個々の拡張や機能にはPreviewのものが残る場合があります。(Microsoft for Developers)
azd Extension FrameworkのGAで何が変わったのか
GA版では、拡張インターフェースの安定化に加え、プロジェクト単位の拡張要件、Semantic Versioningによるバージョン制約、複数の配布経路が整備されました。
| 変更点 | 実務上の意味 |
|---|---|
| 拡張インターフェースの安定化 | プレビュー時代のAPI変更リスクを抑え、継続的に保守しやすくなった |
| プロジェクト単位の拡張要件 | リポジトリを取得した開発者やCI環境でも、必要な拡張を特定できる |
| バージョン制約 | 拡張とazdの互換性をSemantic Versioningで管理できる |
| 配布経路の拡大 | 公式公開、社内限定、開発版、Nightly版を用途別に運用できる |
| 統合ポイントの拡大 | Command、Lifecycle Hook、Validation Provider、MCP Toolなどを追加できる |
GAは「将来、一切変更されない」という意味ではありません。破壊的変更はメジャーバージョン、後方互換のある機能追加はマイナーバージョンというように、バージョン管理を前提として運用することが重要です。MicrosoftはGAに向けて拡張インターフェースを安定化し、プロジェクトレベルの拡張要件や配布機能を追加しています。(Microsoft for Developers)
Azure Developer CLI拡張を使うべき場面
azdには、もともとazure.yamlへスクリプト形式のHookを記述する機能があります。そのため、すべての自動処理を拡張として実装する必要はありません。
| 判断項目 | azure.yamlのHook | azd Extension |
|---|---|---|
| 利用範囲 | 原則として1つのリポジトリ | 複数プロジェクトや組織全体 |
| 実装形式 | PowerShell、Shell、Pythonなどのスクリプト | 独立した拡張プログラム |
| バージョン管理 | リポジトリのソース管理に依存 | 拡張単位でSemVer管理 |
| 配布 | 対象リポジトリへ同梱 | RegistryやBundleで配布 |
| 向いている処理 | 単純なファイル生成、通知、初期化 | 共通ポリシー、独自コマンド、Provider、MCP |
| 更新方法 | リポジトリの更新 | azd extension updateなどで更新 |
たとえば、デプロイ後に1本のスクリプトを実行するだけなら、azure.yamlのHookで十分です。一方、すべてのプロジェクトでリソースタグを検査する、独自ホスティング先へデプロイする、AIエージェントから社内開発ツールを呼び出すといった用途は、拡張として切り出した方が管理しやすくなります。(Microsoft Learn)
azd拡張で追加できる主な機能
GA版のExtension Frameworkでは、次のようなCapabilityをextension.yamlへ宣言できます。
| Capability | 追加できる機能 | 活用例 |
|---|---|---|
custom-commands | 独自コマンドやコマンドグループ | azd guardrails check |
lifecycle-events | provisionやdeploy前後の処理 | デプロイ前の設定確認 |
validation-provider | azdの検証パイプラインへのルール追加 | 命名規則、リージョン、タグの検査 |
mcp-server | AIエージェントから呼び出せるMCPツール | 構成確認、ログ調査、推奨設定の生成 |
service-target-provider | 新しいデプロイ先 | 独自PaaSや社内基盤 |
framework-service-provider | 新しい言語やビルド方式 | 未対応フレームワークのビルド |
provisioning-provider | 独自のインフラプロビジョニング | BicepやTerraform以外の仕組み |
metadata | ヘルプやIntelliSense用メタデータ | コマンド説明や設定候補の表示 |
Capabilityは単なる分類ではありません。拡張が利用する権限や統合ポイントを明示する役割があり、必要なCapabilityを宣言していないと、対応するFramework Serviceの呼び出しが権限エラーになる場合があります。(Microsoft Learn)
Commandで独自のazdコマンドを追加する
custom-commandsを宣言すると、azd配下へ独自の名前空間とコマンドを追加できます。
たとえば、guardrailsという名前空間を作成した場合、次のような操作を提供できます。
azd guardrails check
azd guardrails report
azd guardrails fix
コマンドは単に外部プログラムを実行するだけではありません。azdのプロジェクト、環境、出力形式などのコンテキストを受け取り、既存の開発フローと統合できます。
公式SDKのazdext.NewExtensionRootCommandを使うと、--environmentや出力形式など、azd標準のフラグ処理を独自に作り直す必要がありません。(Microsoft Learn)
Lifecycle Hookでazdの処理に割り込む
lifecycle-eventsを宣言すると、azd provision、azd package、azd deployなどの処理前後に独自ロジックを実行できます。
代表的な利用例は次のとおりです。
preprovisionで必須設定やタグを確認するpostprovisionで作成されたリソース情報を外部システムへ登録するprepackageでコード生成や依存関係の検査を行うpostdeployで疎通確認や通知を実行する
拡張側には、イベントを受け取るためのlistenコマンドが必要です。最新のテンプレートやSDKが提供するExtensionHostを利用し、イベントハンドラーを登録します。サービス単位のイベントでは、hostやlanguageを条件にして対象を絞ることもできます。(Microsoft Learn)
Validation Providerでデプロイ前の検査を共通化する
validation-providerは、組織共通のガードレールを実装する場合に特に有効です。
たとえば、次のようなルールを拡張として配布できます。
- 本番環境では許可されたAzureリージョンだけを利用する
- 必須のリソースタグが設定されているか確認する
- リソースグループ名が組織の命名規則に従っているか確認する
- 公開エンドポイントや危険な構成を検出する
- 本番環境へのデプロイ前に必要な環境変数を確認する
現行のFrameworkでは、Providerに依存せずプロビジョニング前に実行するprovisionチェックと、BicepのARMテンプレートやパラメーターを対象にするarm-provisionチェックを使い分けられます。
Terraformや拡張独自のProvisioning Providerにも適用したい検査はprovision、生成されたARMテンプレートの詳細まで調査したい検査はarm-provisionが適しています。(GitHub)
MCP ToolをAIエージェントへ公開する
mcp-serverを宣言すると、拡張の機能をModel Context Protocol経由でAIエージェントへ公開できます。
たとえば、次のようなMCP Toolを実装できます。
- 現在の
azdプロジェクト構成を説明する - Azureリソースに必要なタグを提案する
- デプロイ前の問題点を一覧化する
- ログや構成情報からトラブルの原因候補を返す
- 組織標準に合う
azure.yamlの設定を生成する
extension.yamlでは、Capabilityに加えて、MCPサーバーを起動する引数を指定できます。
capabilities:
- custom-commands
- mcp-server
mcp:
serve:
args:
- mcp
- start
拡張側ではmcp startコマンドを実装し、標準入出力でMCPクライアントと通信します。動作確認は、たとえば次のコマンドで行えます。
azd guardrails mcp start
MCP ToolからAzureを変更できるようにする場合は、参照専用と更新系のToolを分離し、対象サブスクリプション、環境、リソースグループを必ず検証してください。秘密情報をToolの戻り値やログへ含めないことも重要です。(Microsoft Learn)
Extension要件を管理する4つのバージョン指定
azd Extension Frameworkでは、似た名前のバージョン指定が複数あります。混同すると、インストールできない、意図しない最新版へ更新される、別の開発者環境で動かないといった問題が発生します。
| 設定場所 | プロパティ | 管理する対象 |
|---|---|---|
extension.yaml | version | 拡張そのもののバージョン |
extension.yaml | requiredAzdVersion | その拡張を実行できるazdのバージョン |
azure.yaml | requiredVersions.azd | プロジェクトが必要とするazdのバージョン |
azure.yaml | requiredVersions.extensions | プロジェクトが必要とする拡張とバージョン |
extension.yamlのrequiredAzdVersion
拡張が新しいSDKやFramework APIを利用している場合は、そのAPIを搭載したazdより古いバージョンで実行されないようにします。
version: 1.2.0
requiredAzdVersion: ">=1.30.0"
上記の数値は例です。実際には、拡張が使用するAPIを最初に搭載したazdバージョンに合わせます。
azdは拡張のインストールや更新時にrequiredAzdVersionを確認し、実行中のazdと互換性のない拡張バージョンを候補から除外します。互換性のあるバージョンが1つもない場合は、インストールに失敗します。(GitHub)
azure.yamlのrequiredVersions.extensions
利用するプロジェクトでは、必要な拡張をazure.yamlへ記述します。
name: contoso-webapp
requiredVersions:
azd: ">=1.30.0"
extensions:
contoso.azd.guardrails: "^1.2.0"
この指定により、プロジェクトを利用する開発者は「別途この拡張を入れてください」と書かれたREADMEを探さなくても、必要なExtensionを把握できます。
requiredVersions.extensionsでは、次のようなSemVer制約を利用できます。
| 指定 | 意味 |
|---|---|
1.2.3 | 1.2.3だけを利用 |
^1.2.3 | 1.2.3以上、2.0.0未満 |
~1.2.3 | 1.2.3以上、1.3.0未満 |
>=1.0.0,<2.0.0 | 明示した範囲内 |
latest | 利用可能な最上位バージョン |
複数のバージョンが条件を満たす場合、azdは条件内で最も高いバージョンを選択します。CLIのazd extension install --versionは、基本的に完全一致のバージョンかlatestを指定する点にも注意が必要です。プロジェクトファイルでは範囲指定、CIで明示的にインストールする場合は完全一致という使い分けが分かりやすいでしょう。(GitHub)
本番プロジェクトではlatestを避ける
latestは検証環境では便利ですが、本番運用では、同じコミットから異なる拡張バージョンが選ばれる可能性があります。
一般的には、次のように使い分けます。
- ローカル試験では
latest - 通常の開発では
^1.2.0や~1.2.0 - 厳密な再現性が必要なCIでは
1.2.3 - メジャーバージョンをまたがせたくない場合は
>=1.2.0,<2.0.0
Preview版を対象にする場合は、制約にもプレリリース識別子を含める必要があります。通常の>=0.1.0では、0.1.0-previewなどが対象にならない場合があります。(GitHub)
Azure Developer CLI拡張を作成する手順
ここでは、公式クイックスタートと同じくGoで拡張を作成します。
開発用Extensionをインストールする
拡張開発には、azd xコマンドを提供するmicrosoft.azd.extensionsを利用します。
azd version
azd extension install microsoft.azd.extensions
azd extension list --installed
azd x
azd xが実行できれば、拡張の初期化、ビルド、監視、パッケージ化、公開を行えます。(Microsoft Learn)
Gitリポジトリを作成する
azd x initは、拡張用フォルダーがGitで追跡されていることを前提とします。
mkdir azd-guardrails
cd azd-guardrails
git init
git commit --allow-empty -m "Initial commit"
azd x init
対話形式では、次のような情報を入力します。
| 項目 | 入力例 |
|---|---|
| Extension ID | contoso.azd.guardrails |
| Display name | Contoso azd Guardrails |
| Description | Validate Azure project policies before deployment. |
| Namespace | guardrails |
| Capability | Custom commands |
| Language | Go |
azd x initは、ソースコードの生成だけでなく、初期ビルド、パッケージ化、ローカルRegistryへの公開、ローカル環境へのインストールまで実行します。(Microsoft Learn)
生成されるファイルを確認する
代表的な構成は次のとおりです。
contoso.azd.guardrails/
├── bin/
├── build.ps1
├── build.sh
├── CHANGELOG.md
├── extension.yaml
├── main.go
├── go.mod
└── internal/
特に重要なのは次の3つです。
extension.yaml:ID、バージョン、Capability、利用例を定義するmain.go:拡張のエントリーポイントCHANGELOG.md:リリース時の変更内容を管理する
Windows、Linux、macOS向けのビルド処理は、生成されたビルドスクリプトを基準に整備します。(Microsoft Learn)
extension.yamlを設定する
Command、Lifecycle Event、Validation Provider、MCP Serverを持つ拡張の例は次のとおりです。
# yaml-language-server: $schema=https://raw.githubusercontent.com/Azure/azure-dev/refs/heads/main/cli/azd/extensions/extension.schema.json
id: contoso.azd.guardrails
namespace: guardrails
displayName: Contoso azd Guardrails
description: Validates project policies before provisioning and deployment.
usage: azd guardrails <command> [options]
version: 1.0.0
language: go
requiredAzdVersion: ">=1.30.0"
capabilities:
- custom-commands
- lifecycle-events
- validation-provider
- mcp-server
examples:
- name: check
description: Validates the current azd project.
usage: azd guardrails check
tags:
- governance
- validation
- mcp
mcp:
serve:
args:
- mcp
- start
最低限必要なのは、id、version、displayName、descriptionです。通常の拡張はcapabilitiesを宣言し、複数の拡張をまとめるExtension Packは代わりにdependenciesを宣言できます。(Microsoft Learn)
独自コマンドを実装する
internal/cmd/check.goなどにCobraコマンドを追加します。
package cmd
import (
"fmt"
"github.com/spf13/cobra"
)
func newCheckCommand() *cobra.Command {
return &cobra.Command{
Use: "check",
Short: "Validates the current azd project.",
RunE: func(cmd *cobra.Command, args []string) error {
fmt.Println("Project policy check passed.")
return nil
},
}
}
ルートコマンド側で登録します。
rootCmd.AddCommand(newCheckCommand())
再ビルド後、次のように実行できます。
azd guardrails check
最初は文字列を表示するだけのコマンドで動作確認し、その後、azd SDKを使ったプロジェクト情報の取得やAzure APIの呼び出しを追加すると、問題の切り分けがしやすくなります。(Microsoft Learn)
Lifecycle Eventを登録する
Lifecycle Eventでは、ExtensionHostへハンドラーを登録します。
host := azdext.NewExtensionHost(azdClient).
WithProjectEventHandler(
"preprovision",
func(ctx context.Context, args *azdext.ProjectEventArgs) error {
fmt.Printf("Validating project: %s\n", args.Project.Name)
// 必須タグや環境設定の検査を実装する
return nil
},
)
Lifecycle Eventを受け取る拡張では、最新のSDKが提供するNewListenCommandやNewExtensionHostを利用してください。古いプレビュー版サンプルで使われていたazdext.NewContext()は非推奨となっており、新規実装ではazdext.Runなどの新しいヘルパーが推奨されています。(GitHub)
Validation Providerを登録する
Providerに依存しないプロビジョニング前検査は、次のような形で登録します。
host := azdext.NewExtensionHost(azdClient).
WithValidationCheck(azdext.ValidationCheckRegistration{
CheckType: azdext.ValidationCheckTypeProvision,
RuleID: "required_tags",
Factory: func() azdext.ValidationCheckProvider {
return &RequiredTagsCheck{}
},
})
Rule IDは、ログやエラー内容から原因を追跡できる安定した名前にします。表示メッセージだけでなく、「どの項目が不足しているか」「どのファイルや設定を修正すべきか」まで返すと、CIでも利用しやすくなります。(GitHub)
ビルドとローカルテストを行う
開発中はazd x watchを使用すると、ソース変更後のビルドとローカルインストールを自動化できます。
azd x watch
別のターミナルでコマンドを実行します。
azd guardrails check
手動で実行する場合は、次のコマンドを利用します。
azd x build
azd x pack
azd x publish
すべての対象プラットフォーム向けにビルドするときは、次のようにします。
azd x build --all
azd x pack --rebuild
azd x watchは開発用、build --allとpack --rebuildはリリース前の確認用と分けると、日常的な開発速度を落とさずに済みます。(Microsoft Learn)
azd Extensionの配布方法を選ぶ
GA版では、用途に応じた複数の配布方法を選択できます。
| 配布方法 | 適した用途 | 主な注意点 |
|---|---|---|
| Official Registry | 安定した一般公開Extension | 審査、品質基準、リリース管理が必要 |
| Private Registry | 社内ツールや限定配布 | Registryとアクセス制御を自分で管理する |
| Development Registry | Preview版や公開前検証 | 未署名、サポート対象外、削除や破壊的変更の可能性 |
| Nightly Registry | 最新ビルドの継続検証 | 本番利用には向かない |
| Bundle | 一時的な評価、閉域、単発配布 | 自動更新されず、配布元の信頼確認が必要 |
Official Registryはazdにあらかじめ登録されています。Private配布ではURLまたはファイルベースのRegistryを追加できます。DevelopmentとNightlyは明示的なオプトイン方式です。また、Registryを用意せずに単一のZIPファイルとして渡すBundleも利用できます。(Microsoft for Developers)
Private Registryで社内配布する
社内向けExtensionでは、独自のregistry.jsonをWebサーバーや社内の配布基盤へ配置します。
利用者側では、RegistryをSourceとして追加します。
azd extension source add \
-n contoso \
-t url \
-l "https://example.com/azd/registry.json"
登録後、Sourceを明示してインストールします。
azd extension install contoso.azd.guardrails --source contoso
登録内容を確認するには、次のコマンドを使用します。
azd extension source list
azd extension show contoso.azd.guardrails --source contoso
Private Registryは、機密性の高い社内ロジックや、正式公開する予定のない組織固有のExtensionに適しています。Registryへアクセスする仕組み、配布物の署名、承認済みバージョンの管理は、組織側で設計する必要があります。(Microsoft Learn)
Development Registryを利用する
Development Registryは、Preview版、実験的なExtension、Official Registryへ昇格する前の検証に使います。
azd extension source add \
-n dev \
-t url \
-l "https://aka.ms/azd/extensions/registry/dev"
インストール時はSourceを明示します。
azd extension install my.experimental.extension --source dev
Development RegistryのExtensionは未署名で、Azureサポートの対象外です。予告なく変更や削除が行われる可能性もあるため、本番環境の必須ワークフローへ直接組み込むのは避けます。(GitHub)
Nightly Registryを利用する
Nightly Registryは、最新コードから自動生成されたビルドを継続的に確認する用途に向いています。
azd extension source add \
-n nightly \
-t url \
-l "https://raw.githubusercontent.com/Azure/azure-dev/nightly/cli/azd/extensions/registry.nightly.json"
Nightly版は、次期リリースによる互換性問題の早期発見や、自動テストでのスモークテストに使用します。開発者の通常環境へ常用させるより、専用の検証環境を分けた方が安全です。(GitHub)
Bundleで単発配布する
一時的な評価や、Registryを構築できない環境では、自己完結型Bundleを作成できます。
azd x pack --bundle
生成されたZIPファイルを受け取った利用者は、ファイルを直接インストールできます。
azd extension install ./contoso.azd.guardrails_1.0.0.zip
Bundleにはregistry.jsonと対象プラットフォーム向けArtifactが含まれます。ただし、インストール後に永続的なRegistry Sourceは残らず、azd extension updateによる自動更新も行われません。更新時は新しいBundleを再インストールします。
Bundle内のチェックサムは破損検出には役立ちますが、発行者本人であることまでは保証しません。信頼できる経路で受け取ったBundleだけをインストールしてください。(GitHub)
ExtensionをリリースしてRegistryへ公開する
GitHub ReleaseとRegistryを利用する場合、基本的な流れは次のとおりです。
azd x pack --rebuild
azd x release --repo contoso/azd-guardrails
azd x publish \
--repo contoso/azd-guardrails \
--registry ./registry.json
各コマンドの役割は次のように分かれています。
| コマンド | 処理内容 |
|---|---|
azd x build | Extensionの実行ファイルをビルドする |
azd x pack | 配布用Artifactを作成する |
azd x release | GitHub ReleaseへArtifactを登録する |
azd x publish | RegistryへバージョンとArtifact情報を追加する |
リリース前には、extension.yamlのversionとCHANGELOG.mdを更新します。GitHubへReleaseを作成する場合は、GitHub CLIまたは適切な権限を持つTokenによる認証も必要です。
Official Registryへの掲載は、単にRegistryファイルをアップロードする操作ではありません。スキーマ、メタデータ、対象プラットフォーム、チェックサム、品質基準を満たしたうえで、所定の提出・レビュー手続きを通す必要があります。(GitHub)
CI/CDではExtensionを明示的にセットアップする
azure.yamlへrequiredVersions.extensionsを書けば、ローカルの対話環境では不足しているExtensionのインストールを案内できます。
一方、CI/CDとして検出された環境では、自動インストールが無効になる場合があります。そのため、パイプラインのセットアップ処理でSource追加とExtensionインストールを明示する方が確実です。
azd extension source add \
-n contoso \
-t url \
-l "https://example.com/azd/registry.json"
azd extension install \
contoso.azd.guardrails \
--version 1.2.3 \
--source contoso
azd up --no-prompt
CIでは次の方針がおすすめです。
--versionで完全一致のバージョンを指定する--sourceを常に明示する- Source追加をデプロイ前のBootstrap処理へ含める
- Extensionのバージョンとチェックサムをログへ出力する
- 更新は通常のデプロイと分離し、Pull Requestで確認する
複数のSourceに同じExtension IDが存在すると、対話環境では選択を求められ、非対話環境ではエラーになります。CIではSource名の明示が特に重要です。(GitHub)
失敗しやすいポイントと対処方法
| 症状 | 主な原因 | 対処 |
|---|---|---|
| Extensionが見つからない | Source未登録、IDの間違い | azd extension source listとazd extension showを確認 |
| 複数Sourceで見つかった | 同じIDが複数Registryに存在 | --sourceを指定 |
| 条件を満たすバージョンがない | azure.yamlの制約が厳しすぎる | 公開済みバージョンを確認して制約を見直す |
azdと互換性がない | requiredAzdVersionを満たしていない | azdを更新するか対応Extensionを使用 |
| 更新した版が表示されない | Registryキャッシュが残っている | キャッシュTTLを一時的に0にする |
| CIで自動インストールされない | CIでは自動導入が抑止される | パイプライン内で明示的にインストール |
| Development版で警告が出る | 未署名の実験版を使用している | 検証環境だけで利用する |
基本的な診断は、次の順番で行います。
azd extension source list
azd extension show contoso.azd.guardrails
azd extension list --installed
azd extension install \
contoso.azd.guardrails \
--source contoso
Registryの更新が反映されない場合、PowerShellでは次のようにキャッシュを無効化して確認できます。
$env:AZD_EXTENSION_CACHE_TTL = "0s"
azd extension show contoso.azd.guardrails
Bash系の環境では次のように実行します。
AZD_EXTENSION_CACHE_TTL=0s \
azd extension show contoso.azd.guardrails
バージョン制約を外して無理にインストールするより、azd extension showで公開バージョンとrequiredAzdVersionを確認し、互換性のある組み合わせへ修正する方が安全です。(GitHub)
実務ではPrivate Registryから段階的に公開する
新しいExtensionを最初からOfficial Registryへ出す必要はありません。次の順序で利用範囲を広げると、問題を早い段階で発見できます。
azd x watchで開発者本人がローカル検証する- Bundleで少人数へ渡して操作性を確認する
- Private Registryでチーム内の複数プロジェクトへ展開する
azure.yamlへExtension要件とバージョン制約を追加する- 公開前の機能はDevelopment Registryで検証する
- 安定後にOfficial Registryへの提出を検討する
- Nightly版は専用環境の継続テストだけに使用する
最初のExtensionでは、大規模な独自Provisioning Providerを作るより、「1つのCommand」または「1つのValidation Rule」から始めるのが現実的です。
たとえば、azd guardrails checkで必須タグと利用リージョンだけを検査し、安定した段階でpreprovisionへの自動統合やMCP Toolを追加します。機能追加はマイナーバージョン、互換性を壊す変更はメジャーバージョンとして管理すれば、利用プロジェクト側も安全に更新できます。
Azure Developer CLI拡張を実務へ導入する際は、まずGoテンプレートで最小構成を作成し、extension.yamlへCapabilityとrequiredAzdVersionを定義します。次に、利用プロジェクトのazure.yamlへrequiredVersions.extensionsを追加し、Private RegistryまたはBundleでチーム内検証を始めてください。拡張の実装だけでなく、バージョン制約、配布元、更新方法までセットで設計することが、GA版Extension Frameworkを安定運用するためのポイントです。

コメント