Edited at

ChefDKに含まれるtest-kitchenによるリモートノードへのChef適用

リモート・ノードにChefレシピを適用するには、Chef Serverを使用する方法や、Knife-Zeroを使う方法などがある。

それらを使用しなくとも、ChefDKに含まれるtest-kitchenを用いる事で、リモート・ノードへのChef適用やInSpecテスト実行が可能である。

必要なものはChefDKに入っているのでとてもお手軽。


前提


  • ローカルマシンにChefDKが導入されている。(検証はMacで実施)

  • ローカルマシンからリモートマシンにsshで接続が可能

  • リモートマシンがインターネットに接続されていないならば、Chefクライアントが導入されている。


設定

ほぼ.kitchen.ymlを編集するだけ。

ChefDK導入済みの状態から開始。

まず、クックブックの作成、レシピ、テストの用意、test-kitchenの設定を行う。

$ chef generate cookbook manage_existing_servers

...
$ cd manage_existing_servers/
$ vi recipes/default.rb
...
$ mkdir -p test/integration/default
$ vi test/integration/default/default_test.rb
...
$ vi .kitchen.yml
...


Chefレシピ例


recipes/default.rb

file '/tmp/test.txt' do

content "hello world.\n"
end


InSpecテスト例


test/integration/default/default_test.rb

describe file('/tmp/test.txt') do

its(:content) { should match %r(^hello world\.$) }
end


test-kitchen設定例


.kitchen.yml

---

provisioner:
name: chef_zero
always_update_cookbooks: true
#require_chef_omnibus: false # 古い書式
product_name: chef # 新しい書式
install_strategy: skip # 新しい書式
sudo: false
client_rb: # AIXの場合の問題対応
'Chef::Config[:follow_client_key_symlink] =': true

verifier:
name: inspec
sudo: false
inspec_tests:
- test/integration/default

platforms:
- name: aix
run_list:
- recipe[manage_existing_servers::default]

suites:
<%
%w(p8126a p8127a).each do |host|
%>
- name: <%= host %>
driver:
name: proxy
host: <%= host %>
ssh_key: ~/.ssh/id_rsa
sudo: false
reset_command: 'exit 0'
<%
end
%>



  • .kitchen.ymlは、最初に、Chefのtemplateリソースでも使用しているERBとして処理されるので、Rubyによる値の設定が可能。ここでは、ループで回して2ノード分の構成としている。

  • driver:の設定内容を相手毎に変えたいので、suites:の各要素下に移動。

  • vagrantドライバーの代わりに稼働し続けるノード用のproxyドライバーを設定。(参照1,4,6)

  • p8126a p8127aは、ssh接続可能なサーバー。この例では、これらのサーバーに対するssh接続情報は、~/.ssh/configにて設定しているので、.kitchen.ymlでは基本的にhost:のみ設定。

  • ただし、ssh_key: ~/.ssh/id_rsa は、InSpecの為に必要であったので記載している。

  • reset_command: 'exit 0'は、参照4より

  • sudo: false は、対象サーバーにsudoが無くrootで接続する為。

  • require_chef_omnibus: false は、対象サーバーがインターネット接続されていない為。なお、Chef Clientは事前に導入済み。=> product_name: chef, install_strategy: skip に置き換え。

  • client.rbはAIXと特定のchef-clientの組み合わせ時の問題回避 (参照7)


初期状態

$ kitchen list 

Instance Driver Provisioner Verifier Transport Last Action Last Error
p8126a-aix Proxy ChefZero Inspec Ssh <Not Created> <None>
p8127a-aix Proxy ChefZero Inspec Ssh <Not Created> <None>

Last Actionの<Not Created>に注目。

未作成状態。

ただし、実機は構成され稼働している。


作成(ダミー)

$ kitchen create 

