Chef12対応Chef Workstation構築手順~Bash on Ubuntu on Windows10~

2016年4月に発表された、「Bash on Ubuntu on Windows10」は、Windows10上でubuntu 14.04のバイナリがそのまま動く(ユーザーモード限定ですが)ため、Linux上のアプリケーション開発やクロスプラットフォーム開発がスピーディーに行えるようになる見込みです。ここでは、Windows 10 Pro Insider Priview 14342の上で動くubuntuでChef Workstationを構築してみます。手順自体は本家サイトの手順に従って行います。なお、すでにCentOS7編で詳細なコマンド出力結果は書いていますので、ここではBash on Ubuntu on Windows10特有の出力以外は実行したコマンドだけを記載します。また、Bash on Ubuntu on Windowsの有効化手順はこちらの記事を参照してください。

1. Chef Development Kit (Chef DK)のインストールとユーザー作成

ChefのCookbookを開発するためのSDKやコマンドラインツールがセットになった「Chef Developent Kit」(以下Chef DK)をダウンロードします。そしてRPMコマンドでインストールします。

root@MYCOMPUTER:/ cd /tmp
root@MYCOMPUTER:/tmp# curl -LO "https://packages.chef.io/stable/ubuntu/12.04/chefdk_0.15.15-1_amd64.deb"
  % Total    % Received % Xferd  mAverage Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:--  0:00:01 --:--:--     0
100  134M  100  134M    0     0   638k      0  0:03:35  0:03:35 --:--:--  846k
root@MYCOMPUTER:/tmp# dpkg -i chefdk_0.15.15-1_amd64.deb
(Reading database ... 24998 files and directories currently installed.)
Preparing to unpack chefdk_0.15.15-1_amd64.deb ...
Unpacking chefdk (0.15.15-1) over (0.15.15-1) ...
Setting up chefdk (0.15.15-1) ...
Thank you for installing Chef Development Kit!

dpkgコマンドでのChef DKをインストールする際、30分以上と非常に時間がかかります。その様子はWindowsのタスクマネージャからも見ることができます。

次に、Cookbookの管理などで必要になるgitとunzipをインストールしておきます。

root@MYCOMPUTER:/# apt-get install git unzip
Reading package lists... Done
(以下省略)
Setting up liberror-perl (0.17-1.1) ...
Setting up git-man (1:1.9.1-1ubuntu0.3) ...
Setting up git (1:1.9.1-1ubuntu0.3) ...
Setting up unzip (6.0-9ubuntu1.5) ...

ChefのCookbook作成などの作業には管理者権限は不要なので、開発用の一般ユーザーを作成します。ここではChefにログインするときに作ったユーザーと同じ名前にしておきます。(例では「chef-admin」)

root@MYCOMPUTER:/# useradd -m chef-admin
root@MYCOMPUTER:/# passwd chef-admin
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully

2. Chef開発用ユーザーの環境設定

chef-adminユーザーに切り替えた後、Gitの初期設定を行い、その後Chef DKが正常にインストールされているか確認するコマンドを実行します。以前のCentOS上でのChef Workstation構築の記事ではGitの初期設定をしていませんでしたが、Chef DK 0.15系からはGit初期設定が必要になったようです。設定しないとエラーがたくさん出てしまいます。

root@MYCOMPUTER:/# su - chef-admin
chef-admin@MYCOMPUTER:~$ git config --global user.email "chef-admin@example.local"
chef-admin@MYCOMPUTER:~$ git config --global user.name "Your Name"
chef-admin@MYCOMPUTER:~$ chef verify
Running verification for component 'berkshelf'
Running verification for component 'test-kitchen'
Running verification for component 'tk-policyfile-provisioner'
Running verification for component 'chef-client'
Running verification for component 'chef-dk'
Running verification for component 'chef-provisioning'
Running verification for component 'chefspec'
Running verification for component 'generated-cookbooks-pass-chefspec'
Running verification for component 'rubocop'
Running verification for component 'fauxhai'
Running verification for component 'knife-spork'
Running verification for component 'kitchen-vagrant'
Running verification for component 'package installation'
Running verification for component 'openssl'
Running verification for component 'inspec'
Running verification for component 'delivery-cli'
Running verification for component 'git'
Running verification for component 'opscode-pushy-client'
Running verification for component 'chef-sugar'
Running verification for component 'knife-supermarket'
.......................................................
---------------------------------------------
Verification of component 'rubocop' succeeded.
Verification of component 'kitchen-vagrant' succeeded.
Verification of component 'openssl' succeeded.
Verification of component 'delivery-cli' succeeded.
Verification of component 'test-kitchen' succeeded.
Verification of component 'fauxhai' succeeded.
Verification of component 'inspec' succeeded.
Verification of component 'opscode-pushy-client' succeeded.
Verification of component 'knife-supermarket' succeeded.
Verification of component 'berkshelf' succeeded.
Verification of component 'knife-spork' succeeded.
Verification of component 'git' succeeded.
Verification of component 'tk-policyfile-provisioner' succeeded.
Verification of component 'chef-dk' succeeded.
Verification of component 'chef-sugar' succeeded.
Verification of component 'chef-client' succeeded.
Verification of component 'chefspec' succeeded.
Verification of component 'generated-cookbooks-pass-chefspec' succeeded.
Verification of component 'chef-provisioning' succeeded.
Verification of component 'package installation' succeeded.

