新しいchef-runコマンドによる、Chef ServerやKinfe-Zeroを必要としない、リモートノードへのChef適用


#chef-runコマンド

新しいChef-Workstation(少なくともChef Workstation 0.2.43)は、ChefDKを含み、かつ新しいchef-runという、sshもしくはwinrm接続されたノードへのChef適用を行うコマンドを提供する。

```
$ chef -v
Chef Workstation: 0.2.43
  chef-run: 0.2.4
  chef-client: 14.8.12
  delivery-cli: master (5fb4908da53579c9dcf4894d4acf94d2d9ee6475)
  berks: 7.0.7
  test-kitchen: 1.24.0
  inspec: 3.2.6

$ chef-run -h
Chef Run is a tool to execute ad-hoc tasks using Chef.

chef-run <TARGET[S]> <RESOURCE> <RESOURCE_NAME> [PROPERTIES] [FLAGS]

  Runs a single <RESOURCE> on the specified <TARGET[S]>.
  [PROPERTIES] should be specified as key=value.

  For example:

    chef-run web01 service nginx action=restart
    chef-run web01,web02 service nginx action=restart
    chef-run web0[1:2] service nginx action=restart

chef-run <TARGET[S]> <RECIPE> [FLAGS]

  Runs a single recipe located at <RECIPE> on the specified <TARGET[S]>.

  For example:

    chef-run web01 path/to/cookbook/recipe.rb
    chef-run web01,web02 path/to/cookbook
    chef-run web0[1:2] cookbook_name
    chef-run web01 cookbook_name::recipe_name

ARGUMENTS:
  <TARGET[S]>       The hosts or IPs to target. Can also be an SSH or WinRM URLs
                    in the form:

                    ssh://[USERNAME]@example.com[:PORT]
  <RESOURCE>        A Chef resource, such as 'user' or 'package'
  <RESOURCE_NAME>   The name, usually used to specify what 'thing' to set up with
                    the resource. For example, given resource 'user', 'name' would be
                    the name of the user you wanted to create.
  <RECIPE>          The recipe to converge. This can be provided as one of:
                    1. Full path to a recipe file
                    2. Cookbook name. First we check the working directory for this
                       cookbook, then we check in the chef repository path. If a
                       cookbook is found we run the default recipe.
                    3. This behaves similarly to 'cookbook name' above, but it also allows
                       you to specify which recipe to use from the cookbook.

FLAGS:
    -c, --config PATH                  Location of config file. Default: /Users/aa220269/.chef-workstation/config.toml
        --cookbook-repo-paths PATH     Comma separated list of cookbook repository paths.
    -h, --help                         Show help and usage for `chef-run`
    -i, --identity-file PATH           SSH identity file to use when connecting. Keys loaded into ssh-agent will also be used.
        --[no-]install                 Install Chef client on the target host(s) if it is not installed.
                                       This defaults to enabled - the installation will be performed
                                       if there is no Chef client on the target(s).
        --password <PASSWORD>          Password to use for authentication to the target(s). The same
                                       password will be used for all targets.
    -p, --protocol <PROTOCOL>          The protocol to use for connecting to targets.
                                       The default is 'ssh', and it can be changed in config.toml by
                                       setting 'connection.default_protocol' to a supported option.
        --[no-]ssl                     Use SSL for WinRM. Current default: false
        --[no-]ssl-verify              Verify peer certificate when using SSL for WinRM
                                       Use --ssl-no-verify when using SSL for WinRM and
                                       the remote host is using a self-signed certificate.
                                       Current default: true
        --[no-]sudo                    Whether to use root permissions on the target. Default: true
        --sudo-command <COMMAND>       Command to use for administrative/root access. Defaults to 'sudo'.
        --sudo-options 'OPTIONS...'    Options to use with the sudo command. If there are multiple flags,
                                       quote them. For example: --sudo-options '-H -P -s'
        --sudo-password <PASSWORD>     Password to use with the sudo command.  This must be provided if
                                       password is required for sudo on the target(s). The same sudo password
                                       will be used for all targets.
        --user <USER>                  Username to use for authentication to the target(s). The same
                                       username will be used for all targets.
    -v, --version                      Show the current version of Chef Run.
```