-----> Starting Kitchen (v1.17.0)
-----> Creating <p8126a-aix>...
Resetting instance state with command: exit 0
Finished creating <p8126a-aix> (0m0.42s).
-----> Creating <p8127a-aix>...
Resetting instance state with command: exit 0
Finished creating <p8127a-aix> (0m0.40s).
-----> Kitchen is finished. (0m3.04s)

$ kitchen list 

Instance Driver Provisioner Verifier Transport Last Action Last Error
p8126a-aix Proxy ChefZero Inspec Ssh Created <None>
p8127a-aix Proxy ChefZero Inspec Ssh Created <None>

createを行うと、作成したつもりになるが、実際には予め構成され稼働している。


リモート・サーバーにChefレシピを反映

$ kitchen converge

-----> Starting Kitchen (v1.17.0)
-----> Converging <p8126a-aix>...
$$$$$$ Running legacy converge for 'Proxy' Driver
Preparing files for transfer
Preparing dna.json
Resolving cookbook dependencies with Berkshelf 6.3.1...
Removing non-cookbook files before transfer
Preparing validation.pem
Preparing client.rb
Transferring files to <p8126a-aix>
Starting Chef Client, version 12.17.44
Creating a new client identity for p8126a-aix using the validator key.
resolving cookbooks for run list: ["manage_existing_servers::default"]
Synchronizing Cookbooks:
- manage_existing_servers (0.1.0)
Installing Cookbook Gems:
Compiling Cookbooks...
Converging 1 resources
Recipe: manage_existing_servers::default
* file[/tmp/test.txt] action create
- create new file /tmp/test.txt
- update content in file /tmp/test.txt from none to d0083d
--- /tmp/test.txt 2018-06-01 13:48:03.000000000 +0900
+++ /tmp/.chef-test20180601-22479180-1dschzt.txt 2018-06-01 13:48:03.000000000 +0900
@@ -1 +1,2 @@
+hello world.

Running handlers:
Running handlers complete
Chef Client finished, 1/1 resources updated in 06 seconds
Finished converging <p8126a-aix> (0m14.74s).
-----> Converging <p8127a-aix>...
$$$$$$ Running legacy converge for 'Proxy' Driver
Preparing files for transfer
Preparing dna.json
Resolving cookbook dependencies with Berkshelf 6.3.1...
Removing non-cookbook files before transfer
Preparing validation.pem
Preparing client.rb
Transferring files to <p8127a-aix>
Starting Chef Client, version 12.17.44
Creating a new client identity for p8127a-aix using the validator key.
resolving cookbooks for run list: ["manage_existing_servers::default"]
Synchronizing Cookbooks:
- manage_existing_servers (0.1.0)
Installing Cookbook Gems:
Compiling Cookbooks...
Converging 1 resources
Recipe: manage_existing_servers::default
* file[/tmp/test.txt] action create
- create new file /tmp/test.txt
- update content in file /tmp/test.txt from none to d0083d
--- /tmp/test.txt 2018-06-01 13:48:17.000000000 +0900
+++ /tmp/.chef-test20180601-17826238-1b9wet4.txt 2018-06-01 13:48:17.000000000 +0900
@@ -1 +1,2 @@
+hello world.

Running handlers:
Running handlers complete
Chef Client finished, 1/1 resources updated in 06 seconds
Finished converging <p8127a-aix> (0m14.20s).
-----> Kitchen is finished. (0m31.16s)

$ kitchen list 

Instance Driver Provisioner Verifier Transport Last Action Last Error
p8126a-aix Proxy ChefZero Inspec Ssh Converged <None>
p8127a-aix Proxy ChefZero Inspec Ssh Converged <None>

リモート・サーバーにChefレシピの内容が反映される。

vagrantドライバーの場合と同様に、cookbookは/tmp/kitchen下に転送され実行される。


リモート・サーバーにおいてInSpecによるテスト実行

$ kitchen verify

-----> Starting Kitchen (v1.17.0)
-----> Setting up <p8126a-aix>...
$$$$$$ Running legacy setup for 'Proxy' Driver
Finished setting up <p8126a-aix> (0m0.00s).
-----> Verifying <p8126a-aix>...
Loaded tests from test/integration/default

