Article Image

Vagrant 起動時に1回だけ実行するスクリプトを設定する

インフラ tockytocky

弊社ではサーバの構成管理に Chef を導入しています。最近いたるところで Chef の勉強会が開かれていたり、エンジニア系ブログでも目にしたりすることが増えてきましたが、まだ日本での事例が少ないように思います。

今回は Chef とセットで語られる Vagrantについて書こうと思います。Chef の Recipe や Cookbook を試すときにはローカル環境や何かしらの VM 環境上で実行することになりますが、これを手助けしてくれるのが Vagrant です。Vagrant は VirtualBox の CUI ラッパーという位置づけになり、非常に簡単に VM を作成することができます。ここでは Vagrant の詳しい使い方に触れませんので、より知りたい方は Software Design (ソフトウェア デザイン) 2012年 10月号) や伊藤直也さんが出されている 入門Chef Solo – Infrastructure as Code を参考にするとよいと思います。

さて、この Vagrant は以下のコマンドでインストールすることができます。

$ gem install vagrant

インストールすることによって vagrant というコマンドが利用できるようになります。実際に使うときには vagrant init などサブコマンドを与えてやります。vagrant init したディレクトリには Vagrantfile という VM 起動に必要な設定ファイルが作成されるわけですが、このファイルに VM の細かな設定を入れてあげることができます。また Vagrant 自体が Chef Solo との連携を考えて作られているため、特定の Cookbook を実行することも容易です。

しかし、今回は「VM を Vagrant から起動したときに最初の1回だけスクリプトを実行する」ということを設定してみたいと思います。VM の起動は vagrant up コマンドを使うのですが、初回だけ◯◯するという設定は自分で頑張って書くしかないようです。私は Proxy 設定が必要な環境下ではその設定がなかなか自動化できずに困っていましたが、Vagrant でシェルスクリプトを実行できるということを知ったので、シェルスクリプト内で判断させようと思いました。

Vagrantfile ではこのように VM 起動時の実行するシェルスクリプトを指定してあげます。

Vagrant::Config.run do |config|
  config.vm.box = "precise64"
  config.vm.box_url = "http://files.vagrantup.com/precise64.box"
  config.vm.network :hostonly, "192.168.33.10"
  # vagrant up のときに bootstrap.sh というスクリプトを実行する
  config.vm.provision :shell, :path => "bootstrap.sh"
end

次に、実際に呼ばれるシェルスクリプト bootstrap.sh を用意します。

#!/usr/bin/env bash

HTTP_PROXY="proxy.example.com:8000"
HTTPS_PROXY="$HTTP_PROXY"

# Exit if already bootstrapped
test -f /etc/bootstrapped && exit

echo "Setting HTTP Proxy for /etc/environment"
cat <> /etc/environment
http_proxy="http://$HTTP_PROXY/"
https_proxy="https://$HTTPS_PROXY/"
EOM

echo "Setting HTTP Proxy for /etc/apt/apt.conf"
test ! -f /etc/apt/apt.conf; touch /etc/apt/apt.conf
cat <> /etc/apt/apt.conf
Acquire::http::proxy "http://$HTTP_PROXY/";
Acquire::https::proxy "https://$HTTPS_PROXY/";
EOM

echo "Setting HTTP Proxy for cURL in Vagrant user directory"
if test -d /home/vagrant; then
  cat < /home/vagrant/.curlrc
  proxy = $HTTP_PROXY
EOM
fi

echo "Installing chef from deb package to use chef-solo"
test ! -d /etc/repository/setup; mkdir -p /etc/repository/setup
cp /vagrant/chef_11.4.0-1.ubuntu.11.04_amd64.deb /etc/repository/setup
dpkg -i /etc/repository/setup/chef_11.4.0-1.ubuntu.11.04_amd64.deb

date > /etc/bootstrapped

Proxy 周りは意外と厄介で、いくつかの設定をしてあげる必要があります。この bootstrap.sh では、ひとまずわかっている範囲で設定しています。

  • グローバル環境変数
  • apt が利用する設定
  • vagrant ユーザが curl するときの設定

さらに VM が利用する Chef パッケージも予めセットアップするようにしています (ベースとする VM にもよると思いますが、ここ記述している precise64 では手動で Chef パッケージを入れる必要があったので書いています)

この bootstrap.sh は vagrant up するときに必ず呼ばれるようになりますが、スクリプトの先頭で

# Exit if already bootstrapped
test -f /etc/bootstrapped >> exit

という分岐をしているため、2回目以降はスキップするようになります。