Vagrant, Chef 周りの知見が溜まってきたのでそろそろまとめていきたいと思っているのですが、 まだまだ自分の中で分からない部分も多く、 かつ自分はインフラエンジニアではないので、 正直どこまで書いたらいいのか迷っています。
また、chef-solo はなくなるから、これからは chef-zero だ、なんて言われても、 インフラに関する前提知識が薄いので、なかなかついていくことができません・・・。
とはいえ、少なくとも使っていく中で自分なりの思想みたいなものははっきりしてきたので、 まずはそこから書いてみようと思います。
Vagrant が何なのかを知らない人に説明するとすれば、 仮想マシン(VM)をコマンドラインで統一的に扱えるインターフェースのようなものだと説明できると思います。
決して仮想環境そのものではなく、仮想環境を提供してくれるものとセットで使います。 例えば VirtualBox や VMWare 、あるいはリモートですが AWS(Amazon Web Service) なんかも選択肢になり得ます。
詳しくは https://www.vagrantup.com/ からインストール手順などを参考にして、実際に試されると良いかと思います。 (今回はこの辺り、一切触れません)
Vagrant をどういう用途で使うかというと、おそらく大きく2種類に分かれると思います。(主観)
1.は開発寄りの人が一番思いつきやすい用途だと思います。 全く同一でもない限り、ローカルで開発したものをリモート環境へ持っていくと、 少なからず環境による差異が問題になってきます。
2.は、運用寄り(インフラ寄り?)の人が一番思いつきやすい用途だと思います。 いくら Chef が便利だからといっても、本番環境にトライアンドエラーでレシピ適用して 問題がないケースはほとんどないと言っていいと思います。 この場合、手元の仮想マシンに対してレシピを適用して検証、問題なければ本番マシンに対して適用、 という流れが良いのではないかと考えています。
ここからはポイントに絞ってまとめていきます。
上記の用途の違いから、もし両方の用途が想定される場合は、 そもそも Vagrantfile を複数ディレクトリで分けて管理するとすっきりします。
Vagrantfile 上には、複数の仮想マシンの定義が記述できるため、 まとめて書こうと思えば全然書けてしまうのですが、 目的が全然異なっているので、使うレシピも共通化しないケースが多くなってくると思います。 (例えば開発用であれば、本番環境ほどセキュリティに過敏にならなくても良い場合があります)
Vagrantfile と同階層に cookbooks, site-cookbooks といった 適用するレシピのディレクトリを作って管理していますが、 レシピを共通化しないのであれば、あえて混ぜる理由もありません。
Vagrantfile が複数存在していると、今度は SSH で接続するためのポート番号や、 VM にアクセスするための IP アドレスが重複してくる可能性がどんどん高くなります。
開発想定の VM は何番から何番のポートを順に使い、IP アドレスはここから順に割り当てる、 運用想定の VM はこの番号から順に使う、といったように、 ポート番号、IP アドレスの管理をしっかり行うのが重要だと思います。
.ssh/config に、しっかり名前付きで記述しておき、 どの VM にもすぐにアクセスできるようにしておくと気持ちいいです。
Host virtual_machine_name
HostName 127.0.0.1
User vagrant
Port 12345
UserKnownHostsFile /dev/null
StrictHostKeyChecking no
PasswordAuthentication no
IdentityFile /path/to/insecure_private_key
IdentitiesOnly yes
LogLevel FATAL
認証鍵のレシピがうまく適用できるようになったら、 この辺りの設定も、その認証鍵設定済みのユーザーで気軽にアクセスできるようになっていると なお気持ちいいです。 (この辺りの話はまた改めてまとめ直したいです・・・)
あっ、当たり前ですが、Vagrant で VM を複数管理するときは、 ポート番号を全部バラバラにしないといけません。(当たり前)
vagrant ssh-config >> ~/.ssh/config
上記コマンドで設定を勝手に吐き出して追記してくれる便利なコマンドが用意されていますが、 複数 VM を想定したものになっていない(と思われる)ため、 例えば apple_vm, banana_vm の設定を順に追記してのち、 banana_vm に SSH してたつもりが、ずっと apple_vm に SSH してたことになってた、 なんてことが起こるかもしれません。(体験談)
接続ではまらないためにも、VM にアクセスするためのポート番号と VM 作成時の IP アドレスは きちんと管理すると良いと思います。
Vagrant はあくまで仮想マシン(VM)をコマンドラインで統一的に扱えるインターフェースなので、 仮想マシンの管理に徹した方がすっきりします。
以下は、Vagrant 1.6.5 で vagrant init したときの初期設定(コメント付き)を抜粋したものです。
config.vm.provision "chef_solo" do |chef|
chef.cookbooks_path = "../my-recipes/cookbooks"
chef.roles_path = "../my-recipes/roles"
chef.data_bags_path = "../my-recipes/data_bags"
chef.add_recipe "mysql"
chef.add_role "web"
# You may also specify custom JSON attributes:
chef.json = { mysql_password: "foo" }
end
このような形で、レシピの変更があるたびに Vagrantfile を触るというのは、 なんというか本質的ではないので、あくまで Vagrantfile には以下の情報のみが書かれているのが望ましいのでは?と思っています。(もちろん追加で synced_folder とか)
2つ目のところは自分が使いたい box ファイルを URL で指定すれば良いらしいですが、 以下に公開されているところを名前を指定するだけでも OK です。
https://vagrantcloud.com/boxes/search
ちょっと脱線しましたが、Vagrantfile 上には仮想マシンの定義のみをできるだけシンプルに管理しつつ、 レシピの適用は knife コマンドを用いて行った方がスムーズだと思います。
こちらの方法のメリットとして、上記の運用想定の Vagrant 管理において、 ローカル環境、本番環境とで同一の knife コマンドでレシピの適用ができるため、 レシピの適用方法が、適用先の環境に依存することなくスムーズにレシピ適用できる点があると思います。
また、仮想マシンが起動中に Vagrantfile の設定変更を行ってしまうことで、 うまく再起動などができなくなるケースが出てきます。 (例えば Vagrant 自身が SSH で接続するポート番号を途中で変えてしまうなど) 起動中に Vagrantfile はできるだけ触らない方が良いのではないかと思います。
ただ、vagrant provision でレシピを適用できるようにしておくと、 一通り GUI で扱えるようにしておいた場合に、 コマンドラインが苦手な人とも一緒に扱えるという利点が出てくる場合もあり得ます。
とはいえ、knife コマンドに慣れておいて損はないかなと、使ってみてそう思っています。 (この辺の掘り下げた話も追い追いで・・・)
時間もそこまで取れなかったので、とりあえず自分なりの思想的なところまでをまとめてみました。
実際まだまだ書ききれないことも多く、 例えば Vagrant のプラグインでこれ入れておくとこういうシーンで便利とか、 Web サーバにおいて、Vagrant 特有のはまりポイントと解決方法など、 過去に書いた記事の疑問点もだいぶ解消されてきたところもあるので、 改めてまとめ直したいと思います。
この記事は書かれてから1年以上が経過しており、最新の情報とは異なる可能性があります