PackerでVagrant Boxファイルを作成

やりたいこと

  • PackerでUbuntu 16.04 LTSのVagrant Boxファイルを自動作成
  • テンプレートはBoxcutterを利用する
  • Atlasへboxを登録する

Packer

Packerは仮想マシンやコンテナのイメージを作成するためのツール. BoxcutterはPacker用の設定テンプレート集.

PackerではOSの自動インストールにDebian系ではPreseed,RedHat系ではKickstartを使う. 今回はUbuntuなのでpreseedファイルを利用する.

Boxcutterのubuntu1604.jsonの設定から必要に応じて幾つかパラメータを変更する. 今回は以下の通り.

{
  "_comment": "Build with `packer build -var-file=ubuntu1604.json ubuntu.json`",
  "vm_name": "ubuntu1604",
  "cpus": "2",
  "disk_size": "40000",
  "iso_checksum": "f529548fa7468f2d8413b8427d8e383b830df5f6",
  "iso_checksum_type": "sha1",
  "iso_name": "ubuntu-16.04.2-server-amd64.iso",
  "iso_url": "http://releases.ubuntu.com/16.04/ubuntu-16.04.2-server-amd64.iso",
  "memory": "3072",
  "preseed" : "preseed_v1604.cfg",
  "hostname": "vagrant-xenial64",
  "ssh_fullname": "ubuntu",
  "ssh_password": "*********",
  "ssh_username": "ubuntu",
  "vagrantfile_template": "tpl/vagrantfile-ubuntu1604.tpl",
  "version": "0.1.1"
}

"disk_size""memory"の容量はMB単位.

パスワードが長すぎる場合(?)にユーザー名の入力画面で処理がストップする(エンターを押して次に進めばそのまま処理は続行する).条件の詳細は不明なので今後の課題.

"preseed"のファイル名に記号(文字と数字以外)が入るとsshが繋がらず落ちる.これも理由が不明なので今後の課題.

また,VagrantFileのテンプレート(tpl/vagrantfile-ubuntu1604.tpl)は以下の通り.

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
    config.vm.define "vagrant-ubuntu1604"
    config.vm.box = "xenial64"
    config.ssh.username = "ubuntu"
    config.ssh.password = "*********"
end

packerコマンドでビルドをおこなう.

$ packer build -only=virtualbox-iso -var-file=ubuntu1604.json ubuntu.json

結果は,box/virtualbox以下に保存されている. これをvagrantに追加し利用する.

Vagrant Boxの登録

$ vagrant box add xenial64 box/virtualbox/ubuntu1604-0.1.1.box

あとはどこか好きな場所で起動させる.

$ vagrant init xenial64
$ vagrant up

"update": "true"の場合

Vagrantのproviderがvirtualboxの場合はGuest Additionsがインストールされている. Guest Additionsの意義はGuest Additionsのインストール| VirtualBox Maniaなどを参照.

ただし,仮想マシンのカーネルを更新するとGuest Additionsも更新しなければならない. vagrant-vbguestプラグインを追加しておくことで,必要があれば自動でGuest Additionsを自動で更新してくれる.

$ vagrant plugin install vagrant-vbguest

Atlasへの登録

AtlasはVagrant Boxのホスティングサービス. 登録にはユーザー登録が必要.現状ではprivateだと有料.

packer pushコマンドを使うことでAtlas側でビルドして,完成したboxを公開することもできるが,これも有料.なので,今回はローカルでビルドしたboxをアップロードすることにする.

Atlasにログインして手動でアップロードできるが,ここではBox APIを利用してアップロードする.

アクセストークン

その前に準備としてアクセストークンを生成する必要がある. Atlasのページから

  • Account Settings
    • Tokens

と辿って,適当な名前をつけ,「Generate token」ボタンを押す. トークンが一度だけ表示されるので,どこか適当なところに保存する.

Box APIを使ったアップロード

既にBoxは作ってあるとする(APIからBoxを作ることも可能).

# バージョンを作成
$ curl https://atlas.hashicorp.com/api/v1/box/USER/BOX/versions -X POST -H "X-Atlas-Token: ACCESSTOKEN" -d "version[version]=VERSION"
# providerを追加
$ curl https://atlas.hashicorp.com/api/v1/box/USER/BOX/version/VERSION/providers -X POST -H "X-Atlas-Token: ACCESSTOKEN" -d "provider[name]=virtualbox"
#アップロード用のURLとパスが返る
{"upload_path":"https://binstore.hashicorp.com/UPLOADTOKEN","token":"UPLOADTOKEN"}
# Boxをアップロード
$ curl -X PUT --upload-file PATHTOBOXFILE https://binstore.hashicorp.com/UPLOADTOKEN
# リリース
$ curl https://atlas.hashicorp.com/api/v1/box/USER/BOX/version/VERSION/release -X PUT -H "X-Atlas-Token: ACCESSTOKEN"

これでAtlasへのVagrant Boxの登録が完了した. 今後は,

vagrant init USER/BOX
vagrant up

で起動できる.vagrant addを利用する必要がなくなる.

今後の課題

  • ユーザー名入力画面でストップする現象
    • パスワードが長すぎる場合に起こっている?
  • preseedファイル名に記号が含まれるとsshログインで失敗する
    • preseed-v1640.cfgpreseed_v1640.cfgを使うと発生
    • preseedV1640.cfgとすると解決.
    • その他記号については不明

参考