[CentOS6][Chef] ChefでLAMP構成をつくる9 - OSアカウントの作成


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のテストケースの書き方は、以下を参考にしました。

今回使用する管理対象のノードは、前回までのレシピを実行した状態になっています。OSのアカウントは root しかありません。
そこで、今回作成する新しいレシピを実行することで、管理対象ノードに新しいグループとユーザを作成します。
なお、今回作成するレシピは、users の名称で、新しい Cookbook にします。
また、作成するグループとユーザは、Databag に登録し、レシピから Databag を参照して、ユーザの登録/削除を行うようにします。

1.Databag 作成


Databag にグループとユーザを登録するのに WebUI を使用したかったのですが、バグがあって使えませんでした。
なので、管理サーバのワークステーションで json データを作成して、knife コマンドで登録します。
Databag は名前を付けて複数持つことができ、それぞれのDatabag が複数のDatabagItemを持つことができます。
今回は、以下のような構成で Databag を作ります。
users ・・・ Databag
   ┗  appuser   ・・・  DatabagItem
まず、DatabugItem 用のjsonデータを格納するディレクトリを用意します。
$ 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.json
WebUIで見ると下図のとおり。
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
Databag に定義したグループとユーザを参照して、OSアカウントを作成/削除します。
内容は以下のとおり。
#
# 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

end
Chefspecのテストケースを実行してレシピをチェックします。
結果が、以下のように "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: そのようなユーザは存在しません