ただし、Insider PreviewのバージョンがBuild 14352より古い場合は不具合があり、メモリ確保に失敗した旨のエラーが出てしまいます。執筆時点では修正版がリリースされています。不具合の詳細はGithubのこちらのサイトに記述がありました。

chef-admin@MYCOMPUTER:~$ chef verify
(省略)
/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/mixlib-shellout-2.2.6/lib/mixlib/shellout/unix.rb:338:in `exec': Cannot allocate memory - /opt/chefdk/bin/berks (Errno::ENOMEM)
        from /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/mixlib-shellout-2.2.6/lib/mixlib/shellout/unix.rb:338:in `block in fork_subprocess'
        from /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/mixlib-shellout-2.2.6/lib/mixlib/shellout/unix.rb:316:in `fork'
        from /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/mixlib-shellout-2.2.6/lib/mixlib/shellout/unix.rb:316:in `fork_subprocess'
        from /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/mixlib-shellout-2.2.6/lib/mixlib/shellout/unix.rb:93:in `run_command'
        from /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/mixlib-shellout-2.2.6/lib/mixlib/shellout.rb:259:in `run_command'
        from /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-dk-0.15.15/lib/chef-dk/helpers.rb:30:in `system_command'
        from /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-dk-0.15.15/lib/chef-dk/component_test.rb:117:in `sh'
        from /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-dk-0.15.15/lib/chef-dk/command/verify.rb:96:in `block (3 levels) in <class:Verify>'
        from /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-dk-0.15.15/lib/chef-dk/component_test.rb:165:in `block in tmpdir'
        from /opt/chefdk/embedded/lib/ruby/2.1.0/tmpdir.rb:88:in `mktmpdir'
        from /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-dk-0.15.15/lib/chef-dk/component_test.rb:164:in `tmpdir'
        from /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-dk-0.15.15/lib/chef-dk/command/verify.rb:94:in `block (2 levels) in <class:Verify>'
        from /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-dk-0.15.15/lib/chef-dk/component_test.rb:99:in `instance_eval'
        from /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-dk-0.15.15/lib/chef-dk/component_test.rb:99:in `run_smoke_test'
        from /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-dk-0.15.15/lib/chef-dk/command/verify.rb:580:in `block (2 levels) in invoke_tests'

出力結果の後半で、すべてのコンポーネントの結果が「succeeded」となっていることを確認します。次に、このユーザーでのデフォルトRubyのパスをChef DKと一緒にインストールされているものに設定します。そのためには、~/.bashrcに1行追記し、~/.bashrcの設定を再読み込みします。

$ echo 'eval "$(chef shell-init bash)"' >> ~/.bashrc
chef-admin@MYCOMPUTER:~$ source ~/.bashrc
chef-admin@MYCOMPUTER:~$ which ruby
/opt/chefdk/embedded/bin/ruby

これでchef-adminユーザーのデフォルトrubyがChef DKに同梱されたものになりました。なお、実際に設定される環境変数などを確認すると、以下のようになります。

