久しぶりの投稿になってしまいました・・・。
以前の投稿で、Ubuntu 24.04 LTSのVagrant Boxを作成した記事を書いていましたが、今回はその関連記事です。以前作成していた時には、私は VirtualBox を Vagrant のプロバイダー(バックエンドになるプラットフォームのこと)として使用していました。
結構遅かったのですが VMware Fusion pro が無償になり、Vagrantのプロバイダーとして使用可能ということを知りまして、試用してみたところ思いのほか好感触であったことから、ローカル環境作成を VirtualBox から VMware Fusion に切り替えしています。
主要なLinuxディストリビューションのインストールから検証を行っていたところ、CentOS系(AlmaLinux, RockyLinux)はあらかじめ Vagrant Box もあるので特に問題はなかったのですが、Ubuntuは前述の投稿にも書いた通り、Vagrant Boxの提供がありません。
そのため、以下のような手順で試してみたのですが、正常に起動するBoxの作成がどうもうまくいきません。
- VMware FusionでOVFエクスポートして ovftool で VMX に変換したのち、Box形式に圧縮
うまくいかなかったので詳細は省略しますが、ネットワークアダプタ(UbuntuのNetplan)要因なのか、設定の不備なのか特定ができませんでした。
どうしたものかと調べていたところ、AIアシスタントの Cursor さんに「Packer使うと自動作成してくれますよ!」と言われましたので、調べてみたところ、以下を行うツールだそうです。
- Vagrantと同じ、HashiCorp社製のサーバーイメージ自動作成ツール
- 単一のテンプレート(Packerの設定ファイル)でAWS (AMI)、Azure、VMware (VMDK/VMX)、VirtualBox (OVF) などで使用できるイメージを定義できる
特徴としては以下が挙げられるそうです。
- 自動化: JSONファイルで定義を記述し、コマンド一つでビルド可能
- 一貫性・安定性: イメージ構築手順をコード化し、手作業によるミスを減らし、テストを容易に
- プロビジョニング: Chef, Puppet, Ansibleなどのツールと連携してイメージ内ソフトウェアをカスタマイズ可能
1回設定ファイルを作成しておくと、後々Box作成する時に便利ではないかと思い、今回試してみました。
というわけで、以下に手順と注意点などを書いていこうと思います。ちなみに今回ですが、以前と同じでUbuntu 24.04 LTSのISOイメージからBoxを作っていこうと思います。
1.Packerをインストール
Homebrew(パッケージマネージャ)を使用して、Packerをインストールします。
brew install packer
2.ディレクトリ構成
今回の作業ディレクトリ構成は以下のとおりです。
├── ubuntu-24.04.pkr.hcl # メインのPacker設定ファイル
└── cidata/ # cloud-init設定(autoinstall用)
├── user-data # インストール設定
└── meta-data # メタデータ(空ファイル)
- locale設定
- ネットワーク設定
- ストレージ設定
- ユーザー設定
- SSH設定
- パッケージインストール
- インストール後のvagrant用のsudo設定、SSH設定
user-data というファイルに記述されています。一方 meta-data ですが、本来はインスタンスIDやホスト名を記述できますが、今回は user-data に記述しています。そのため空になっています。ただし、cloud-init のNoCloudデータソースは、user-data と meta-data の両方が必要になります。どちらかが欠けるとNoCloudデータソースとして認識されず、autoinstallが起動しません。
cloud-init:クラウドインスタンス(仮想マシン)の初期設定を自動化するための業界標準ツール
データソース:cloud-init は通常、AWS、GCP、Azure などのクラウドプロバイダーが提供するメタデータサービス(例:169.254.169.254)からデータを取得します。データソースとは、このデータの取得元を定義するコンポーネント(部品)のことです。
NoCloudデータソース:ローカル環境(仮想マシンやベアメタルサーバー)ではクラウドプロバイダーが提供するメタデータサービスがありません。NoCloudデータソースは、そのような環境でcloud-initが初期設定に必要なデータを取得するための仕組みです。
どこからデータを取得してくるかにより、使用するものが変わってきます。
メインのPacker設定ファイル(ubuntu-24.04.pkr.hcl)は、Ubuntu 24.04 のISOイメージからVagrant Boxを自動生成するためのテンプレートです。大きく分けて4つのセクションで構成されています。
1)プラグイン定義
Packerの拡張機能として、2つのプラグインを使用しています。
-
-
-
- vmware プラグイン: VMware Fusion上で仮想マシンを作成・操作するために必要
- vagrant プラグイン: ビルド完了後に .box ファイルを生成するために必要
-
-
Packerはプラグインベースのアーキテクチャを採用しており、対象のプラットフォームに応じたプラグインを組み合わせて使います。
2)変数定義
テンプレートの再利用性を高めるため、変更が必要な値を変数として切り出しています。
-
-
-
- ISOファイルのパス: 環境によって異なるため変数化
- VM名: 生成されるVMの名前
- SSH認証情報: プロビジョニング時にPackerがSSH接続するための認証情報
-
-
変数化しておくことで、同じテンプレートを別バージョンのUbuntuにも流用しやすくなります。
3)ソース定義(VMビルダー)
このセクションが設定ファイルの肝で、どのような仮想マシンを作成するかを定義しています。
⚪︎ハードウェア構成
CPU、メモリ、ディスクサイズなど、仮想マシンのスペックを指定します。今回は最低限の構成(2コア、2GB RAM、20GB ディスク)としています。
⚪︎ISOとブート設定
UbuntuのISOファイルを指定し、起動時のブートコマンドを定義します。ポイントはGRUBコマンドラインから直接カーネルを起動している点です。これにより、GRUBメニューのタイミングに依存せず、確実に自動インストール(autoinstall)を開始できます。
⚪︎cloud-init連携
autoinstallを動作させるため、NoCloudデータソース を利用しています。user-data と meta-data ファイルをISOイメージとしてマウントし、ボリュームラベルを cidata に設定することで、cloud-initがこれを認識して自動インストールを実行します。
⚪︎SSH接続設定
Packerはインストール完了後、SSHでVMに接続してプロビジョニングを行います。タイムアウトや再試行回数を十分に確保し、インストールに時間がかかっても接続が成功するようにしています。
4)ビルド定義
VMが作成された後の後処理を定義するセクションです。
⚪︎プロビジョニング(シェルスクリプト)
SSHで接続した後、Vagrant Boxとして使えるようにするための設定を行います。
-
-
-
-
- システムアップデート: 最新のセキュリティパッチを適用
- Vagrant SSH公開鍵の設定: vagrant ssh でパスワードなしログインできるようにします
- sudoers設定: vagrant ユーザーがパスワードなしで sudo を実行可能に
- ネットワーク設定の汎用化: Netplanをワイルドカード設定に変更し、どの環境でもDHCPでIPを取得できるようにします
- Machine-IDのリセット: 同じBoxから複数VMを起動した際のDHCP重複問題を防止
- ディスクのゼロ埋め: 未使用領域をゼロで埋めることで、Boxファイルの圧縮効率を大幅に向上(これは以前の投稿でも書きましたね)
-
-
-
⚪︎ポストプロセッサ(Vagrant Box生成)
プロビジョニングが完了したVMを、Vagrantで利用可能な .box ファイルとしてパッケージングします。
3.実際のファイル
2.で説明したファイルの中身が以下になります。ISOファイルやチェックサムなどは適宜置き換える必要があります。
cidata/user-data
====================
#cloud-config
autoinstall:
version: 1
# ロケール設定
locale: en_US.UTF-8
keyboard:
layout: us
# ネットワーク(DHCPで自動取得)
network:
version: 2
ethernets:
id0:
match:
name: en*
dhcp4: true
# ストレージ(自動パーティション)
storage:
layout:
name: lvm
# ユーザー設定
identity:
hostname: ubuntu
username: vagrant
# パスワード: vagrant(SHA-512ハッシュ)
# このパスワード(vagrant)はVagrant Boxの開発用デフォルトパスワードです。
password: "$6$randomsalt$jguz.88OgNwt3/K5rWTBg.PCeut4KfhMQF0TCyAGmUzgcoHYnfRGTa8vU9WkmZj7uCLiMPkY77fZJdNG5xbSy."
# SSH設定
ssh:
install-server: true
allow-pw: true
# パッケージ
packages:
- open-vm-tools
- curl
- wget
- ca-certificates
# インストール後のコマンド(最小限に)
late-commands:
# vagrantユーザーにsudo権限付与(これだけでSSH接続可能になる)
- echo 'vagrant ALL=(ALL) NOPASSWD:ALL' > /target/etc/sudoers.d/vagrant
- chmod 440 /target/etc/sudoers.d/vagrant
cidata/meta-data
====================
# 空です。
ubuntu-24.04.pkr.hcl
====================
packer {
required_plugins {
vmware = {
version = ">= 1.0.0"
source = "github.com/hashicorp/vmware"
}
vagrant = {
version = ">= 1.1.0"
source = "github.com/hashicorp/vagrant"
}
}
}
# ===================
# 変数定義
# ===================
variable "iso_path" {
type = string
default = "/path/to/ubuntu-24.04.3-live-server-amd64.iso" # ← ISOパスを変更
}
variable "vm_name" {
type = string
default = "ubuntu-24.04-vagrant"
}
variable "ssh_username" {
type = string
default = "vagrant"
}
variable "ssh_password" {
type = string
default = "vagrant"
}
# ===================
# VMware Fusion ビルダー
# ===================
source "vmware-iso" "ubuntu" {
# VM基本設定
vm_name = var.vm_name
guest_os_type = "ubuntu-64"
version = "21" # VMware Hardware Version
headless = false # GUIを表示(デバッグ用、完成後はtrueに)
# ISO設定
iso_url = var.iso_path
iso_checksum = "sha256:xxxxxxxxxx" # ← チェックサムを変更
# ハードウェア設定
cpus = 2
memory = 2048
disk_size = 20480
disk_type_id = "0" # Growable disk
# ネットワーク設定
network = "nat"
network_adapter_type = "e1000e"
# 出力設定
output_directory = "output-ubuntu-24.04"
# SSH接続設定
ssh_username = var.ssh_username
ssh_password = var.ssh_password
ssh_timeout = "45m"
ssh_port = 22
ssh_handshake_attempts = 100
# シャットダウンコマンド
shutdown_command = "echo '${var.ssh_password}' | sudo -S shutdown -P now"
# cloud-init用ISO(セカンダリCD)
cd_files = ["./cidata/user-data", "./cidata/meta-data"]
cd_label = "cidata"
# ブートコマンド(GRUBコマンドラインから直接ブート)
boot_wait = "5s"
boot_command = [
"c",
"<wait3>",
"set gfxpayload=keep<enter>",
"linux /casper/vmlinuz quiet autoinstall 'ds=nocloud' ---<enter>",
"initrd /casper/initrd<enter>",
"boot<enter>"
]
# VMware VMX追加設定(Packerデフォルトと重複しない設定のみ)
vmx_data = {
"ethernet0.present" = "TRUE"
"ethernet0.addressType" = "generated"
}
}
# ===================
# ビルド定義
# ===================
build {
name = "ubuntu-vagrant-box"
sources = ["source.vmware-iso.ubuntu"]
# ---------------------------------------
# プロビジョニング: Vagrant用設定
# ---------------------------------------
provisioner "shell" {
execute_command = "echo '${var.ssh_password}' | sudo -S bash -c '{{ .Vars }} {{ .Path }}'"
inline = [
# アップデート
"echo '>>> システムアップデート中...'",
"apt-get update",
"apt-get upgrade -y",
# 必要なパッケージインストール
"echo '>>> パッケージインストール中...'",
"apt-get install -y open-vm-tools curl wget ca-certificates",
# Vagrant SSH公開鍵設定
"echo '>>> Vagrant SSH鍵設定中...'",
"mkdir -p /home/vagrant/.ssh",
"chmod 700 /home/vagrant/.ssh",
"curl -fsSL https://raw.githubusercontent.com/hashicorp/vagrant/main/keys/vagrant.pub -o /home/vagrant/.ssh/authorized_keys",
"chmod 600 /home/vagrant/.ssh/authorized_keys",
"chown -R vagrant:vagrant /home/vagrant/.ssh",
# sudoers設定(パスワードなしsudo)
"echo '>>> sudoers設定中...'",
"echo 'vagrant ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/vagrant",
"chmod 440 /etc/sudoers.d/vagrant",
# SSH設定
"echo '>>> SSH設定中...'",
"sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication yes/' /etc/ssh/sshd_config",
"sed -i 's/^#*UseDNS.*/UseDNS no/' /etc/ssh/sshd_config",
# Netplan汎用化(重要!)
"echo '>>> ネットワーク設定汎用化中...'",
"cat > /etc/netplan/00-vagrant.yaml << 'EOF'",
"network:",
" version: 2",
" renderer: networkd",
" ethernets:",
" id0:",
" match:",
" name: \"en*\"",
" dhcp4: true",
" id1:",
" match:",
" name: \"eth*\"",
" dhcp4: true",
"EOF",
# 既存のNetplan設定を削除
"rm -f /etc/netplan/50-cloud-init.yaml",
"rm -f /etc/netplan/00-installer-config.yaml",
# Cloud-initネットワーク設定無効化
"mkdir -p /etc/cloud/cloud.cfg.d",
"echo 'network: {config: disabled}' > /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg",
# Machine-IDリセット(DHCP問題対策)
"echo '>>> Machine-IDリセット中...'",
"truncate -s 0 /etc/machine-id",
"rm -f /var/lib/dbus/machine-id",
"ln -sf /etc/machine-id /var/lib/dbus/machine-id",
# クリーンアップ
"echo '>>> クリーンアップ中...'",
"apt-get autoremove -y",
"apt-get clean",
"rm -rf /tmp/*",
"rm -rf /var/tmp/*",
"rm -rf /var/cache/apt/archives/*.deb",
# ログクリア
"find /var/log -type f -exec truncate -s 0 {} \\;",
# Bash履歴クリア
"rm -f /home/vagrant/.bash_history",
"rm -f /root/.bash_history",
# swap無効化(ゼロ埋め前に必要)
"swapoff -a",
# ディスクのゼロ埋め(圧縮効率を大幅に向上)
"echo '>>> ディスクのゼロ埋め中...(時間がかかります)'",
"dd if=/dev/zero of=/EMPTY bs=1M 2>/dev/null || true",
"rm -f /EMPTY",
"sync",
"echo '>>> プロビジョニング完了!'"
]
}
# ---------------------------------------
# ポストプロセッサ: Vagrant Box生成
# ---------------------------------------
post-processor "vagrant" {
output = "ubuntu-24.04-vmware.box"
keep_input_artifact = false
}
}
4.PackerでBoxをビルド
以下コマンドを実行することで、Vagrant Boxファイルが自動生成されます。
### 1. 作業ディレクトリに移動
cd /path/to/work/directory
### 2. プラグインをインストール
packer init ubuntu-24.04.pkr.hcl
### 3. 設定を検証
packer validate ubuntu-24.04.pkr.hcl
### 4. ビルド実行
packer build ubuntu-24.04.pkr.hcl
実行中は VMware Fusion のウィンドウが自動で立ち上がったり、コマンド入力が行われたりします。





Boxファイルが作成できたら、VMware Fusionのウィンドウは閉じて問題ありません。(Box作成時に仮想マシンはシャットダウンしているため)
ちなみに今回作成したBoxファイルですが、大体12分前後で作成されます。あとファイルサイズですが1.4GB前後です。以前の投稿と比較してみると、パッケージを入れた分少し大きくなっているのかもしれません。今回容量についてはあまりスリム化を突き詰めてはいませんので、とりあえずはよしとしておきます。
まずは作成したBoxでvagrantの起動確認を行います。

起動は問題ありませんでした。
設定を一度作成しておけば同じものを何回も作成できるので、便利だなと思いました。あと、Dockerイメージ作成の時にも使用できるらしく、ケースによっては有用だということなので、もう少し触ってみて、何か発見があればまた共有しようと思います。