Edited at

初めての Vagrant + Chef zero + Berkshelf

More than 3 years have passed since last update.


はじめに

Macでローカルのテスト環境を自動構築したいなーと思い、手を出してみました。

初心者なので、できる限りシンプルな構成で、とりあえず試してみることにします。


事前準備


まずはインストール


必要な Vagrant プラグインをインストールしておく

$ vagrant plugin install vagrant-omnibus

$ vagrant plugin install vagrant-chef-zero
$ vagrant plugin install vagrant-vbox-snapshot


  • vagrant-omnibus:ゲスト OS に Chef をインストールするために必要なプラグイン

  • vagrant-chef-zero:Vagrant から Chef Zero Server を起動するためのプラグイン

  • vagrant-vbox-snapshot:Vagrant のスナップショットを管理するプラグイン


構築してみる


VagrantFile の作成

まずは、ひな形を作成します。

今回は、短時間で仮想環境を作りたいので、Box と呼ばれる仮想マシンのベースイメージの CentOS6.4 を使うことにしました。

$ mkdir test_centos64

$ cd test_centos64
$ vagrant init test_centos64 http://developer.nrel.gov/downloads/vagrant-boxes/CentOS-6.4-x86_64-v20131103.box

そうすると Vagrantfile が作成され、中身はこんな感じになります。


Vagrantfile

Vagrant.configure(2) do |config|

・・・
config.vm.box = "test_centos64"
config.vm.box_url = "http://developer.nrel.gov/downloads/vagrant-boxes/CentOS-6.4-x86_64-v20131103.box"
・・・
end


  • config.vm.box:自分の box の名前として box の内容が分かるような文字列を指定します。

  • config.vm.box_url:Box の URL を指定します。

    参照:http://www.vagrantbox.es/

これらの記述があると、ローカルの Box に"test_centos64"という Box がある場合、ローカルの Box が使われ、存在しない場合は、指定した URL から Box をダウンロードし、ローカルに配置してくれます。

続いて、Vagrantfile にプライベートネットワークの設定します


Vagrantfile

Vagrant.configure(2) do |config|

・・・
config.vm.network :private_network, ip:"192.168.33.20"
・・・
end

これは別に設定しなくてもいいけど、把握しておきたいので、適当に。

ここまできたら、一度仮想マシンが起動できるか確かめてみます。

$ vagrant up

起動できたら、ゲスト OS に接続してみます

$ vagrant ssh

無事に接続OK!

問題なく接続できたら、ゲスト OS からログアウトしておきます。


いろいろ試すためにも Vagrant のスナップショットとっておく

初期状態をスナップショット。これで困ったら初期状態に戻せます。

# スナップショット作成

$ vagrant snapshot take test_centos64-init
# 確認
$ vagrant snapshot list


ゲスト OS にChefをインストール

Vagrantfile に最新バージョンをインストールするように下記設定を追加


Vagrantfile

Vagrant.configure(2) do |config|

・・・
config.omnibus.chef_version=:latest
・・・
end

起動中のゲスト OS に provisioners を実行

$ vagrant provision


Chef 設定ファイルの作成

とりあえずファイルの雛形を生成します。

$ chef generate repo chef-repo

$ tree
.
├── Vagrantfile
└── chef-repo
├── LICENSE
├── README.md
├── Rakefile
├── certificates
│   └── README.md
├── chefignore
├── config
│   └── rake.rb
├── cookbooks
│   └── README.md
├── data_bags
│   └── README.md
├── environments
│   └── README.md
└── roles
└── README.md


Berksfile を作成

Berkshelf を使って cookbook を管理するために Berksfile というファイルを新規に作成します。

$ cd chef-repo

$ vi Berksfile

今回はお試しということで、github 上に公開されている timezone を変更する cookbook を利用してみます。1


Berksfile

source "https://supermarket.chef.io"

cookbook 'timezone-ii', git: "https://github.com/L2G/timezone-ii.git"


cookbooks 配下に cookbook をインストールします。