##リソース指定の例

リモートノードにChefのfileリソースを直接指定して/tmp/hello.txtファイルを作成

```
$ chef-run web1 -i ~/.ssh/id_rsa file /tmp/hello.txt  # 対象は RHEL on POWER
[✔] Packaging cookbook... done!
[✔] Generating local policyfile... exporting... done!
[✔] Applying file[/tmp/hello.txt] from resource to target.
└── [✔] [web1] Successfully converged file[/tmp/hello.txt].
```

- web1にはssh接続
- Chefクライアントが未導入なら導入が試みられる
- リソースにアトリビュートを指定するには、file hello.txt content='Hello World!'の様に key=value で指定。改行を渡すにはレシピ指定を使用する必要がある(?)
- Why-run指定無し
- ~/.ssh/configにおいてidファイルを指定していても-i(もしくは--identity-file)にて指定する必要があった
    - [公式 learn chef : try-chef : 3. Basic ingredients ](https://learn.chef.io/modules/try-chef#/step3) の docker環境では-iは不要。docker-compose.ymlにおけるlinks:指定に依る?
- 処理内容は、対象ノードにおける /var/chef-workstation/cookbook_artifacts 下に cookbook として copy されて使用される様子


##レシピ指定の例

```
$ cat ./recipe.rb 
file '/tmp/hello.txt' do
  content "Hello World!\n"
end

$ chef-run web1 -i ~/.ssh/id_rsa ./recipe.rb
[✔] Packaging cookbook... done!
[✔] Generating local policyfile... exporting... done!
[✔] Applying recipe from ./recipe.rb to target.
└── [✔] [web1] Successfully converged recipe.

$ ssh web1 cat /tmp/hello.txt
Hello World!
```

##クックブックへのパス指定の例

```
$ tree .
.
└── recipes
    └── default.rb

1 directory, 1 file

$ cat ./recipes/recipe.rb 
file '/tmp/hello.txt' do
  content "Hello World! 2\n"
end

$ chef-run web1 -i ~/.ssh/id_rsa $(pwd)
[✔] Packaging cookbook... done!
[✔] Generating local policyfile... exporting... done!
[✔] Applying default from /xxx/recipes/default.rb to target.
└── [✔] [web1] Successfully converged default.
```

metadata.rbも不要。単にrecipesディレクトリーがあれば良い様子。


##クックブック指定の例

```
$ chef generate cookbook test-book 
...

$ cd test-book/

$ grep name metadata.rb 
name 'test-book'

$ cat <<_EOC_ > recipes/default.rb 
> file '/tmp/hello.txt' do
>   content "Hello World! 3\n"
> end
> _EOC_

$ chef-run web1 -i ~/.ssh/id_rsa test-book::default --cookbook_repo_paths .. 
[✔] Packaging cookbook... done!
[✔] Generating local policyfile... exporting... done!
[✔] Applying test-book::default from /xxx/test-book to target.
└── [✔] [web1] Successfully converged test-book::default.

あるいはcookbooks直下やchef-repo直下で実行

$ ( cd .. && chef-run web1 -i ~/.ssh/id_rsa test-book::default )
[✔] Packaging cookbook... done!
[✔] Generating local policyfile... exporting... done!
[✔] Applying test-book::default from /xxx/test-book to target.
└── [✔] [web1] Successfully converged test-book::default.


$ ssh web1 cat /tmp/hello.txt
Hello World! 3
```

cookbook_repo_paths は設定ファイル ~/.chef/config.rb に設定することも可能

```ruby:~/.chef/config.rb

cookbook_path [ '/xxx/cookbooks' ]
```



##クックブックが依存する例


###依存先クックブックdepends_test_targetとそのレシピ作成

```
$ pwd
/xxx/cookbooks/test-book

$ ( cd .. && chef generate cookbook depends_test_target )
...

$ cat <<_EOC_ > ../depends_test_target/recipes/default.rb
file '/tmp/depends_test_target'
_EOC_
```






###依存設定を構成

```:./metadata.rb
name 'test-book'
...
depends 'depends_test_target' # 依存先クックブック指定を追記
```

###クックブックの場所を指定
クックブックの場所の指定には、Berksfile(従来の方法)もしくはPolicyfile(新しい方法)を使用する

####Berksfile(old)
```:./Berksfile
# frozen_string_literal: true
source 'https://supermarket.chef.io'
source chef_repo: ".."                # 追記: chef-repoかcookbooksのパスを設定

metadata

```
chef generate cookbook test-book 時に作成されているBerksfileを必要に応じて編集
デフォルトではchef supermarket上のクックブックのみの対応の為、ここではローカルの設定を追記

####Policyfile(new)
```ruby:./Policyfile.rb
name 'test-book'                            # ポリシー名。ここではcookbook名に合わせている。
default_source :chef_repo, '/xxx/cookbooks' # chef-repoかcookbooksのパスを設定
run_list 'chef-run::default'                # chef-runでは未使用
```
Chef社としてはPolicyfileに移行して行くことを推奨
Berksfileと同様に、cookbook毎の指定や、supermarketやgithubの指定も可能。
注：cookbookのパスには絶対パスを使用。\_\_FILE__が/var/folders/yd/.../chef-run/Policyfile.rb などと展開されていた為。


参考：
[公式: Policyfile.rb](https://docs.chef.io/config_rb_policyfile.html)


####レシピ例

```:./recipes/default.rb
include_recipe 'depends_test_target::default' # 依存先クックブックのレシピを取り込んで実行
```

###実行

```

$ chef-run web1 test-book -i ~/.ssh/id_rsa
[✔] Packaging cookbook... done!
[✔] Generating local policyfile... exporting... done!
[✔] Applying test-book::default from /xxx/cookbooks/test-book to target.
└── [✔] [web1] Successfully converged test-book::default.

$ ssh hl1 ls /tmp/depends_test_target
/tmp/depends_test_target
```
cookbookパスは ~/.chef/config.rb にて設定済み

参考：
[公式 Chef Workstation : chef-run Guide : Configuring Cookbook Dependencies and Sources](https://www.chef.sh/docs/chef-workstation/chef-run-users-guide/#configuring-cookbook-dependencies-and-sources)




##chef-run: 0.2.4における対象の制約
chef-run: 0.2.4では、管理対象ノードは Windows と Linux のみ。
対象は拡張予定。

```

$ chef-run p8126a -i ~/.ssh/id_rsa file hello.txt  # 対象はAIX
[✔] Packaging cookbook... done!
[✔] Generating local policyfile... exporting... done!
[✖] Applying file[hello.txt] from resource to target.
└── [✖] [p8126a] ChefApply::TargetHost::UnsupportedTargetOS

'aix' is not a supported target operating system at this time.

We plan to support a range of target operating systems,
but during this targeted beta we are constraining our efforts
to Windows and Linux.
```



##参照

[Announcing General Availability of Chef Workstation](https://blog.chef.io/2018/10/16/announcing-general-availability-of-chef-workstation/)
[[和訳] Chef Workstationの正規版リリースのお知らせ](https://www.creationline.com/lab/23515)

[公式 learn chef : try-chef : 3. Basic ingredients ](https://learn.chef.io/modules/try-chef#/step3)
[公式 Chef Workstation : Ad-hoc remote execution with chef-run](https://www.chef.sh/docs/chef-workstation/getting-started/#ad-hoc-remote-execution-with-chef-run)
[公式 Chef Workstation : chef-run Guide](https://www.chef.sh/docs/chef-workstation/chef-run-users-guide/)
[公式 Chef Workstation : Chef Run CLI Reference](https://www.chef.sh/docs/reference/chef-run/)