Create: 2013/08/01
LastUpdate: 2013/08/13
ここでは、Chef11を使用して、段階的にLAMP環境を構築していきます。
今回は、前回の「 [CentOS6][Chef] ChefでLAMP構成をつくる8 - MySQLのユーザとDB作成」に引き続き、OSアカウントを作成するレシピを追加します。
Chef11のテスト環境の詳細については、「メニュー」を参照してください。
[テスト環境]
- 管理サーバ
192.168.1.67(chetos6g) ・・・ Chefサーバ + ワークステーション - 管理対象
192.168.1.68(centos6h) ・・・ ノード
前回同様、テスト駆動開発のように、まずテストケースを作成してからレシピを作成し、実際にノードで実行する前に Cookbook が期待する動作を行うかテストすることにします。
Chefのレシピの書き方や、Chefspecのテストケースの書き方は、以下を参考にしました。
- 入門Chef Solo - Infrastructure as Code を読みながらChef Soloで遊べるようになるまで
- Cookbookテストフレームワーク「ChefSpec」
- chefspecチートシート
- Cucumber, ChefSpecとchefでテスト駆動のサーバ構築管理
- [chef] data bag活用法
今回使用する管理対象のノードは、前回までのレシピを実行した状態になっています。OSのアカウントは root しかありません。
そこで、今回作成する新しいレシピを実行することで、管理対象ノードに新しいグループとユーザを作成します。
なお、今回作成するレシピは、users の名称で、新しい Cookbook にします。
また、作成するグループとユーザは、Databag に登録し、レシピから Databag を参照して、ユーザの登録/削除を行うようにします。
1.Databag 作成
Databag にグループとユーザを登録するのに WebUI を使用したかったのですが、バグがあって使えませんでした。
なので、管理サーバのワークステーションで json データを作成して、knife コマンドで登録します。
Databag は名前を付けて複数持つことができ、それぞれのDatabag が複数のDatabagItemを持つことができます。
今回は、以下のような構成で Databag を作ります。
users ・・・ Databag
┗ appuser ・・・ DatabagItem
まず、DatabugItem 用のjsonデータを格納するディレクトリを用意します。┗ appuser ・・・ DatabagItem
$ cd ~/chef-repo/data_bags $ mkdir users"users" ディレクトリに、"appuser.json" の名称でファイルを作成します。
内容は以下のとおり。
{ "groups":[ { "action": "create", "name": "appgrp", "uid": 10001 } ], "users":[ { "action": "create", "name": "user01", "password": "$1$ziLdcBJJ$8wCrrrrN9.NqKi6NGfgvs0", "uid": 10001, "gid": 10001, "shell": "/bin/bash" }, { "action": "create", "name": "user02", "password": "$1$ziLdcBJJ$8wCrrrrN9.NqKi6NGfgvs0", "uid": 10002, "gid": 10001, "shell": "/bin/bash" } ], "id": "appuser" }上記では、グループ1つと、ユーザ2つを定義しており、それぞれ、レシピに必要な属性情報(ID、パスワードなど)を定義しています。
属性情報の"action" が "create" なら登録し、"remove" なら削除します。
属性情報の"password" は、暗号化(SHA-512)しておきます。以下の例では、"password" を暗号化しています。
$ openssl passwd -1 'password' $1$ziLdcBJJ$8wCrrrrN9.NqKi6NGfgvs0データができたので、Chefサーバーにアップロードします。
まず、Databag を作成します。
$ knife data bag create users次に、DatabagItem の appuser.json をアップロードします。修正したデータをアップロードする場合も同じようにコマンドを実行します。
$ knife data bag from file users appuser.jsonWebUIで見ると下図のとおり。
Databag の一覧です。
"users" の DatabagItem です。
"appuser" のデータです。
2.Cookbook 作成
以下、管理サーバに chefユーザでログインして、Chefのワークステーションで作業します。
2.1.ひな形の作成
今回、"users" という名称で新しくcookbookを作成するので、ひな形を用意します。
$ cd ~/chef-repo/cookbooks $ knife cookbook create users $ knife cookbook create_specs users
2.2.Chefspec のテストケース追加
以下のファイルにChefspecのテストケースを作成します。
- ~/chef-repo/cookbooks/users/spec/default_spec.rb
require 'chefspec' Chef::Config[:data_bag_path] = '/home/chef/chef-repo/data_bags'; describe 'users::default' do let (:chef_run) { ChefSpec::ChefRunner.new.converge 'users::default' } it "shold create group" do expect(chef_run).to create_group "appgrp" end it "shold create user" do expect(chef_run).to create_user "app01" expect(chef_run).to create_user "app02" end end上記1で作成した Databag のJSONデータファイルの格納場所を指定して、Databag に定義した グループ1つと、ユーザ2つを作成しているかチェックします。
2.3.レシピ修正
以下のファイルにレシピを作成します。
- ~/chef-repo/cookbooks/users/recipes/default.rb
内容は以下のとおり。
# # Cookbook Name:: users # Recipe:: default # # Copyright 2013, YOUR_COMPANY_NAME # # All rights reserved - Do Not Redistribute # # Group add / delete for d in data_bag_item('users','appuser')['groups'] group d["name"] do gid d["id"] action d["action"] end end # User add / delete for d in data_bag_item('users','appuser')['users'] home_dir = "/home/" + d["name"] user d["name"] do password d["password"] uid d["uid"] gid d["gid"] shell d["shell"] home home_dir action d["action"] end endChefspecのテストケースを実行してレシピをチェックします。
結果が、以下のように "0 failures" であればOKです。
$ cd ~/chef-repo/cookbooks $ rspec -fd --color users users::default shold create group shold create user Finished in 0.01714 seconds 2 examples, 0 failures
2.4.metadata の変更
以下のファイルを修正して Cookbookの metadata 変更します。
- ~/chef-repo/cookbooks/users/metadata.rb
name 'users' maintainer 'blue21' maintainer_email 'canopus@blue21.ddo.jp' license 'All rights reserved' description 'Installs/Configures users' long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) version '0.1.0'Foodcritic で Cookbookの全体的なチェック(文法、矛盾など)をします。
以下のように何も表示されなければOKです。
$ cd ~/chef-repo/cookbooks $ foodcritic ./users
2.5.CookbookをChefサーバに登録
作成した Cookbook をChefサーバにアップロードします。
$ cd ~/chef-repo/cookbooks $ knife cookbook upload users Uploading users [0.1.0] Uploaded 1 cookbook.
3.ノードの Run List にレシピを追加
前回までは、WebGUI を使用していましたが、今回は、knifeコマンドを使用してみます。
管理サーバのワークステーションで以下のように実行します。
$ knife node run_list add centos6h 'recipe[users]' centos6h: run_list: role[LAMP] recipe[mysql::database] recipe[users]"centos6h" はノード名、"recipe[users]" はレシピ名です。
4.ノードでレシピの実行
管理対象のノードに、root ユーザでログインして作業します。
以下のようにコマンドを実行して、レシピを実行します。
# /opt/chef/bin/chef-client Starting Chef Client, version 11.4.4 resolving cookbooks for run list: ["apache", "php", "mysql", "mysql::database", "users"] Synchronizing Cookbooks: - users - mysql - apache - php Compiling Cookbooks... Recipe: mysql::database * chef_gem[ruby-mysql] action install (up to date) Converging 19 resources Recipe: apache::default * package[httpd] action install (up to date) * template[/etc/httpd/conf/httpd.conf] action create (up to date) * service[httpd] action enable (up to date) * service[httpd] action start (up to date) Recipe: php::default * package[php] action install (up to date) * package[php-mysql] action install (up to date) * package[php-mbstring] action install (up to date) * package[php-gd] action install (up to date) * template[/etc/php.ini] action create (up to date) Recipe: mysql::default * package[mysql] action install (up to date) * package[mysql-server] action install (up to date) * template[/etc/my.cnf] action create (up to date) * service[mysqld] action enable (up to date) * service[mysqld] action start (up to date) Recipe: mysql::database * link[/tmp/mysql.sock] action create (up to date) * chef_gem[ruby-mysql] action install (up to date) * mysql_database[appdb] action create (up to date) * mysql_database_user[app_user] action create (up to date) * mysql_database_user[app_user] action grant Recipe: users::default * group[appgrp] action create - create group[appgrp] * user[app01] action create - create user user[app01] * user[app02] action create - create user user[app02] Chef Client finished, 4 resources updated適用済みのレシピは、何も行われていません。(up to date)
グループとユーザが作成されたことが確認できます。
作成したアカウントを確認してみます。
# id app01 uid=10001(app01) gid=10001(appgrp) 所属グループ=10001(appgrp) # id app02 uid=10002(app02) gid=10001(appgrp) 所属グループ=10001(appgrp) # ls /home app01 app02こんどは、ユーザの削除を試してみます。
Databag の ユーザ(app02) の "action" を "remove" に変更します。
再度、レシピを実行します。
# /opt/chef/bin/chef-client Starting Chef Client, version 11.4.4 resolving cookbooks for run list: ["apache", "php", "mysql", "mysql::database", "users"] Synchronizing Cookbooks: - users - mysql - apache - php Compiling Cookbooks... Recipe: mysql::database * chef_gem[ruby-mysql] action install (up to date) Converging 19 resources Recipe: apache::default * package[httpd] action install (up to date) * template[/etc/httpd/conf/httpd.conf] action create (up to date) * service[httpd] action enable (up to date) * service[httpd] action start (up to date) Recipe: php::default * package[php] action install (up to date) * package[php-mysql] action install (up to date) * package[php-mbstring] action install (up to date) * package[php-gd] action install (up to date) * template[/etc/php.ini] action create (up to date) Recipe: mysql::default * package[mysql] action install (up to date) * package[mysql-server] action install (up to date) * template[/etc/my.cnf] action create (up to date) * service[mysqld] action enable (up to date) * service[mysqld] action start (up to date) Recipe: mysql::database * link[/tmp/mysql.sock] action create (up to date) * chef_gem[ruby-mysql] action install (up to date) * mysql_database[appdb] action create (up to date) * mysql_database_user[app_user] action create (up to date) * mysql_database_user[app_user] action grant Recipe: users::default * group[appgrp] action create (up to date) * user[app01] action create (up to date) * user[app02] action remove - remove user user[app02] Chef Client finished, 2 resources updatedユーザの app02 が削除されたようです。
一応、ユーザの有無を確認してみます。
# id app02 id: app02: そのようなユーザは存在しません