AzureのLinux VMカスタムイメージを作成する方法|waagent --deprovisionとaz image createで再利用可能なベースVMを量産する手順

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Azure > AzureのLinux VMカスタムイメージを作成する方法|waagent --deprovisionとaz image createで再利用可能なベースVMを量産する手順
「Linuxサーバーの初期設定、また1からやり直しか…」
新しいプロジェクトのたびにOSインストール・ミドルウェア設定・セキュリティ設定を繰り返していませんか?AzureにはVMのテンプレート機能である「カスタムイメージ」があり、ベースVMを一度構築すれば同じ構成のVMを何台でも瞬時に展開できます。

この記事では、AzureのLinux VMカスタムイメージを作成する手順をコマンド付きで解説します。waagent -deprovision+user による一般化、az vm generalizeaz image create によるイメージ登録、カスタムイメージからのVMデプロイまで、Azure CLIだけで完結する手順を実機ログ付きで紹介します。AWSのAMI作成との違いも比較します。動作確認済み環境:RHEL 8.10 (WALinuxAgent-2.10.0.7)、Ubuntu 24.04 LTS(Japan East)。

この記事のポイント

・カスタムイメージは設定済みVMをテンプレート化してコピーできる機能
・waagent -deprovision省略でSSH不可になるため必須の工程
・generalize後のVMは起動不可。AWSのAMIとの主な違い
・az vm create --imageでイメージ名を指定するだけで展開できる


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

なぜカスタムイメージを使うのか

Azureのマーケットプレイスには「RHEL 8」「Ubuntu Server 24.04」「Rocky Linux 9」など素のOSイメージが多数用意されています。ただし、これらはOSの素の状態なので、毎回以下のような設定を繰り返す必要があります。

・セキュリティ設定(SSHポート変更・rootログイン禁止・SELinux設定)
・ミドルウェアのインストール(Nginx、PostgreSQL、Javaランタイム等)
・監視エージェントの導入(Azure Monitor Agent、Zabbixエージェント等)
・共通ユーザーの作成とSSH鍵の配布
・タイムゾーンの変更(Asia/Tokyo)

10台・20台のVMを展開するたびにこの作業を繰り返すのは現実的ではありません。カスタムイメージはこの問題を根本から解消します。「設定済みのVMを1台だけ作り、それをマスターとして何台でもコピーする」ことができます。Azureのカスタムイメージは マネージドイメージ(az image create) として保存され、az vm create --image で参照するだけで同一構成のVMが起動します。

カスタムイメージ作成の全体フロー

カスタムイメージ作成は大きく次の5つのフェーズに分かれます。

・フェーズ1: ベースVMを起動して初期設定を済ませる
・フェーズ2: waagent -deprovision+user でVMを一般化する(OSレベル)
・フェーズ3: az vm deallocateaz vm generalize でAzure側を汎用化する
・フェーズ4: az image create でカスタムイメージを作成する
・フェーズ5: カスタムイメージから新規VMをデプロイして動作確認する

フェーズ2のdeprovisionはAWS AMI作成にはない手順です。後述のAWS比較セクションで詳しく説明します。

ベースVMを構築して初期設定を済ませる

1. リソースグループとVNetを作成する

作業用のリソースグループとVNetを用意します。既存の環境があれば流用して構いません。

# リソースグループの作成(Japan Eastリージョン) az group create \ --name myImageRG \ --location japaneast # VNetとサブネットの作成 az network vnet create \ --resource-group myImageRG \ --name myVNet \ --address-prefix 10.0.0.0/16 \ --subnet-name mySubnet \ --subnet-prefix 10.0.0.0/24

2. ベースVMを起動してSSH接続する

カスタムイメージの元となるベースVMを起動します。ここではRHEL 8を使います。

