Vagrantでのprovisionerとしての使用を想定しつつ、Chefの基本的な操作をチュートリアルに従って確認。また、公式のドキュメントを流し見して、全体の概要をまとめてみる。

  1. 環境確認
  2. とりあえず動かしてみる
  3. とりあえずパッケージをインストールしてみる
  4. Chefに関するMemo

環境

  • OS: Mac OS 10.11.4
  • VirtualBox: 5.0.20
  • Vagrant: 1.8.1
  • chefdk: 0.13.21

1. 環境確認

Vagrantで構築したCentOSの仮想マシンを使用する。今回はすでにChefのインストールされているボックスファイルを選択。

[vagrant@localhost ~]$ uname -a
Linux localhost.localdomain 2.6.32-358.el6.x86_64 #1 SMP Fri Feb 22 00:31:26 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

[vagrant@localhost ~]$ cat /etc/redhat-release
CentOS release 6.4 (Final)

[vagrant@localhost ~]$ chef-client -v
Chef: 11.8.0

2. とりあえず動かしてみる

公式のチュートリアルを見ながら進めようとしたが、chef-client --local-mode hello.rbを実行してもhello.rbが認識されなくてしょっぱなから躓く。色々調べて以下のようなディレクトリ構成、コマンドを書き換えてから動作することを確認。

# Cookbooks structure
$ tree cookbooks
cookbooks
├── helloworld (called as 'Cookbook')
│   └── recipes
│       ├── default.rb (called as 'Recipe')
│       └── renamed.rb (called as 'Recipe')
└── motd (called as 'Cookbook')
    └── recipes
        └── default.rb (called as 'Recipe')
# First recipe
[vagrant@localhost cookbooks]$ cat helloworld/recipes/default.rb
file '/tmp/motd' do
  content 'hello world'
end

# '-z' option means '--local-mode', '-o' name of recipe
[vagrant@localhost cookbooks]$ chef-client -z -o helloworld
[2016-05-18T13:12:43+00:00] WARN: No config file found or specified on command line, using command line options.
Starting Chef Client, version 11.8.0
[2016-05-18T13:12:43+00:00] WARN: Run List override has been provided.
[2016-05-18T13:12:43+00:00] WARN: Original Run List: [recipe[helloworld]]
[2016-05-18T13:12:43+00:00] WARN: Overridden Run List: [recipe[helloworld]]
resolving cookbooks for run list: ["helloworld"]
Synchronizing Cookbooks:
  - helloworld
Compiling Cookbooks...
Converging 1 resources
Recipe: helloworld::default
  * file[/tmp/motd] action create
    - create new file /tmp/motd
    - update content in file /tmp/motd from none to b94d27
        --- /tmp/motd	2016-05-18 13:12:43.722662694 +0000
        +++ /tmp/.motd20160518-4058-19d2ftv	2016-05-18 13:12:43.724662693 +0000
        @@ -1 +1,2 @@
        +hello world

Chef Client finished, 1 resources updated

# Second recipe
[vagrant@localhost cookbooks]$ cat helloworld/recipes/renamed.rb
file '/tmp/motd' do
  content 'hello hello world'
end

[vagrant@localhost cookbooks]$ chef-client -z -o helloworld::renamed
[2016-05-18T13:16:36+00:00] WARN: No config file found or specified on command line, using command line options.
Starting Chef Client, version 11.8.0
[2016-05-18T13:16:37+00:00] WARN: Run List override has been provided.
[2016-05-18T13:16:37+00:00] WARN: Original Run List: [recipe[helloworld]]
[2016-05-18T13:16:37+00:00] WARN: Overridden Run List: [recipe[helloworld::renamed]]
resolving cookbooks for run list: ["helloworld::renamed"]
Synchronizing Cookbooks:
  - helloworld
Compiling Cookbooks...
Converging 1 resources
Recipe: helloworld::renamed
  * file[/tmp/motd] action create
    - update content in file /tmp/motd from b94d27 to 1324b3
        --- /tmp/motd	2016-05-18 13:12:43.724662693 +0000
        +++ /tmp/.motd20160518-4313-yq22rf	2016-05-18 13:16:37.179662468 +0000
        @@ -1,2 +1,2 @@
        -hello world
        +hello hello world

Chef Client finished, 1 resources updated

3. とりあえずパッケージをインストールしてみる

チュートリアルに従って’httpd’パッケージをインストールしてみる。

