成らぬは人の為さぬなりけり

エンジニアライフをエンジョイする為のブログ

Chef-solo+knife-solo+Vagrantでサーバ構築を自動化してみる - その1 ユーザー追加

本日(8/24)、LL祭りで、
Inftastructure as LLというセッションを見てきました。
最近、Chef-solo+knife-soloをいろいろいじっていたので、今日は一番興味深いセッションでした。

いい機会なので、最近自分がChef+Vagrantでやった事を、メモしていきたいと思います。

環境

  • Chef 11.6.0
  • knife-solo 0.3.0
  • Vagrant 1.2.2
  • GuestOS ubuntu 13.04

今回の流れ

※各種インストールに関しては参考サイトにお任せします。
Chef Soloと Knife Soloでの ニコニコサーバー構築 (2) 〜導入編〜:dwango エンジニア ブロマガ:ドワンゴ研究開発チャンネル(ドワンゴグループのエンジニア) - ニコニコチャンネル:生活
Chef Soloの正しい始め方 | tsuchikazu blog
開発メモ#5 : Amazon Linux で knife-solo を使って chef-solo 実行 - naoyaのはてなダイアリー

  1. 今回の環境の各種設定を晒してみる
  2. chefリポジトリ(kitchen?)を作る
  3. ユーザー追加のレシピを書く
  4. kife-soloでサーバに適用する
  5. レシピでやってる事をリソース化する
  6. もっかい適用してみる(結果が変わらない事を確認)
  7. おまけ

今回の環境の各種設定を晒してみる

Gemfile

chefはrubyのgemになっているので、bundlerで管理する為にGemfileを書きました。

source 'http://rubygems.org'

gem 'chef'
gem 'knife-solo', '~> 0.3.0.pre3'
gem 'berkshelf'

Vagrantfile

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu13.04"

  config.vm.network :private_network, ip: "192.168.33.10"

  config.vm.provider :virtualbox do |vb|
    vb.customize ["modifyvm", :id, "--memory", "2048", "--cpus", "2"]
  end
end

今回はVMのIPを192.168.33.10に固定しました。

chefリポジトリ(kitchen?)を作る

では早速、chefっていきます。
※詳しい内容は参考サイトにお任せします。

$ bundle exec knife solo init chef-repo 
Creating kitchen...
Creating knife.rb in kitchen...
Creating cupboards...
Setting up Berkshelf...
$ cd chef-repo

ユーザー追加のレシピを書く

というわけで、早速書いてみます。
で、まずはcookbookを作ります。

$ bundle exec knife cookbook create users -o site-cookbooks 
** Creating cookbook users
** Creating README for cookbook: users
** Creating CHANGELOG for cookbook: users
** Creating metadata for cookbook: users

ユーザーを追加するレシピなのでusersというクックブックを作りました。

ではレシピを書いていきます。
今回はdefaultのレシピとして、書きますが、
本当は追加なので、addとかのレシピにした方が良いのかな、とか思ってます。
( recipe[users::add]みたいな)

site-cookbooks/users/recipes/default.rbを編集します。

group 'deploy' do
  group_name 'deploy'
  gid 999
  action :create
end

user 'deploy' do
  comment 'deploy user'
  group 'deploy'
  home '/home/deploy'
  shell '/bin/bash'
  supports :manage_home => true
  action :create
end

OK。じゃあここまで実行してみます!

ではVagrantでVM起動して、knife-soloでchef-soloをインストールさせて、レシピを実行します。
(今回は~/.ssh/configでVMにchef-testという名前をつけました)

