VagrantとChefで楽をしたい。コミュニティで作成されたレシピを使ったり、VagrantでAWS上にプロビジョニングしたりしたいけれど、Chef Serverを立てるほどじゃない。自分で作ったレシピは使い回ししたいけど、Berkshelfでバリバリ管理するほででもない。そんなちょと中途半端で怠け者な僕たちのためのVagrant+Chef入門です。
Vagrantのインストール
公式サイトから使用しているOSに対応したパッケージをインストールします。
http://vagrantup.com/downloads.html
Vagrant Pluginのインストール
次にChefをプロビジョニングするためのプラグインをインストールします。
$ vagrant plugin install vagrant-omnibus
AWSを使う場合はAWS用のプロバイダーもインストールします。
$ vagrant plugin install vagrant-aws
Vagarnt Pluginの確認
インストールしたプラグインは、vagrant plugin list
コマンドで表示できるので、確認しておきましょう。
$ vagrant plugin list
vagrant-aws (0.5.0)
vagrant-login (1.0.1, system)
vagrant-omnibus (1.4.1)
これでVagrantのインストールは完了です。
Chefのインストール
次にChefをインストールします。これまでchef, berkshelf等は個別にインストールしてきましたが、Chef DKというChef関連ツールを一括でインストールできるパッケージがリリースされたので、こちらを使うことにします。
Chef DKのインストール
Chef DKのサイトに行き、使用しているOSに対応したパッケージをインストールします。
https://downloads.getchef.com/chef-dk/
knife-soloのインストール
knife-soloはChef DKでインストールしたchefコマンドを使用してインストールします。
chef gem install knife-solo
chef gemコマンドでインストールすることで、Chef DKの環境の中にknife-soloがインストールされます。
Vagrant+Chefディレクトリ構成
全体のディレクトリ構成ですが、ChefのファイルをVagrant間で共有するため、以下のようにトップディレクトリにChef関連のファイルを置き、その一段下に、各Vagrantの作業用のディレクトリを配置するという構成にします。
こうすることで、ChefのレシピをそれぞれのVagrantで簡単に共有することができます。
+-+- Berksfile
+- cookbooks/
+- data_bags/
+- environments/
+- nodes/
+- roles/
+- site-cookbooks/
+- vagrant-nginx/
+- vagrant-play/
+- vagrant-web/
+- vagrant-.../
この構成にするために、いくつか作業を行います。
Chef初期設定ファイルをknife soloで生成
まず、トップディレクトリにChef関連ファイルを準備するためknife solo
を実行します。
$ knife solo init .
コマンドを実行すると、Berksfile
、cookbooks
、site-cooksbooks
などのファイルやディレクトリが作成されます。
Vagrant Boxファイルの準備
VM作成のテンプレートとして、VagrantのBoxファイルを準備します。標準で配布されているVagrantのBoxファイルは、
で見つけることができます。このサイトからのBoxのインストールは表示されているBox名を指定することで行えます。
$ vagrant box add chef/centos-6.5
インストールされているBoxファイルは、
$ vagrant box list
で表示できます。
さらにコミュニティで作成されているBoxもあります。有名なところでは、
などがあります。試しに、Bento BoxからVMWare用のCentOS 6.6 Boxをインストールしてみましょう。vagrant addコマンドの文法は、
$ vagrant box add URL [--name VALUE]
ですので、上記のBento Boxのページから、VMWare用CentOS 6.6のリンクをコピーしてURLとして指定し、--nameにBox名としてbento-centos66を指定してみましょう。
$ vagrant box add http://opscode-vm-bento.s3.amazonaws.com/vagrant/vmware/opscode_centos-6.6_chef-provisionerless.box --name bento-centos66
これでBox名bento-centos66がインストールされました。
Vagrantfileの作成
さていよいよVagrant用のディレクトリを用意します。トップディレクトリに
$ mkdir vagrant-nginx
$ cd vagrant-nginx
をしてnginx向けVagrant設定用のディレクトリへ移動します。ここで、vagrant initコマンドを実行することで、Vagrantfileを作成することができます。
$ vagrant init bento-centos66
lsコマンドでVagrantfileが生成されていることを確認しましょう。
$ ls
Vagrantfile
このVagrantfileをカスタマイズすることで、VMに対して様々なプロビジョニングを行うことができます。
インスタンスの起動
まずこの状態でインスタンスの起動をしてみましょう。インスタンスの起動はvagrant upコマンドで行います。
$ vagrant up
特に問題がなければインスタンスが無事起動すると思います。
インスタンスのステータスとsshログイン
インスタンスの状態はvagrant statusコマンドで確認できます。
$ vagrant status
current machine states:
default running (vmware_fusion)
The VM is running. To stop this VM, you can run `vagrant halt` to
shut it down, or you can run `vagrant suspend` to simply suspend
the virtual machine. In either case, to restart it again, run
`vagrant up`.
またvagrant sshコマンドで、インスタンスにsshログインすることができます。
$ vagrant ssh
各種インスタンス操作
インスタンスの操作ですが、上記以外にも以下のコマンドが用意されています。
インスタンスの停止
$ vagrant halt
インスタンスのサスペンド
$ vagrant suspend
インスタンスの再開
$ vagrant resume
インスタンスの削除
$ vagrant destroy
Berkshelfでコミュニティクックブックをダウンロード
次にBerkshelfを活用してコミュニティクックブックをダウンロードしてみましょう。
最初は例として、selinuxのレシピを取得してみます。
ここで注意ですが、Berkshelfをコミュニティクックブックのダウンロードのみに使いますので、VagrantのBerkshelfプラグインは使用しないようにしましょう。
さきほどトップディレクトリで実行したknife soloの結果により、Berksfileが生成されており、中身が、
site :opscode
となっています。siteコマンドをレシピのダウンロード先の指定として使っていますが、これは古い記述法なので、より新しいsource指定に変更し、さらにSELinuxのレシピを取得するようにしてみます。
Berkshelfの内容を、以下のようにします。
source "https://api.berkshelf.com"
cookbook 'selinux'
レシピをダウンロードするにはberns vendorコマンドと、宛先ディレクトリ指定で呼び出しますが、ディレクトリがすでに存在している時にはエラーになってしまいます。
$ berks vendor ./cookbooks
destination already exists /Users/kunihiro/Chef/cookbooks. Delete it and try again or use a different filepath.
これを回避するために、以下のようなshell scriptをberks-update-recipe.shという名前で作成しておき、
#! /bin/sh
##
## Download thirdparty cookbooks under ./cookbooks using Berksfile.
##
if [ -d ./cookbooks ];then
echo "Removing existing cooksbooks"
rm -rf ./cookbooks
fi
berks vendor ./cookbooks
これを呼び出します。
$ ./berks-update-recipe.sh
Removing existing cooksbooks
Resolving cookbook dependencies...
Using selinux (0.8.0)
Vendoring selinux (0.8.0) to /Users/kunihiro/Chef/cookbooks/selinux
無事SELinuxのクックブックが./cookbook以下にダウンロードされます。
VagrantからChefクックブックを呼び出す
このSELinuxクックブックをVagrantから呼び出すよう設定しましょう。まずvagrant-nginxディレクトリに移動して、Vagrantfileの内容を変更します。
変更する箇所は2箇所あります。まずインスタンスにChefをプロビジョニングするために、config.omnibus.chef_version = :latestを指定し、最新のChefパッケージがインストールされるようにします。
もう一箇所は、クックブック関連の設定で、クックブックのパスとして、一つ上のディレクトリのcookbooksとsite-cookbooksを指定します。さらにadd_recipeコマンドで、SELinuxクックブックを指定します。
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
# Every Vagrant virtual environment requires a box to build off of.
config.vm.box = "bento-centos66"
# Omnibus
config.omnibus.chef_version = :latest
# Chef
config.vm.provision "chef_solo" do |chef|
chef.cookbooks_path = ["../cookbooks", "../site-cookbooks"]
chef.add_recipe "selinux::disabled"
end
end
これで準備は完了です。
Vagrantでインスタンスをプロビジョニング
さて、この内容をインスタンスに反映させましょう。その前にまず今のSELinuxの状態を確認しておきます。
$ vagrant ssh
Last login: Wed Nov 12 03:27:35 2014 from 192.168.48.1
[vagrant@localhost ~]$ getenforce
Enforcing
getenforceコマンドの出力からSELinuxが有効なのがわかります。
変更したVagrantfileを再読み込みしてプロビジョニングを行うには、vagrant reload --provisionコマンドを実行します。このコマンドはインスタンスが起動していてもいなくても有効です。
$ vagrant reload --provision
これで無事SELinuxが無効(PermissiveまたはDisabled)になったのが確認できると思います。
$ vagrant ssh
Last login: Wed Nov 12 03:52:19 2014 from 192.168.48.1
[vagrant@localhost ~]$ getenforce
Permissive
SSL Verify Mode Warningの抑制
デフォルトの設定だと、SSLのVerification Warningがでることがあります。
==> default: Running chef-solo...
==> default: [2014-11-10T02:30:19+00:00] INFO: Forking chef instance to converge...
==> default: [2014-11-10T02:30:19+00:00] WARN:
==> default: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
==> default: SSL validation of HTTPS requests is disabled. HTTPS connections are still
==> default: encrypted, but chef is not able to detect forged replies or man in the middle
==> default: attacks.
==> default:
==> default: To fix this issue add an entry like this to your configuration file:
==> default:
==> default: ```
==> default: # Verify all HTTPS connections (recommended)
==> default: ssl_verify_mode :verify_peer
==> default:
==> default: # OR, Verify only connections to chef-server
==> default: verify_api_cert true
==> default: ```
==> default:
==> default: To check your SSL configuration, or troubleshoot errors, you can use the
==> default: `knife ssl check` command like so:
==> default:
==> default: ```
==> default: knife ssl check -c /tmp/vagrant-chef-3/solo.rb
==> default: ```
==> default:
==> default: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
このワーニングは、Vagrantfileに以下の設定を書き
Vagrant.configure("2") do |config|
config.vm.provision "chef_solo" do |chef|
# the next line is added
chef.custom_config_path = "../Vagrantfile.chef"
end
end
さらにトップディレクトリにVagrantfile.chefを以下の内容で作成することで抑制できます。
Chef::Config.ssl_verify_mode = :verify_peer
nginx用カスタムクックブックの作成とコミュニティクックブックyum-epelの設定
さて、コミュニティクックブックだけではなく、自作のカスタムクックブックを作成してみましょう。
ここではnginxを例にカスタムクックブックを作成してみます。
まずknifeコマンドでクックブックの雛形を作成します。
$ knife cookbook create nginx -o site-cookbooks
次にレシピの実装をします。site-cookbooks/nginx/recipes/default.rbを編集してnginxのインストールと、status, restart, reloadコマンドをサポートしていることを指定して、nginxの起動を行う指示をします。
package "nginx" do
action :install
end
service "nginx" do
supports status: true, restart: true, reload: true
action [:enable, :start]
end
nginxのインストールには、EPELレポジトリの設定が必要です。こちらはコミュニティクックブックを活用しましょう。
Berksfileの内容にyum-epelを追加したのち、Berkshelfの設定時に作成したberks-update-recipe.shを実行してyum-epelクックブックをダウンロードします。
source "https://api.berkshelf.com"
cookbook 'selinux'
cookbook 'yum-epel'
これで準備完了なので、Vagrantfileにクックブックのレシピ呼び出し指定を追加します。
config.vm.provision "chef_solo" do |chef|
chef.cookbooks_path = ["../cookbooks", "../site-cookbooks"]
chef.custom_config_path = "../Vagrantfile.chef"
chef.add_recipe "selinux::disabled"
chef.add_recipe "yum-epel"
chef.add_recipe "nginx"
end
準備が整ったら、vagrant reload --provisionでプロビジョニングをしてみましょう。
iptablesを無効にするカスタムクックブックの作成
最後にiptablesを無効にするカスタムクックブックを作成してみましょう。これまでと同様knife cookbookコマンドで雛形を作成し、
$ knife cookbook create iptables -o site-cookbooks
site-cookbooks/nginx/iptables/default.rbを編集します。iptablesの無効および停止するという簡単なものです。
service "iptables" do
action [:disable, :stop]
end
このクックブックをVagrantfileに指定します。
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
# Every Vagrant virtual environment requires a box to build off of.
config.vm.box = "bento-centos65"
# Omnibus
config.omnibus.chef_version = :latest
# Chef
config.vm.provision "chef_solo" do |chef|
chef.cookbooks_path = ["../cookbooks", "../site-cookbooks"]
chef.custom_config_path = "../Vagrantfile.chef"
chef.add_recipe "selinux::disabled"
chef.add_recipe "iptables"
chef.add_recipe "yum-epel"
chef.add_recipe "nginx"
end
end
そして、
$ vagrant reload --provision
で完了です。