Profile: tests from test/integration/default
Version: (not specified)
Target: ssh://root@p8126a:22

File /tmp/test.txt
✔ content should match /^hello world\.$/

Test Summary: 1 successful, 0 failures, 0 skipped
Finished verifying <p8126a-aix> (0m0.73s).
-----> Setting up <p8127a-aix>...
$$$$$$ Running legacy setup for 'Proxy' Driver
Finished setting up <p8127a-aix> (0m0.00s).
-----> Verifying <p8127a-aix>...
Loaded tests from test/integration/default

Profile: tests from test/integration/default
Version: (not specified)
Target: ssh://root@p8127a:22

File /tmp/test.txt
✔ content should match /^hello world\.$/

Test Summary: 1 successful, 0 failures, 0 skipped
Finished verifying <p8127a-aix> (0m0.52s).
-----> Kitchen is finished. (0m3.43s)

$ kitchen list 

Instance Driver Provisioner Verifier Transport Last Action Last Error
p8126a-aix Proxy ChefZero Inspec Ssh Verified <None>
p8127a-aix Proxy ChefZero Inspec Ssh Verified <None>

リモート・サーバーでInSpecテストが実行された。


kitchen loginも可能

$ kitchen login p8126a

$$$$$$ Running legacy login for 'Proxy' Driver
Last unsuccessful login: Thu Apr 12 18:50:21 JST 2018 on ssh from p8127a
Last login: Fri Jun 1 13:48:41 JST 2018 on ssh from p8104a
*******************************************************************************
* *
* *
* Welcome to AIX Version 7.2! *
* *
* *
* Please see the README file in /usr/lpp/bos for information pertinent to *
* this release of the AIX Operating System. *
* *
* *
*******************************************************************************
p8126a:[/]# cat /tmp/test.txt
hello world.
p8126a:[/]# exit
Connection to p8126a closed.

vagrantドライバー構成と同様の操作が可能。

なお、実際には稼働していても、未構成と認識されている状態では、kitchen loginはできない。


削除(ダミー)

$ kitchen destroy

-----> Starting Kitchen (v1.17.0)
-----> Destroying <p8126a-aix>...
Resetting instance state with command: exit 0
Finished destroying <p8126a-aix> (0m0.41s).
-----> Destroying <p8127a-aix>...
Resetting instance state with command: exit 0
Finished destroying <p8127a-aix> (0m0.55s).
-----> Kitchen is finished. (0m3.10s)

$ kitchen list 

Instance Driver Provisioner Verifier Transport Last Action Last Error
p8126a-aix Proxy ChefZero Inspec Ssh <Not Created> <None>
p8127a-aix Proxy ChefZero Inspec Ssh <Not Created> <None>

削除を行っても、実機はそのまま稼働を続ける。


作成、Chefレシピ反映、InSpecテスト、削除を通して実行

$ kitchen test 

-----> Starting Kitchen (v1.17.0)
-----> Cleaning up any prior instances of <p8126a-aix>
-----> Destroying <p8126a-aix>...
Finished destroying <p8126a-aix> (0m0.00s).
-----> Testing <p8126a-aix>
-----> Creating <p8126a-aix>...
Resetting instance state with command: exit 0
Finished creating <p8126a-aix> (0m0.46s).
-----> Converging <p8126a-aix>...
$$$$$$ Running legacy converge for 'Proxy' Driver
Preparing files for transfer
Preparing dna.json
Resolving cookbook dependencies with Berkshelf 6.3.1...
Removing non-cookbook files before transfer
Preparing validation.pem
Preparing client.rb
Transferring files to <p8126a-aix>
Starting Chef Client, version 12.17.44
resolving cookbooks for run list: ["manage_existing_servers::default"]
Synchronizing Cookbooks:
- manage_existing_servers (0.1.0)
Installing Cookbook Gems:
Compiling Cookbooks...
Converging 1 resources
Recipe: manage_existing_servers::default
* file[/tmp/test.txt] action create (up to date)

