はじめに
Macでローカルのテスト環境を自動構築したいなーと思い、手を出してみました。
初心者なので、できる限りシンプルな構成で、とりあえず試してみることにします。
事前準備
まずはインストール
- VirtualBox:VirtualBox 4.3.26
Download VirtualBox - Vagrant:Vagrant 1.7.2
Download Vagrant - Chef:Chef Development Kit Version: 0.4.0
Download Chef
必要な 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 が作成され、中身はこんな感じになります。
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 にプライベートネットワークの設定します
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 に最新バージョンをインストールするように下記設定を追加
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
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
{
"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
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 あたりにも手を出して、より理解を深めていければなと。
-
2015/03/20時点では、https://supermarket.chef.io には最新の timezone-ii がアップされていなくて、 CentOs だと /etc/sysconfig/clock は更新されないみたいです。 ↩