初めての Vagrant + Chef zero + Berkshelf

  • 108
    いいね
  • 4
    コメント
この記事は最終更新日から1年以上が経過しています。

はじめに

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