chef-admin@MYCOMPUTER:~$ chef shell-init bash
export PATH="/opt/chefdk/bin:/home/chef-admin/.chefdk/gem/ruby/2.1.0/bin:/opt/chefdk/embedded/bin:/opt/chefdk/bin:/home/chef-admin/.chefdk/gem/ruby/2.1.0/bin:/opt/chefdk/embedded/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games"
export GEM_ROOT="/opt/chefdk/embedded/lib/ruby/gems/2.1.0"
export GEM_HOME="/home/chef-admin/.chefdk/gem/ruby/2.1.0"
export GEM_PATH="/home/chef-admin/.chefdk/gem/ruby/2.1.0:/opt/chefdk/embedded/lib/ruby/gems/2.1.0"
_chef_comp() {
    local COMMANDS="exec env gem generate shell-init install update push push-archive show-policy diff provision export clean-policy-revisions clean-policy-cookbooks delete-policy-group delete-policy undelete verify"
    COMPREPLY=($(compgen -W "$COMMANDS" -- ${COMP_WORDS[COMP_CWORD]} ))
}
complete -F _chef_comp chef

3. Starter Kitの展開とChef Serverとの接続設定

Chef DKの環境を簡単に整えるために、Chef ServerのWeb管理画面からStarter Kitをダウンロードします。そのために、Web管理画面にログイン後、画面TOPの「Administration」をクリックします。

次に、画面左にある「Organization」をクリック後、表示された組織一覧から前回の記事で作成した組織を選びます。その後、画面左にある「Starter Kit」をクリックします。その後、画面中央に表示される「Download Starter Kit」ボタンをクリックします。

ボタンをクリックすると警告が表示されますが、「Proceed」をクリックしてダウンロードを行います。

ここでダウンロードした「chef-starter.zip」は/mnt/c/Users/(ユーザー名)/Downloads以下にあるのでコピーを行い、unizpコマンドで展開します。

chef-admin@MYCOMPUTER:~$ cp /mnt/c/Users/aniku/Downloads/chef-starter.zip ~
chef-admin@MYCOMPUTER:~$ ls
chef-starter.zip
chef-admin@MYCOMPUTER:~$ unzip -q chef-starter.zip
chef-admin@MYCOMPUTER:~$ ls
chef-repo  chef-starter.zip

ここで作られたchef-repoディレクトリでCookbookを作成できるよう初期化を行います。