[vagrant@localhost cookbooks]$ cat helloworld/recipes/webserver.rb
package 'httpd' do
  action :install
end

[vagrant@localhost cookbooks]$ sudo chef-client -z -o helloworld::webserver
[2016-05-18T13:43:12+00:00] WARN: No config file found or specified on command line, using command line options.
Starting Chef Client, version 11.8.0
[2016-05-18T13:43:13+00:00] WARN: Run List override has been provided.
[2016-05-18T13:43:13+00:00] WARN: Original Run List: [recipe[helloworld]]
[2016-05-18T13:43:13+00:00] WARN: Overridden Run List: [recipe[helloworld::webserver]]
resolving cookbooks for run list: ["helloworld::webserver"]
Synchronizing Cookbooks:
  - helloworld
Compiling Cookbooks...
Converging 1 resources
Recipe: helloworld::webserver
  * package[httpd] action install
    - install version 2.2.15-47.el6.centos.4 of package httpd

Chef Client finished, 1 resources updated

[vagrant@localhost cookbooks]$ httpd -v
Server version: Apache/2.2.15 (Unix)
Server built:   Mar 22 2016 19:03:53

簡単にインストールできたので、起動、index.html表示と流れるようにいけると思いきややはり躓く。どうやらiptables周りが原因なようだったので、一旦OFFにしてhttpサーバの動作を確認することにする。

[vagrant@localhost cookbooks]$ cat helloworld/recipes/webserver.rb
service 'iptables' do
  action [:stop, :disable]
end

package 'httpd' do
  action :install
end

# chkconfig httpd on
# service httpd start
service 'httpd' do
  action [:enable, :start]
end

# Source file located in helloworld/templates/default
template '/var/www/html/index.html' do
  source 'index.html.erb'
  mode 0644
end

[vagrant@localhost cookbooks]$ sudo chef-client -z -o helloworld::webserver
...

httpサーバが起動しており、ホスト側からcurl 192.168.33.10で目的のindex.htmlにアクセスできることを確認。


4. Chefに関するMemo

公式のチュートリアルやドキュメントを触り読みながらChefに関する概要をメモ書き。

Chef全体

  • 処理の単位にはCookbook, Recipe, Resourceというものがある。
    • Resourceが最も最小単位であり、1つの動作を表す。上でいうfile
    • ‘Recipe’は’Resource’をまとめたもの。上でいうdefault.rb, renamed.rb
    • ‘Cookbook’はRecipeをまとめたもの。上でいうhelloworld
  • recipe名のデフォルトはdefault.rbのよう。違うrecipeを指定したい時は<cookbook>::<recipe>という記述となる。

Chefを構成するマシン

基本的にChefはクライアント-サーバ構成を持つ。マシンの主要な役割と関係するツールは以下のような感じ。

  • Chef server
    • clientが使用するcookbooksなどを管理するマシン
  • Nodes(Chef client)
    • Chefによるprovisionを行いたい対象マシン
    • chef-clientを使用
  • Workstation
    • cookbooksの作成などを行い、サーバにアップする作業用マシン
    • (単一、あるいは複数の)cookbookをリポジトリ(chef-repoと表記されることが多い)にまとめ、これをgit等でバージョン管理を行うのを推奨
    • Chef Supermarketに多数のcookbookが登録されている
    • chef, kitchen, knife, chefspec, berkshelf等を使用
    • chefdkをインストールすれば一式揃う

Workstation上での主要な操作

chef

  • chef generate repo <repository_name>
    • chef-repoの作成。cookbooks/を含むディレクトリ構成を持つ。
  • chef generate cookbook <cookbook_name>
    • cookbookの作成。様々なファイルを作って含めてくれる。recipeとしてはrecipes/default.rbが自動で生成される。
  • chef generate recipe <path_to_cookbook> <recipe_name>
    • recipeの作成。<path_to_cookbook>/recipes/<recipe_name>.rb等が作成される。
  • chef generate template <path_to_cookbook> <template_name>
    • templateの作成。 <path_to_cookbook>/templates/default/<template_name>.erbが作成される。
    • .erb形式なので<%= var %>, <% proc %>等の記述で変数の埋込や処理の実行を行える。
  • chef generate attribute <path_to_cookbook> <attribute_name>
    • attributeファイルの作成。<path_to_cookbook>/attributes/<attribute_name>.rbが作成される。
    • Chefでのattributeの概念は結構複雑で、異なる箇所に、幾つかの優先度を持たせて書くことができる。
    • とりあえずrecipeに値をベタ書きしたくない、という程度ならdefault.rbでattributeを定義してあげれば十分そう。