$ vagnrant up
Bringing machine 'default' up with 'virtualbox' provider...
[default] Importing base box 'ubuntu13.04'...
[default] Matching MAC address for NAT networking...
[default] Setting the name of the VM...
[default] Clearing any previously set forwarded ports...
[default] Creating shared folders metadata...
[default] Clearing any previously set network interfaces...
[default] Preparing network interfaces based on configuration...
[default] Forwarding ports...
[default] -- 22 => 2222 (adapter 1)
[default] Running any VM customizations...
[default] Booting VM...
[default] Waiting for VM to boot. This can take a few minutes.
[default] VM booted and ready for use!
[default] Configuring and enabling network interfaces...
[default] Mounting shared folders...
[default] -- /vagrant
$ bundle exec knife solo prepare chef-test
Bootstrapping Chef...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  6790  100  6790    0     0   1158      0  0:00:05  0:00:05 --:--:--  8161
Downloading Chef 11.6.0 for ubuntu...
^[[DInstalling Chef 11.6.0
(Reading database ... 65296 files and directories currently installed.)
Preparing to replace chef 10.12.0-3 (using .../chef_11.6.0_amd64.deb) ...
 * Stopping chef-client chef-client                                      [ OK ] 
Unpacking replacement chef ...
dpkg: warning: unable to delete old directory '/etc/chef': Directory not empty
dpkg: warning: unable to delete old directory '/var/log/chef': Directory not empty
Setting up chef (11.6.0-1.ubuntu.13.04) ...
Thank you for installing Chef!
Processing triggers for ureadahead ...
Processing triggers for man-db ...
Generating node config 'nodes/chef-test.json'...

ここで、nodesディレクトリ配下にjsonファイルが出来たので、
chef-test.jsonを編集します。

{
    "run_list":[
        "recipe[users]"
    ]
}
$ bundle exec knife solo cook chef-test  
..省略..
Converging 2 resources
Recipe: users::default
  * group[deploy] action create
    - create group[deploy]

  * user[deploy] action create
    - create user user[deploy]

Chef Client finished, 2 resources updated

うまく行ったっぽい感じです。
確認してみましょう。

$ ssh chef-test
$ id deploy
uid=1002(deploy) gid=999(deploy) groups=999(deploy)
$ ls -al /home/deploy/
total 20
drwxr-xr-x 2 deploy deploy 4096 Aug 24 14:14 .
drwxr-xr-x 5 root   root   4096 Aug 24 14:14 ..
-rw-r--r-- 1 deploy deploy  220 Mar 30 15:37 .bash_logout
-rw-r--r-- 1 deploy deploy 3637 Mar 30 15:37 .bashrc
-rw-r--r-- 1 deploy deploy  675 Mar 30 15:37 .profile

ちゃんとユーザーが追加されました。

では、ついでに公開鍵の登録もやってしまいましょう。

site-cookbooks/users/recipes/default.rbを編集します。

group 'deploy' do
  group_name 'deploy'
  gid 999
  action :create
end

user 'deploy' do
  comment 'deploy user'
  group 'deploy'
  home '/home/deploy'
  shell '/bin/bash'
  supports :manage_home => true
  action :create
end

# 以下を追加
directory "/home/deploy/.ssh/" do
  owner 'deploy'
  group 'deploy'
  mode 0755
end

cookbook_file "/home/#{params[:name]}/.ssh/authorized_keys" do
  owner params[:name]
  mode 0600
  source "#{params[:name]}.authorized_keys"
end

site-cookbooks/users/files/default/deploy.authorized_keysに公開鍵を書いたファイルを用意しました。

ではもう一回chefってみます。

$ bundle exec knife solo cook chef-test
.. 省略 ..
Converging 4 resources
Recipe: users::default
  * group[deploy] action create (up to date)
  * user[deploy] action create (up to date)
  * directory[/home/deploy/.ssh/] action create
    - create new directory /home/deploy/.ssh/
    - change mode from '' to '0755'
    - change owner from '' to 'deploy'
    - change group from '' to 'admin'

  * file[/home/deploy/.ssh/authorized_keys] action create
    - create new file /home/deploy/.ssh/authorized_keys
    - update content in file /home/deploy/.ssh/authorized_keys from none to 4d65e9
        --- /home/deploy/.ssh/authorized_keys	2013-08-24 14:31:27.907907024 +0000
        +++ /tmp/.authorized_keys20130824-8101-ibsszv	2013-08-24 14:31:27.907907024 +0000
        @@ -0,0 +1 @@
(公開鍵)
    - change mode from '' to '0600'
    - change owner from '' to 'deploy'
Chef Client finished, 2 resources updated

サーバにログインして確認してみましょう。
多分できてるはず。

レシピでやってる事をリソース化する

ここまでdeployユーザの設定はできましたが、
じゃあ、次、yagiっていうユーザー追加してよ。みたいな話になった場合、
ちゃんとDRYに書きたいですよね。
なので、こいつらをリソース化して使いまわせるようにしてみます。
今回はDefinitionを使ってResourceを定義します。

site-cookbooks/users/definitions/create_user.rbを作成します。

define :create_user, :group => 'admin' do
  user params[:name] do
    comment "#{params[:name]} user"
    group params[:group]
    home "/home/#{params[:name]}"
    shell '/bin/bash'
    supports :manage_home => true
    action :create
  end

  directory "/home/#{params[:name]}/.ssh/" do
    owner params[:name]
    group params[:group]
    mode 0755
  end

  cookbook_file "/home/#{params[:name]}/.ssh/authorized_keys" do
    owner params[:name]
    mode 0600
    source "#{params[:name]}.authorized_keys"
  end
end

site-cookbooks/users/recipes/default.rbを編集します。

group 'deploy' do
  group_name 'deploy'
  gid 999
  action :create
end

create_user 'deploy' do
  group 'deploy'
end

これで、再実行すればOKです。

  1. おまけ

ついでに、複数のユーザを登録できるように変えてみます。
site-cookbooks/users/recipes/default.rbを編集します。

group 'deploy' do
  group_name 'deploy'
  gid 999
  action :create
end

node['users'].each{|user|
  create_user user['name'] do
    group user['group'] # グループは先に作成しとかなきゃいけないけど、それはまた今度
  end
}

nodes/chef-test.jsonを編集します。

{
    "users": [
        { "name": "yagi", "group": "deploy"},
        { "name": "deploy", "group": "deploy"}
    ],
    "run_list":[
        "recipe[users]"
    ]
}

最後に、deployユーザーと同じように
site-cookbooks/users/files/default/yagi.authorized_keysを作っておきます。
これで再実行すれば、yagiユーザも出来たはずです。

$ id yagi
uid=1003(yagi) gid=999(deploy) groups=999(deploy)

次回は

sudoersをいじってみたいと思います。

毎度の事ですが、エントリーの内容が長いですね、、、
メモなので、ご容赦下さい・・・


入門Chef Solo - Infrastructure as Code

入門Chef Solo - Infrastructure as Code

5000部くらい売れてるらしいです。すごい。