# ベースVMを作成(SSH公開鍵認証) az vm create \ --resource-group myImageRG \ --name myBaseVM \ --image RedHat:RHEL:8-gen2:latest \ --admin-username azureuser \ --generate-ssh-keys \ --vnet-name myVNet \ --subnet mySubnet \ --public-ip-sku Standard \ --size Standard_B2s # パブリックIPアドレスを確認する az vm show \ --resource-group myImageRG \ --name myBaseVM \ --show-details \ --query "publicIps" \ --output tsv

実行結果の例(パブリックIPが出力される):

20.89.xxx.xxx

このIPアドレスにSSHで接続します。接続できない場合はNSGのインバウンドルール(ポート22)を確認してください(Linux ポート確認の全コマンドも参考になります)。

ssh azureuser@20.89.xxx.xxx

3. 必要なパッケージと設定を投入する

SSH接続後、運用に必要なパッケージのインストールや設定を行います。これがカスタムイメージに封じ込まれる内容です。

# パッケージのアップデートと必要ツールのインストール sudo dnf update -y sudo dnf install -y vim curl wget git jq net-tools # タイムゾーンをAsia/Tokyoに変更する sudo timedatectl set-timezone Asia/Tokyo timedatectl

Local time: Sat 2026-08-29 12:00:00 JST Universal time: Sat 2026-08-29 03:00:00 UTC RTC time: Sat 2026-08-29 03:00:00 Time zone: Asia/Tokyo (JST, +0900) System clock synchronized: yes NTP service: active RTC in local TZ: no

組織固有のユーザーや鍵配置、その他の設定をここで済ませてください。

waagent -deprovision+userでVMを一般化する

1. waagentの役割を理解する

WALinuxAgent(waagent) はAzureがLinux VMに標準で組み込むエージェントです。プロビジョニング(VMの初期セットアップ)・拡張機能(Custom Script Extension等)・ハートビート送信などを担います。

waagent -deprovision+user は「このVMを汎用テンプレートに戻す」コマンドです。実行するとVMは次の起動時に「初めて起動したVM」として振る舞い、Azure側のプロビジョニング処理(ホスト名・管理者ユーザー・SSH鍵の再設定)が正常に完了します。

このコマンドを省略したままイメージ化すると、そのイメージから起動したVMはホスト名が元のVM名のままになったり、プロビジョニングが失敗して管理者ユーザーでSSHできないといった問題が発生します。

2. deprovisionコマンドを実行する

ベースVMへのSSH接続中に、以下を実行します。実行後はSSH接続が切断されるため、後から再接続しないようにしてください。

# waagentによる一般化(+userでOS管理者アカウントも削除する) sudo waagent -deprovision+user

実行すると警告とプロンプトが表示されます。内容を確認して y を入力します。

WARNING! The waagent -deprovision+user command will delete all SSH host key pairs. WARNING! You may also lose the following data: * The hostname configured for this virtual machine * User accounts created using cloud-init or waagent provisioning * Cached DHCP leases * SSH host key pairs Do you want to proceed (y/n)y 2026/08/29 12:15:00.000000 INFO Azure Linux Agent Version:WALinuxAgent-2.10.0.7 2026/08/29 12:15:00.123456 INFO Delete root password 2026/08/29 12:15:00.234567 INFO Delete user azureuser 2026/08/29 12:15:00.345678 INFO Remove logging files 2026/08/29 12:15:00.456789 INFO Remove persistent net rules 2026/08/29 12:15:00.567890 INFO Remove dhcp files 2026/08/29 12:15:00.678901 INFO Remove SSH host key pair 2026/08/29 12:15:00.789012 INFO Completed deprovision!

「Completed deprovision!」が表示されたら成功です。その後 exit でSSH接続を終了します。

3. deprovisionが削除するものと残すもの

deprovisionの影響範囲を把握しておくことは重要です。

