Amazon Linux 2023 を vagrant で使うメモ
Section 1.2 packer で box 作成 1 - 基礎作成 -
About
vagrant で使用するOSイメージのboxを作成します。
AWSで配布されている VMware で使用する際のマシンイメージ、 OVA形式のものを利用します。そのため、packer の VirtualBox integration にある VirtualBox OVF/OVA を使用してboxにしていきます。
フォルダ構造
いろいろ作成することになりますが、下記のような構造で作業していきます。
特に説明がなければ、フォルダやファイルはあるということになります。
[-] C:\
`--[-] vagrant
|--[+] box
|--[+] iso
|--[-] packer-amazonlinux2023
| |--[+] provisioners
| |--[+] seed
| `--[+] vagrant-config
`-- packer.exe
構成など
基本的には、packer build 設定ファイル.pkr.hcl でHCLファイルの内容に沿ってセットアップをしていきます。
HCL(HashiCorp Configuration Language)はHashiCorp社が開発した、人間が読み書きしやすく、かつ機械による自動処理にも適した設定言語です。Terraformなどでも採用されています。
HCLファイルは、sourceブロックで仮想マシンの元となるイメージをどうするかを指定し、buildブロックでプロビジョニング(shellの実行など)や後処理(boxファイルの作成など)を定義します。
HCL2ファイル
まずは、packer-amazonlinux2023 フォルダに、amazonlinux2023.12.pkr.hclを作成します。
内容は下記の通り。
required_plugins、source、buildブロックは必須です、localsはバージョンアップ毎に見直して書き直すのが手間だったので、バージョンなどを指定できるように変数にしています。
また、virtualboxのバージョンを作成したBoxファイル名に適応するために、variableブロックを使ってコマンドラインから指定できるようにしています。
packer {
required_plugins {
vagrant = {
source = "github.com/hashicorp/vagrant"
version = ">= 1"
}
virtualbox = {
source = "github.com/hashicorp/virtualbox"
version = ">= 1.1.5"
}
}
}
variable "virtualbox_version" {
type = string
description = "VirtualBox version"
default = "7.2.14"
sensitive = false
}
variable "al_version" {
type = string
description = "Amazon Linux 2023 version"
default = "2023.12.20260909.0"
sensitive = false
}
variable "user_home_path" {
type = string
description = "Windows User home directory path."
default = env("USERPROFILE")
sensitive = false
}
locals {
vmname_version = "2023.12"
ova_filename = "al2023-vmware_esx-${var.al_version}-kernel-6.1-x86_64.xfs.gpt.ova"
vmdk_filename = replace(local.ova_filename, ".ova", "-disk1.vmdk")
}
source "virtualbox-ovf" "AmazonLinux2023" {
headless = false
vm_name = "AmazonLinux-${local.vmname_version}"
source_path = "..\\iso\\${local.ova_filename}"
guest_additions_mode = "disable"
ssh_username = "vagrant"
ssh_password = "vagrant"
ssh_timeout = "15m"
# cd_files = ["./seed/meta-data", "./seed/user-data"]
# cd_label = "cidata"
shutdown_command = "echo 'vagrant' | sudo -S shutdown -P now"
vboxmanage = [
["modifyvm", "{{ .Name }}", "--firmware", "efi"],
["modifyvm", "{{ .Name }}", "--memory", "2048"],
["modifyvm", "{{ .Name }}", "--cpus", "4"],
["modifyvm", "{{ .Name }}", "--nat-localhostreachable1", "on"],
["modifyvm", "{{ .Name }}", "--pae", "on"],
["modifyvm", "{{ .Name }}", "--vram", "128"],
["modifyvm", "{{ .Name }}", "--graphicscontroller", "vmsvga"],
["modifyvm", "{{ .Name }}", "--audio-driver", "none"],
["modifyvm", "{{ .Name }}", "--uart1", "0x3F8", "4"],
["storagectl", "{{ .Name }}", "--name", "SCSI", "--remove"],
["storagectl", "{{ .Name }}", "--name", "VirtIO", "--add", "virtio"],
["storageattach", "{{ .Name }}", "--storagectl", "VirtIO", "--port", "0", "--device", "0", "--type", "hdd", "--medium", "${var.user_home_path}/VirtualBox VMs/{{ .Name }}/${local.vmdk_filename}"],
["storageattach", "{{ .Name }}", "--storagectl", "VirtIO", "--port", "1", "--device", "0", "--type", "dvddrive", "--medium", "./seed.iso"]
]
}
build {
sources = ["sources.virtualbox-ovf.AmazonLinux2023"]
post-processor "vagrant" {
keep_input_artifact = false
vagrantfile_template = "./vagrant-config/Vagrantfile.template"
output = "./AmazonLinux-${var.al_version}_VB${var.virtualbox_version}.box"
}
}
内容について上から解説。
packer
boxを作るうえで必須となる packer の plugin のバージョンを指定します。 virtualbox のプラグインは 1.1.5 以上にしているのはこのバージョンとでStorage周りに記法が変化したためです。
variable
コマンドライン上から指定できる変数を定義しています。
virtualbox_version はホストPC、この場合 Windows にインストールした VirtualBoxのバージョンです。
最終的に出力されるファイル名に使用しているだけの変数です。動作確認で変えたりするときにコードを修正しないで済むという理由で定義しているものです。
al_version AmazonLinux2023 のバージョンをフルで指定するための変数です。
このバージョンを使ってファイル名を特定しているので、必ず 2023.12.YYYYmmdd.x のような形式の値を使ってください。ova をダウンロードした際のページにある値を使えば大丈夫だと思われます。
なお、AWSサイトに上がっている最新版以外を使うと、dnfを使う時点でupgradeを求められます。その結果、boxはできるけれど仮想マシン起動時にエラーが出るという状態になるので注意してください。
user_home_path このあとの vboxmanage のところで説明しますが、ディスクイメージが展開された場所のパス情報が必要になるので定義しています。
env で環境変数として取得できるのですが、 variable 内でしか使用できないという制限があることもあってこのようにしています。
locals
出力されるファイル名や、仮想マシンの名称などでちょいちょい使うので変数化したものと、AWSのサイトからダウンロードしてきた ova のファイルパスの作成、vmdk のファイル名を構築しています。
vmdk_filename は、ovaファイルが展開されて出てきた仮想ディスク(VMDK = Virtual Machine Disk )をマウントするためにファイル名が必要になるためです。
ここまでが変数として定義したもので、これらを使いながら source を構成していきます。
source
headless は false にしています。trueにすることで画面すら出さずにboxまで作ってくれますが、途中経過を見つつ原因を調べる必要もあるのであえて表示しながら進めています。
guest_additions_mode = "disable"
OSのインストールCD/DVDのisoイメージの時には、これで VirtualBox Guest Addiotns のisoイメージを送り込んでいたのですが、CDドライブを認識させるのが面倒になったので disable にして何もしないように指定しています。
# cd_files = ["./seed/meta-data", "./seed/user-data"]
# cd_label = "cidata"
AWSのセットアップで使う Cloud-init が使えないので、cidata というディスクイメージ(isoイメージ)を作成してこの中身を使ってローカル版の Cloud-init が初期設定をします。ここで指定するとpackerの内部でisoイメージを作ってくれるのですが、Windowsの場合、Windows ADK をインストールして、oscdimg コマンドが使えるようにしなければならないらしく、手間だったのでコメントアウトしています。
source 内の vboxmanage
vboxmanage = [
この中身について。
["modifyvm", "{{ .Name }}", "--firmware", "efi"],
["modifyvm", "{{ .Name }}", "--memory", "2048"],
["modifyvm", "{{ .Name }}", "--cpus", "4"],
["modifyvm", "{{ .Name }}", "--nat-localhostreachable1", "on"],
["modifyvm", "{{ .Name }}", "--pae", "on"],
memory と cpus は希望するサイズに変えてください。最低でもこれでないと詰まる感じだったのでここを最低にしておいたほうが良いかもしれません。
boxができた後は、Vagrantfile で下げてもいいかもしれませんが…
firmware は、Virutalboxの標準のBIOSでは駄目だったので、 efi に変更します。
それ以外は、おまじないのようなものです。pae は on にしたほうが安定したので……
["modifyvm", "{{ .Name }}", "--uart1", "0x3F8", "4"],
AWS上ではいくつかの出力がシリアルポート経由で出ているらしく、シリアルポートが仮想マシンにある、という設定をしないとハングアップします。
["storagectl", "{{ .Name }}", "--name", "SCSI", "--remove"],
["storagectl", "{{ .Name }}", "--name", "VirtIO", "--add", "virtio"],
["storageattach", "{{ .Name }}", "--storagectl", "VirtIO", "--port", "0", "--device", "0", "--type", "hdd", "--medium", "${var.user_home_path}/VirtualBox VMs/{{ .Name }}/${local.vmdk_filename}"],
["storageattach", "{{ .Name }}", "--storagectl", "VirtIO", "--port", "1", "--device", "0", "--type", "dvddrive", "--medium", "./seed.iso"]
最後はディスクのつなぎ方の設定です。
VirutalBoxは SCSI 接続であると想定しているのですが、VMWareは VirtIO で繋げているようで、そのままだとディスクが繋がっていないことになってしまい起動しません。
なので、SCSIから外して(SCSO remove)、VirtIOのデバイスをつけて(VirtIO add)、storageattach でディスクイメージ(vmdkファイル)を繋げている、という流れになります。
最後の一行は、Cloud-init用のディスクイメージをDVDドライブにセットしてとして繋げたという設定です。seed.iso の内容などについては後述。
post-processor
build {
sources = ["sources.virtualbox-ovf.AmazonLinux2023"]
post-processor "vagrant" {
keep_input_artifact = false
vagrantfile_template = "./vagrant-config/Vagrantfile.template"
output = "./AmazonLinux-${var.al_version}_VB${var.virtualbox_version}.box"
}
}
vagrantfile_template を使って、boxを初期化した際にVagrantに与える初期設定を変更することができます。
PAE/NXの設定と、シリアルポートの設定が引き継げなかったのでここで設定を送り込んでおいて使うときに Vagrantfile を修正しないで済むようにしておきます。
作成ししていないファイルがあれこれ出てきたのでそれらを作りつつ、実行に必要なものを作成していきます。