$ berks vendor cookbooks

$ cd ..
$ tree
.
├── Vagrantfile
└── chef-repo
├── Berksfile
├── Berksfile.lock
├── LICENSE
├── README.md
├── Rakefile
├── certificates
│   └── README.md
├── chefignore
├── config
│   └── rake.rb
├── cookbooks
│   └── timezone-ii
│   ├── Gemfile
│   ├── Gemfile.lock
│   ├── LICENSE
│   ├── README.md
│   ├── Thorfile
│   ├── attributes
│   │   └── default.rb
│   ├── chefignore
│   ├── files
│   │   └── default
│   │   └── tests
│   │   └── minitest
│   │   └── default_test.rb
│   ├── metadata.json
│   ├── recipes
│   │   ├── amazon.rb
│   │   ├── debian.rb
│   │   ├── default.rb
│   │   ├── fedora.rb
│   │   ├── linux-generic.rb
│   │   ├── pld.rb
│   │   ├── rhel.rb
│   │   └── rhel7.rb
│   ├── spec
│   │   ├── attributes_spec.rb
│   │   ├── recipes
│   │   │   ├── amazon_spec.rb
│   │   │   ├── debian_spec.rb
│   │   │   ├── default_spec.rb
│   │   │   ├── fedora_spec.rb
│   │   │   ├── linux-generic_spec.rb
│   │   │   ├── pld_spec.rb
│   │   │   ├── rhel7_spec.rb
│   │   │   └── rhel_spec.rb
│   │   └── spec_helper.rb
│   ├── templates
│   │   ├── amazon
│   │   │   └── clock.erb
│   │   ├── centos
│   │   │   └── clock.erb
│   │   ├── default
│   │   │   └── timezone.conf.erb
│   │   ├── pld
│   │   │   └── timezone.conf.erb
│   │   └── redhat
│   │   └── clock.erb
│   └── test
│   └── integration
│   ├── default
│   │   └── bats
│   │   ├── date_output.bats
│   │   ├── debian.bats
│   │   └── etc_localtime.bats
│   └── helpers
│   └── bats
│   └── helper.bash
├── data_bags
│   └── README.md
├── environments
│   └── README.md
└── roles
└── README.md


Vagrant と Chef を連携します

調べてみたけど、いまいちどう管理するのがベストプラクティスなのかわからない。

共通系の cookbook は roles で run_list しちゃう方針として作ってみる。

$ vi chef-repo/roles/common.json


common.json

{

"name": "common",
"chef_type": "role",
"json_class": "Chef::Role",
"default_attributes": {
"tz": "Asia/Tokyo"
},
"run_list": [
"recipe[timezone-ii::rhel]"
]
}

ただ、roles で run_list はアンチパターンに該当してしまうのかも。。。2

Vagrantfile に下記を追加します

$ vi Vagrantfile


Vagrantfile

Vagrant.configure(2) do |config|

・・・
config.vm.provision "chef_zero" do |chef|
chef.cookbooks_path = "./chef-repo/cookbooks"
chef.roles_path = "chef-repo/roles"
chef.add_role "common"
end
・・・
end

起動中のゲスト OS を再起動して provisioners を実行

$ rm .vagrant/machines/default/virtualbox/synced_folders

$ vagrant reload --provision

バグらしく、通常の provisioners を実行だとエラーが発生してしまうので注意してください。

これで、ゲスト OS 起動時に recipe が実行され、timezone が"Asia/Tokyo"に設定されます。


まだまだ初心者なので、

今後、自作 recipe を作ってみたり、knife 使ってみたり、クライアント/サーバー構成にしてみたり、最終的には Docker あたりにも手を出して、より理解を深めていければなと。






  1. 2015/03/20時点では、https://supermarket.chef.io には最新の timezone-ii がアップされていなくて、 CentOs だと /etc/sysconfig/clock は更新されないみたいです。 



  2. [和訳]ChefConf 2013: Beginner Chef Antipatterns