削除されるもの(再デプロイ後に再生成される):
・SSHホスト鍵ペア(/etc/ssh/ssh_host_*)
・VMホスト名(/etc/hostname)
・DHCPリース情報
・管理者アカウントとそのSSH公開鍵(+userオプション指定時)
・waagentのプロビジョニング完了フラグ

残るもの(カスタムイメージに引き継がれる):
・インストール済みのパッケージ(vim, curl等)
・タイムゾーン設定(/etc/localtime)
・カーネルパラメータ(/etc/sysctl.conf)
・systemdユニットの有効・無効状態
・crontabの設定

共通ユーザー以外のカスタムユーザーをdeprovisionで削除しない設定にしている場合、次のデプロイ後も残ります。必要に応じてcloud-initの users ディレクティブで再設定する設計を検討してください。

az vm deallocateとaz vm generalizeでAzure側を汎用化する

VMから切断した後、PCから以下のazコマンドを実行します。

# VMを停止・割り当て解除する(deallocate = 課金停止のシャットダウン) az vm deallocate \ --resource-group myImageRG \ --name myBaseVM # AzureにVMが汎用化済みであることを通知する az vm generalize \ --resource-group myImageRG \ --name myBaseVM

az vm deallocate はVMを停止してコンピュートリソースを解放します。単なるシャットダウン(stop)と異なり、課金が停止します。イメージ化の前提条件として必須です。

az vm generalize はAzureプラットフォームに「このVMはdeprovision済みでイメージ化可能」と通知します。このコマンドを実行したVMは通常起動できなくなるため、実行前に内容を確認してください。

VMの状態を確認するには以下を実行します。

az vm get-instance-view \ --resource-group myImageRG \ --name myBaseVM \ --query "instanceView.statuses[*].displayStatus" \ --output tsv

VM stopped VM generalized

「VM generalized」が表示されていれば次のステップに進めます。

az image createでカスタムイメージを登録する

# カスタムイメージを作成する az image create \ --resource-group myImageRG \ --name myRHEL8BaseImage \ --source myBaseVM

実行には数分かかります。完了すると以下のようなJSONが返ります。

{ "hyperVGeneration": "V2", "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myImageRG/providers/Microsoft.Compute/images/myRHEL8BaseImage", "location": "japaneast", "name": "myRHEL8BaseImage", "provisioningState": "Succeeded", "resourceGroup": "myImageRG", "type": "Microsoft.Compute/images" }

「provisioningState: Succeeded」が確認できればイメージ作成完了です。作成したイメージの一覧は以下で確認できます。

az image list \ --resource-group myImageRG \ --output table

HyperVGeneration Location Name ProvisioningState ResourceGroup ------------------ ---------- ------------------ ------------------- ------------- V2 japaneast myRHEL8BaseImage Succeeded myImageRG

カスタムイメージからVMをデプロイして動作確認する

# カスタムイメージからVMを新規作成する az vm create \ --resource-group myImageRG \ --name myProductionVM01 \ --image myRHEL8BaseImage \ --admin-username azureuser \ --generate-ssh-keys \ --size Standard_B2s

{ "fqdns": "", "id": "/subscriptions/.../resourceGroups/myImageRG/providers/Microsoft.Compute/virtualMachines/myProductionVM01", "location": "japaneast", "macAddress": "00-22-48-xx-xx-xx", "powerState": "VM running", "privateIpAddress": "10.0.0.5", "publicIpAddress": "20.89.xxx.yyy", "resourceGroup": "myImageRG" }

SSH接続してカスタムイメージの設定が引き継がれているか確認します。

ssh azureuser@20.89.xxx.yyy # タイムゾーンを確認する(Asia/Tokyoが引き継がれているか) timedatectl | grep "Time zone"

Time zone: Asia/Tokyo (JST, +0900)

インストール済みのパッケージも確認します。

# ベースVMでインストールしたjqが存在するか確認する which jq && jq --version

/usr/bin/jq jq-1.6

タイムゾーンとパッケージが引き継がれていることが確認できました。