kitchen

テスト用仮想マシンの管理を行うツール。自作のcookbookの動作確認を行うために使用する。.kitchen.ymlが設定ファイルとなる。

  • kitchen list
    • テスト用仮想マシン一覧の表示。
  • kitchen converge
    • テスト用仮想マシンの作成。
    • <path_to_cookbook>/.kitchen.ymlを参照して仮想マシンを作成し、cookbookを適用する。
  • kitchen login
    • 作成したテスト用仮想マシンへのログイン。
  • kitchen destroy
    • テスト用仮想マシンの破棄。

.kitchen.ymlの記述例は以下の通り。

driver:
  name: vagrant
  network:
      - ["private_network", {ip: "192.168.33.33"}]

provisioner:
  name: chef_zero

# Set driver.box if want to use local box
platforms:
  - name: centos-7.2
    driver:
        box: centos-7.2

suites:
  - name: default
    run_list:
      - recipe[awesome_customers::default]
    attributes:

Berkshelf

cookbookのインストールおよび依存関係を解決するためのツール。
Berksfileが設定ファイル。

  • berks install
    • Berksfileに記載したcookbookを依存関係を解決しつつダウンロードする。デフォルトのダウンロード先は~/.berkshelfとなる。
    • 依存cookbookはBerksfileではなくmetadata.rbに記載するべき? 参照
      • 多分そもそも2つは用途が異なる。以下は現在の認識であり、間違いがあるかも。
      • metadata.rbに含めるということは、cookbookのメタデータの一つになるということだといえる。もしcookbookのディレクトリ下でberksコマンドを実行すれば、その依存関係を解決して全ての必要なcookbookをダウンロードしてくれるが、それが主目的で依存関係をmetadata.rbに書くわけではない(と思う)。
      • Berksfileは純粋にcookbookを集めるためのもの。特定のcookbookに関わったりするものではない(はず)。
  • berks vendor <path_to_repo>
    • 指定したパスにcookbookをダウンロードする。
    • Vagrantのprovisionとして用いたりするときに使っているのをよく見る。

Policyに関して

Chefを実行する際の設定等を管理する仕組みというイメージ。例えば、あるnodeに対して’web server’というroleを与え、”development”というenvironmentでChefを実行させることで、開発時のWeb Server用マシンを構築する、というような。
Policyとしては以下の3つが含まれる。

  • Role
    • 対象のサーバタイプを決定する。 e.g. ‘web server’, ‘database server’
    • attributeやrun-listが定義できる
  • Environment
    • 対象の開発プロセスを決定する。 e.g. ‘development’, ‘production’
    • attributeをプロセスによって書き換えるような使い方
  • Data bags
    • パスワードのようなセキュアに管理したい設定を保管する仕組み

Role

  • 設定ファイルは<path_to_cookbook>/roles/<name_of_role>.json
  • rb形式でも設定できるらしいが、未確認。
  • roleの定義ファイルは以下のような感じ。
$ cat roles/web.json
{
    "name": "web",
    "description": "Web role",
    "chef_type": "role",
    "json_class": "Chef::Role",
    "default_attributes": {},
    "override_attributes": {},
    "run_list": [
        "recipe[env_test::web]"
    ]
}

Environment

  • 設定ファイルは<path_to_cookbook>/environments/<name_of_environment>.json
  • rb形式でも設定できるらしいが、試しにkitchenで動かしている際には確認できず。
  • 以下のようにdefault attributeで設定した値をenvironmentで定義した値で上書きすることができる。
  • こちらを参考に。

attributeのみ定義

$ cat recipes/default.rb
puts '##########'
puts "node['env_test']['foo'] is #{node['env_test']['foo']}."
puts '##########'

$ cat attributes/default.rb
default['env_test']['foo'] = "This is foo"

$ kitchen converge
...
##########
node['env_test']['foo'] is This is foo.
##########
...

environment定義後

$ cat environments/development.json
{
  "name": "development",
  "description":"variables depends on environment",
  "chef_type": "environment",
  "json_class": "Chef::Environment",
  "default_attributes": {
    "env_test": {
      "foo": "This is overwritten"
    }
  },
  "override_attributes": {}
}

$ kitchen converge
...
##########
node['env_test']['foo'] is This is overwritten.
##########
...

参考