Running handlers:
Running handlers complete
Chef Client finished, 0/1 resources updated in 06 seconds
Finished converging <p8126a-aix> (0m15.57s).
-----> Setting up <p8126a-aix>...
$$$$$$ Running legacy setup for 'Proxy' Driver
Finished setting up <p8126a-aix> (0m0.00s).
-----> Verifying <p8126a-aix>...
Loaded tests from test/integration/default

Profile: tests from test/integration/default
Version: (not specified)
Target: ssh://root@p8126a:22

File /tmp/test.txt
✔ content should match /^hello world\.$/

Test Summary: 1 successful, 0 failures, 0 skipped
Finished verifying <p8126a-aix> (0m0.58s).
-----> Destroying <p8126a-aix>...
Resetting instance state with command: exit 0
Finished destroying <p8126a-aix> (0m0.44s).
Finished testing <p8126a-aix> (0m17.07s).
-----> Cleaning up any prior instances of <p8127a-aix>
-----> Destroying <p8127a-aix>...
Finished destroying <p8127a-aix> (0m0.00s).
-----> Testing <p8127a-aix>
-----> Creating <p8127a-aix>...
Resetting instance state with command: exit 0
Finished creating <p8127a-aix> (0m0.39s).
-----> Converging <p8127a-aix>...
$$$$$$ Running legacy converge for 'Proxy' Driver
Preparing files for transfer
Preparing dna.json
Resolving cookbook dependencies with Berkshelf 6.3.1...
Removing non-cookbook files before transfer
Preparing validation.pem
Preparing client.rb
Transferring files to <p8127a-aix>
Starting Chef Client, version 12.17.44
resolving cookbooks for run list: ["manage_existing_servers::default"]
Synchronizing Cookbooks:
- manage_existing_servers (0.1.0)
Installing Cookbook Gems:
Compiling Cookbooks...
Converging 1 resources
Recipe: manage_existing_servers::default
* file[/tmp/test.txt] action create (up to date)

Running handlers:
Running handlers complete
Chef Client finished, 0/1 resources updated in 06 seconds
Finished converging <p8127a-aix> (0m14.88s).
-----> Setting up <p8127a-aix>...
$$$$$$ Running legacy setup for 'Proxy' Driver
Finished setting up <p8127a-aix> (0m0.00s).
-----> Verifying <p8127a-aix>...
Loaded tests from test/integration/default

Profile: tests from test/integration/default
Version: (not specified)
Target: ssh://root@p8127a:22

File /tmp/test.txt
✔ content should match /^hello world\.$/

Test Summary: 1 successful, 0 failures, 0 skipped
Finished verifying <p8127a-aix> (0m0.64s).
-----> Destroying <p8127a-aix>...
Resetting instance state with command: exit 0
Finished destroying <p8127a-aix> (0m0.48s).
Finished testing <p8127a-aix> (0m16.40s).
-----> Kitchen is finished. (0m35.81s)

$ kitchen list 

Instance Driver Provisioner Verifier Transport Last Action Last Error
p8126a-aix Proxy ChefZero Inspec Ssh <Not Created> <None>
p8127a-aix Proxy ChefZero Inspec Ssh <Not Created> <None>

先にChefレシピを実行していた為、ファイル作成は * file[/tmp/test.txt] action create (up to date) としてスキップされている。

削除が実際には行われないことから、kitchen test -d neverの方を使うメリットはそれほど多くないと思える。


参照


  1. Test Kitchenを稼働中のサーバに使う

  2. Shellで構築、Shellでテストする Test-Kitchen

  3. Chef-Kitchen Do it simply..

  4. Using kitchen-ssh driver to run Inspec tests on remote node

  5. .kitchen.yml

  6. Class: Kitchen::Driver::Proxy

  7. AIX V7 にて chef-client を使用する際の integer 137438954242 too big to convert to `int' エラー