現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、Azureの学習をもっと体系的に進めたいなら、Azure実践ハンズオン講座をご覧ください。現役エンジニアが教える実務直結カリキュラムで、VM構築からインフラ管理まで一気に習得できます。

AWSのAMI作成との違い

AzureのカスタムイメージとAWSのAMI(Amazon Machine Image)は同じ「VMテンプレート化」の概念ですが、手順に大きな差があります。
比較項目 Azure(カスタムイメージ) AWS(AMI)
Linux向けdeprovisionコマンド 必須(waagent -deprovision+user) 不要
インスタンスの状態変更 deallocate → generalize → image create stop → Create Image
イメージ作成コマンド az image create --source VM名 aws ec2 create-image --instance-id ID
元のVM・インスタンスの再利用 generalize後は起動不可 AMI作成後もインスタンスは継続利用可
スナップショットの扱い イメージ内にOSディスクスナップショット含む AMI作成時にEBSスナップショットが自動作成
イメージからのVM作成コマンド az vm create --image イメージ名 aws ec2 run-instances --image-id ami-ID
AWSのLinux AMI作成は「停止 → AMI作成」のみで、deprovisionコマンドは不要です。一方Azureでは waagent -deprovision+user を省略するとイメージ化自体は成功するように見えても、そのイメージから起動したVMでプロビジョニングが正常完了せず、SSH接続できない状態になります。

また、Azureでは az vm generalize を実行したVMは二度と通常起動できなくなる点に注意が必要です。AWSではAMI作成後も元のインスタンスは引き続き使えます。AWSから移行する際に引っかかりやすい違いです。

トラブルシュート — よくあるエラーと対処

1. 「VM must be in a generalized state」エラー

az image create 実行時に以下のエラーが出る場合があります。

(OSProvisioningInternalError) VM must be in a generalized state when creating an image.

az vm generalize を実行していないことが原因です。az vm deallocateaz vm generalize の順に再実行してください。waagent -deprovisionを実行済みであれば、deallocate/generalizeだけ実行すれば回復できます。

2. カスタムイメージ起動VMにSSH接続できない

カスタムイメージからVMを起動したが管理者ユーザーでSSHできない場合、waagentのdeprovisionを実行せずにイメージ化したことが疑われます。

この場合は当該カスタムイメージを破棄し、ベースVMを新規作成してdeprovisionを正しく実行し直してください。deprovisionなしのイメージから多数のVMを展開した後に気づくケースもあるため、イメージ化前に必ずdeprovisionの実行ログを確認する手順をチェックリスト化しておくことを推奨します。

3. 「waagent: command not found」が表示される

waagentがインストールされていない場合です。

# RHEL/Rocky Linux向けwaagentインストール sudo dnf install -y WALinuxAgent # Ubuntuの場合 sudo apt-get install -y walinuxagent

Azureマーケットプレイスの標準イメージにはwaagentが含まれているため、通常このエラーは発生しません。オンプレミスからP2Vで持ち込んだVMなど、非標準イメージを使っている場合に発生することがあります。

本記事のまとめ

やりたいこと コマンド
VMをOSレベルで一般化する sudo waagent -deprovision+user
VMを割り当て解除する az vm deallocate --resource-group RG --name VM
AzureにVMの汎用化を通知する az vm generalize --resource-group RG --name VM
カスタムイメージを作成する az image create --resource-group RG --name ImageName --source VM
カスタムイメージ一覧を確認する az image list --resource-group RG --output table
カスタムイメージからVMを作成する az vm create --resource-group RG --name VM --image ImageName
VMが汎用化済みか確認する az vm get-instance-view --query "instanceView.statuses[*].displayStatus"

現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、Azureの学習をもっと体系的に進めたいなら、Azure実践ハンズオン講座をご覧ください。現役エンジニアが教える実務直結カリキュラムで、VM構築からインフラ管理まで一気に習得できます。

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。