chef-admin@MYCOMPUTER:~$ cd chef-repo
chef-admin@MYCOMPUTER:~/chef-repo$ chef generate app chef-repo
Installing Cookbook Gems:
Compiling Cookbooks...
Recipe: code_generator::app
  * directory[/home/chef-admin/chef-repo] action create (up to date)
  * template[/home/chef-admin/chef-repo/.kitchen.yml] action create
    - create new file /home/chef-admin/chef-repo/.kitchen.yml
    - update content in file /home/chef-admin/chef-repo/.kitchen.yml from none to 210d0b
    (diff output suppressed by config)
  * directory[/home/chef-admin/chef-repo/test/integration/default/serverspec] action create
    - create new directory /home/chef-admin/chef-repo/test/integration/default/serverspec
  * directory[/home/chef-admin/chef-repo/test/integration/helpers/serverspec] action create
    - create new directory /home/chef-admin/chef-repo/test/integration/helpers/serverspec
  * cookbook_file[/home/chef-admin/chef-repo/test/integration/helpers/serverspec/spec_helper.rb] action create_if_missing
    - create new file /home/chef-admin/chef-repo/test/integration/helpers/serverspec/spec_helper.rb
    - update content in file /home/chef-admin/chef-repo/test/integration/helpers/serverspec/spec_helper.rb from none to a226b8
    (diff output suppressed by config)
  * template[/home/chef-admin/chef-repo/test/integration/default/serverspec/default_spec.rb] action create_if_missing
    - create new file /home/chef-admin/chef-repo/test/integration/default/serverspec/default_spec.rb
    - update content in file /home/chef-admin/chef-repo/test/integration/default/serverspec/default_spec.rb from none to 1e81da
    (diff output suppressed by config)
  * template[/home/chef-admin/chef-repo/README.md] action create
    - update content in file /home/chef-admin/chef-repo/README.md from 2b98f1 to 6401b8
    (diff output suppressed by config)
  * directory[/home/chef-admin/chef-repo/cookbooks] action create (up to date)
  * directory[/home/chef-admin/chef-repo/cookbooks/chef-repo] action create
    - create new directory /home/chef-admin/chef-repo/cookbooks/chef-repo
  * template[/home/chef-admin/chef-repo/cookbooks/chef-repo/metadata.rb] action create
    - create new file /home/chef-admin/chef-repo/cookbooks/chef-repo/metadata.rb
    - update content in file /home/chef-admin/chef-repo/cookbooks/chef-repo/metadata.rb from none to b8624d
    (diff output suppressed by config)
  * cookbook_file[/home/chef-admin/chef-repo/cookbooks/chef-repo/chefignore] action create
    - create new file /home/chef-admin/chef-repo/cookbooks/chef-repo/chefignore
    - update content in file /home/chef-admin/chef-repo/cookbooks/chef-repo/chefignore from none to e394e1
    (diff output suppressed by config)
  * cookbook_file[/home/chef-admin/chef-repo/cookbooks/chef-repo/Berksfile] action create
    - create new file /home/chef-admin/chef-repo/cookbooks/chef-repo/Berksfile
    - update content in file /home/chef-admin/chef-repo/cookbooks/chef-repo/Berksfile from none to 5ec92e
    (diff output suppressed by config)
  * directory[/home/chef-admin/chef-repo/cookbooks/chef-repo/recipes] action create
    - create new directory /home/chef-admin/chef-repo/cookbooks/chef-repo/recipes
  * template[/home/chef-admin/chef-repo/cookbooks/chef-repo/recipes/default.rb] action create
    - create new file /home/chef-admin/chef-repo/cookbooks/chef-repo/recipes/default.rb
    - update content in file /home/chef-admin/chef-repo/cookbooks/chef-repo/recipes/default.rb from none to 2cdf1a
    (diff output suppressed by config)
  * directory[/home/chef-admin/chef-repo/cookbooks/chef-repo/spec/unit/recipes] action create
    - create new directory /home/chef-admin/chef-repo/cookbooks/chef-repo/spec/unit/recipes
  * cookbook_file[/home/chef-admin/chef-repo/cookbooks/chef-repo/spec/spec_helper.rb] action create_if_missing
    - create new file /home/chef-admin/chef-repo/cookbooks/chef-repo/spec/spec_helper.rb
    - update content in file /home/chef-admin/chef-repo/cookbooks/chef-repo/spec/spec_helper.rb from none to 945e09
    (diff output suppressed by config)
  * template[/home/chef-admin/chef-repo/cookbooks/chef-repo/spec/unit/recipes/default_spec.rb] action create_if_missing
    - create new file /home/chef-admin/chef-repo/cookbooks/chef-repo/spec/unit/recipes/default_spec.rb
    - update content in file /home/chef-admin/chef-repo/cookbooks/chef-repo/spec/unit/recipes/default_spec.rb from none to be7503
    (diff output suppressed by config)
  * execute[initialize-git] action run
    - execute git init .
  * cookbook_file[/home/chef-admin/chef-repo/.gitignore] action create
    - update content in file /home/chef-admin/chef-repo/.gitignore from f7d9f8 to dd37b2
    (diff output suppressed by config)

次に、秘密鍵などが保管されている.chefディレクトリをgit管理対象外にするための設定を行います。

$ echo '.chef' >> ~/chef-repo/.gitignore 

最後にChef ServerのSSL証明書(自己証明書)を信頼するよう設定します。前提条件として、Chef Serverの名前解決ができることと、~/chef-repo/.chef/knife.rbに書かれているChef ServerのURLが正しいこと(ホスト名がFQDNになっているかなど)を確認しておきます。また、このコマンドも非常に長い時間がかかります(2016/7/18追記:Windows10 build 14390にアップデート後、時間がかからず完了するようになりました。)

root@MYCOMPUTER:/home/chef-admin/chef-repo# knife ssl fetch
WARNING: Certificates from chefserver will be fetched and placed in your trusted_cert
directory (/home/chef-admin/chef-repo/.chef/trusted_certs).

Knife has no means to verify these are the correct certificates. You should
verify the authenticity of these certificates after downloading.

Adding certificate for chefserver in /home/chef-admin/chef-repo/.chef/trusted_certs/chefserver.crt

以上で、Chef DKの環境が整いました。

4. Chef Serverとの接続確認

~/chef-repoディレクトリ以下でknifeコマンドを実行することで、Chef Serverと接続でき、クライアントや管理者ユーザーのリストが取得できることを確認します。

$ knife user list
chef-admin
$ knife client list
takanyan-validator

以上で、一般的なBash on Ubuntu on Windows環境内にChef Workstation環境が出来上がりました。ただ、時間がかかりすぎて今はまだ実運用までたどり着けない、かもしれません・・・(2016/7/18追記:Windows 10 Build 14390以降はスムーズに実行されるようになりました。使える、かもしれません!)