Edited at

怠け者のためのVagrant+Chef入門

More than 3 years have passed since last update.

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 .

コマンドを実行すると、Berksfilecookbookssite-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が生成されており、中身が、


Berksfile

site :opscode


となっています。siteコマンドをレシピのダウンロード先の指定として使っていますが、これは古い記述法なので、より新しいsource指定に変更し、さらにSELinuxのレシピを取得するようにしてみます。

Berkshelfの内容を、以下のようにします。


Berksfile

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クックブックを指定します。


Vagrantfile

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に以下の設定を書き


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を以下の内容で作成することで抑制できます。


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の起動を行う指示をします。


site-cookbooks/nginx/recipes/default.rb

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クックブックをダウンロードします。


Berksfile

source "https://api.berkshelf.com"

cookbook 'selinux'
cookbook 'yum-epel'


これで準備完了なので、Vagrantfileにクックブックのレシピ呼び出し指定を追加します。


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の無効および停止するという簡単なものです。


site-cookbooks/nginx/iptables/default.rb

service "iptables" do

action [:disable, :stop]
end

このクックブックをVagrantfileに指定します。


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

で完了です。