Chef Server/DK (Workstation)を1台のマシンにインストールする (Chef12)

## 目的、前提条件
* 有償版、hostedは使わず、OSS(Basics)で頑張りたい人向け
    - [https://www.chef.io/pricing/](https://www.chef.io/pricing/)
* Chef ServerとChef DKを同一サーバに同居させ節約
* 複数プロジェクトを共存させるため、organizationを分割（1プロジェクトだけでもOK）
* 有償になったアドオン部分は使わない方向で
* CentOS6.8で構築してる

## Chef Serverのインストール

* chef操作系のユーザを作成し、recipeの格納先ディレクトリを用意する

```
sudo groupadd -g 10001 chef_admin
sudo useradd -g chef_admin -u 10001 chef_admin
sudo sh -c "echo 'chef_admin ALL=(ALL)NOPASSWD: ALL' > /etc/sudoers.d/chef_admin"

sudo mkdir -p /data/chef/
sudo chown -P chef_admin.chef_admin /data/chef/
```

* chef-serverインストール
    - [https://downloads.chef.io/chef-server/](https://downloads.chef.io/chef-server/)

```
sudo yum install -y https://packages.chef.io/stable/el/6/chef-server-core-12.8.0-1.el6.x86_64.rpm
```

* 操作用鍵のGenerate (1プロジェクトの場合は1つだけ生成)

```
sudo su - chef_admin

sudo chef-server-ctl reconfigure
mkdir ~/.ssh
sudo chef-server-ctl user-create chef_admin chef_admin chef_admin chef_admin@example.com 'chef_admin' --filename ~/.ssh/chef_admin.pem
sudo chef-server-ctl org-create project1 project1 --association_user chef_admin --filename ~/.ssh/project1-validator.pem
sudo chef-server-ctl org-create project2 project2 --association_user chef_admin --filename ~/.ssh/project2-validator.pem
sudo chef-server-ctl org-create project3 project3 --association_user chef_admin --filename ~/.ssh/project3-validator.pem
```

## Chef DK インストール （旧workstation的な）

https://docs.chef.io/install_dk.html#manually-w-o-webui
http://www.creationline.com/lab/6255

* Chef DKインストール
    - [https://downloads.chef.io/chef-dk/](https://downloads.chef.io/chef-dk/)

```
sudo yum install -y https://packages.chef.io/stable/el/6/chefdk-0.16.28-1.el6.x86_64.rpm
chef verify
echo 'eval "$(chef shell-init bash)"' >> ~/.bash_profile
source ~/.bash_profile
```

## Knife Commandでコンフィグと操作用鍵生成
* まずは格納用ディレクトリを作る

```
mkdir -p /data/chef/project1/.chef
mkdir -p /data/chef/project2/.chef
mkdir -p /data/chef/project3/.chef
```

* 操作用鍵を各位置に配置

```
sudo cp -p ~/.ssh/project1-validator.pem /data/chef/project1/.chef/
sudo cp -p ~/.ssh/project2-validator.pem /data/chef/project2/.chef/
sudo cp -p ~/.ssh/project3-validator.pem /data/chef/project3/.chef/
sudo cp -p ~/.ssh/chef_admin.pem /data/chef/project1/.chef/
sudo cp -p ~/.ssh/chef_admin.pem /data/chef/project2/.chef/
sudo cp -p ~/.ssh/chef_admin.pem /data/chef/project3/.chef/
```

* knife configure (project1)

```
knife configure
Where should I put the config file? [/home/chef_admin/.chef/knife.rb]
/data/chef/project1/.chef/knife.rb
Please enter the chef server URL: [https://CHEF-SERVER-URL:443]
https://CHEF-SERVER-URL/organizations/project1
Please enter an existing username or clientname for the API: [user]
chef_admin
Please enter the validation clientname: [chef-validator]
project1-validator
Please enter the location of the validation key: [/etc/chef-server/chef-validator.pem]
/data/chef/project1/.chef/project1-validator.pem
Please enter the path to a chef repository (or leave blank):
/data/chef/project1

cd /data/chef/project1/

knife ssl fetch
knife ssl check

knife client list
とかで動作確認
```

* knife configure (project2)

```
knife configure
Where should I put the config file? [/home/chef_admin/.chef/knife.rb]
/data/chef/project2/.chef/knife.rb
Please enter the chef server URL: [https://CHEF-SERVER-URL:443]
https://CHEF-SERVER-URL/organizations/project2
Please enter an existing username or clientname for the API: [user]
chef_admin
Please enter the validation clientname: [chef-validator]
project2-validator
Please enter the location of the validation key: [/etc/chef-server/chef-validator.pem]
/data/chef/project2/.chef/project2-validator.pem
Please enter the path to a chef repository (or leave blank):
/data/chef/project2

cd /data/chef/project2/

knife ssl fetch
knife ssl check

knife client list
とかで動作確認
```

* knife configure (project3)

```
knife configure
Where should I put the config file? [/home/chef_admin/.chef/knife.rb]
/data/chef/project3/.chef/knife.rb
Please enter the chef server URL: [https://CHEF-SERVER-URL:443]
https://CHEF-SERVER-URL/organizations/project3
Please enter an existing username or clientname for the API: [user]
chef_admin
Please enter the validation clientname: [chef-validator]
project3-validator
Please enter the location of the validation key: [/etc/chef-server/chef-validator.pem]
/data/chef/project3/.chef/project3-validator.pem
Please enter the path to a chef repository (or leave blank):
/data/chef/project3

cd /data/chef/project3/

knife ssl fetch
knife ssl check

knife client list
とかで動作確認
```

## chef用repositoryを準備

* 新規にリポジトリ立てるときは、generateコマンドでひな形を出力 -> githubなどで管理

```
cd /data/chef
chef generate repo project1
chef generate repo project2
chef generate repo project3
```

* 既存でgithubにリポジトリがある場合は、各リポジトリをcloneする

```
cd /data/chef/project1
git clone git@github.com:project1/chef.git ./.

cd /data/chef/project2
git clone git@github.com:project2/chef.git ./.

cd /data/chef/project3
git clone git@github.com:project3/chef.git ./.
```

### client側設定（organizationがproject1のとき）

* 以下の様なスクリプトで一気に設定すると楽

```

mkdir -p /etc/chef/trusted_certs/

cat <<'EOF' >/etc/chef/client.rb
## https://CHEF-SERVER-URL:443
chef_server_url 'https://CHEF-SERVER-URL/organizations/project1'
ssl_verify_mode        :verify_none
log_level              :info
validation_client_name "project1-validator"
EOF

echo node_name "'"`hostname`"'" >> /etc/chef/client.rb


cat <<'EOF' >/etc/chef/validation.pem
-----BEGIN RSA PRIVATE KEY-----
※※ サーバ側 project1-validator.pemの内容 ※※
-----END RSA PRIVATE KEY-----
EOF

cat <<'EOF' >/etc/chef/trusted_certs/CHEF-SERVER-URL.crt
-----BEGIN CERTIFICATE-----
※※ サーバ側 /home/chef_admin/.chef/trusted_certs/CHEF-SERVER-URL.crtの内容 ※※
-----END CERTIFICATE-----
EOF

# Chef-Clientのログローテート
cat <<'EOF' >/etc/logrotate.d/chef-client
/var/log/chef-client.log {
        compress
        rotate 4
        size 5M
        missingok
        notifempty
        nocreate
}
EOF

yum install -y https://packages.chef.io/stable/el/6/chef-12.12.15-1.el6.x86_64.rpm
```


## おまけ
### chef-client実行時にこんなエラー出るとき

```
Running handlers:
[2016-05-31T17:56:28+09:00] ERROR: Running exception handlers
Running handlers complete
[2016-05-31T17:56:28+09:00] ERROR: Exception handlers complete
Chef Client failed. 22 resources updated in 11 seconds
[2016-05-31T17:56:28+09:00] FATAL: Stacktrace dumped to /data/chef/cache/chef-stacktrace.out
[2016-05-31T17:56:28+09:00] FATAL: Please provide the contents of the stacktrace.out file if you file a bug report
[2016-05-31T17:56:28+09:00] ERROR: 403 "Forbidden"
[2016-05-31T17:56:29+09:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)
[root@test-tmp ~]#
```

* デフォルトだと、何故かclient側からserverへのnode情報のupdate権限がついていない

公式だと、Chef management console使う方法しか書いてないし、
[https://docs.chef.io/errors.html#forbidden](https://docs.chef.io/errors.html#forbidden)
そもそもChef management consoleでやるのは、1node単位なので解決になっていないような

バカバカしいので、chef server側にknife-aclを使って一気に権限をなおす
[https://getchef.zendesk.com/hc/en-us/articles/206435493-I-Want-to-Update-Existing-Node-Data-Using-New-Clients](https://getchef.zendesk.com/hc/en-us/articles/206435493-I-Want-to-Update-Existing-Node-Data-Using-New-Clients)

```
chef gem install knife-acl
knife acl add group clients containers nodes update

## すでに存在しているnodeへのupdate権限追加は
## knife acl bulk add group clients nodes '.*' update
```