[和訳] Chef Client 12.5 の独自 Resource #getchef
この記事は1年以上前に投稿されました。情報が古い可能性がありますので、ご注意ください。
本稿は Custom Resources in Chef Client 12.5 (2015/11/06) の和訳です。
2015年10月28日、Chef 社の Principal Engineer である John Keiser が Chef Client 12.5 の独自 Resource に関する Webinar を行いました。John は独自 Resource の概念を紹介し、なぜそれを書くべきなのかを説明し、言語概念を紹介し、作成方法のチュートリアルを行いました。
Webinar の録画はこちらで視聴可能です。生放送で答えることのできなかった質問を含む質疑応答をこの投稿の最後に記載しました。
質疑応答
「以前のやり方」は今後の Chef のバージョンでは推奨しないのでしょうか?
以前の方法を削除する予定はありません。それを利用する Cookbook が既に多く出回っているためです。下位互換機能は保持しますが、過去の LWRP/HWRP パラダイムはもはや Resource を作成する「推奨の」方法ではありません。
pure ruby を Chef DSL 構築に再マップするためのトリックやアドバイスはありますか? Provider を書いていると、pure ruby で通知を送信したり、pure ruby で Chef 組み込み Resource や Provider を生成する (または include_recipe のようなその他の DSL 機能を用いる) 必要があり、結局 Ruby の「require」ファイルを Chef ソースコード全体で追跡することになります。
Resource 内からそれらの機能を使用しているならば、新しい Resource (include_recipe や Resource 内で動いている他の Resource) で既に利用可能のはずです。一般的に、私は可能であれば DSL を使用するようにしています。1つのコツとしては、呼び出している Recipe や Resource にリファレンスを保存することです。そうすることでそれを用いて Resource を作成できます。例えば、次のようにします:
recipe = self; ruby_block 'x' { block { recipe.file '/x.txt' }}
Resource と Provider のパターンは、Resource ディレクトリにすべてを書いて実装するよりも良いカプセル化であるように思うのですが、間違っていますか?
こちらのほうが容易であることの最大の理由としては、Resource を書きたい人が新しい概念を学ぶ必要がないということです。あなたは Recipe も Resource も Action もすでにご存じですね。Provider とは何でしょう? ...コンピューター科学の視点から見れば、これはコンクリートベースクラスと、別々のファイルにインターフェイスと実装を持つことの違いです。すべてのクラスをインターフェイスと実装に分けず、サブクラスを増やしたり、後で削除したいクラスのみを分けますよね。そうでなければコードが読みづらくなってしまいます。そういうわけで、実装を別々のファイルに入れて結構です。ただ、それは Provider ではないというだけです。
why-run ロジックをどのように変更したのか例を見せてください。
why-run は変更していません。Action で Resource を用いる、もしくは converge_by を用いるのであれば、why-run モードでは何の動作も発生しません。load_current_value と converge_if_changed (chef-docker Cookbook を参照) は偶然にも why-run モードにも対応している冪等性を処理するのにより簡単な新たな選択肢です。
test kitchen と chefspec は今もきちんと動作しますか?
はい。
chefspec の独自 Resource で利用可能なサポートにはどのようなものがありますか?
通常の Resource と同様です。
Cookbook が chef-client 12.5.x を必要とすることを明示する方法はありますか?
上位互換性を保証したいのであれば、Cookbook に「depends 'compat_resource'」を追加してください。そうすればすべての新しい Resource 機能が 12.0 以降で動作します。
では、プロパティの以前の値にアクセスしますか? current_resource.x はまだ使用できますか?
current_resource は今も存在はしますが、独自 Resource で "x" と打つと current_resource.x が初期値になるということを指摘させてください。
Resource/Provider ではなく Library にすべてのコードを入れてはどうでしょうか?
Library で Resource を宣言したいのであれば、 MyResource < Chef::Resource というクラスを使うことができます。
この新しい Resource をどのように Rspec テストしますか?
chefspec、serverspec、test kitchen です。すべてあなたが知っていて愛用しているツールでしょう?
見せていた例 (myapp_website) はどのようにサブクラス化しますか?
resource/ ディレクトリで宣言している Resource をサブクラス化することはできません。サブクラス化したいのであれば、ライブラリで宣言して MyAppWebsite < Chef::Resource というクラス化をする必要があります。
Chef 11.x サーバーの Node に chef-client 12.5 をインストールすることができますか?
もちろんです!
独自 Resource と LWRP は共存できますか? 11 と 12.5 の両方のクライアントで動作する Resource はありますか? ないとすれば、12.5 以前と以後が混合したエコシステムで chef-provisioning がプロビジョニングした Node 上に、どのように正しい Resource Cookbook を適用しますか?
独自 Resource と LWRP は共存できます。「depends 'compat_resource'」を Cookbook Metadata に追加する場合、12.0 から 12.5 までの Resource 機能を使用することができます。chef-client バージョン 11 では動作しません。
独自 Resource と独自 Definition の主な違いは何ですか?
Output や Action 内で使用する Resource に表示される独自 Resource は Output でも表示されます(意図的にどの Resource から来ているかを見ることができるように意図しています)。さらに、その中のコードは収束時間までは動作しません。そのほうが自然に理解できまると思います。独自 Definition は多くの場合マクロのように動作し、その Recipe は Definition を使用するとすぐにコンパイルを行います。そして、それは実際は Resource ではないため、Definition は chef-client の Output には現れません。
Chef でコード関連のことを試す際に Ruby 言語の制限はあるのでしょうか?
それほどありません。すべてコードであるためです。
2つ以上の Cookbook で独自 Resource を有効にすることは可能ですか?
はい、Resource は常にすべての Cookbook で利用可能です。
ある Action にプロパティを要求して他のものには要求しないという機能はありますか?
直接そのように定義されたものではありません。Action が開始した際に、要求したプロパティがない場合に例外を返せば可能です。
話がそれますが、あなたの bash/zsh 構成は、ライトグレーで候補が表示されますがタイピングし続けることができるようです。いいですね。どのようにすればできますか?
Fish shellです。http://fishshell.com/
通常の Resource について only_if と not_if 条件が適用されますか?
はい。
この機能進化版の機能には複数のバグとドキュメンテーションエラーがあります。例えば、load_current_value は Action 内から動作しません。Action はドキュメントによるとサポートしているはずです。
load_current_value は Action 外から呼び出さなければなりません。
Chef Client 12.5 は本日利用可能ですか? アップグレードの手順はどのようになっていますか? リスクは何ですか?
12.5 は利用可能です! omnibus_updater Cookbook でクライアントを最新にしておくことができます。12.4 からアップグレードする際の既知の上位互換性の問題はありません。
ウェブのドキュメントで読んだのですが、Definition の価値が低くなり、代わりに独自 Resource を使用するように推奨するそうです。Definition をコンパイル時に実行し、収束中に LWRP/HWRP を実行します。Definition のようにコンパイル時に何かを実行したい場合、独自 Resource はどのような状況になりますか?
独自 Resource は収束時間に実行されます。(プロパティを埋める) Resource を「使用」している do ブロックはコンパイル時に実行します。
通知フローはどのようになっていますか? LWRP について定義していますか? 例えば、LWRP use_inline_resources についてはどうでしょうか?
はい、それらは LWRP use_inline_resources と同様に動作します(見えないところでその性能を利用します)。
Chef にはダイナミックプロパティはありますか?
property :x, default: lazy { } でプロパティが値を計算します(ユーザーがプロパティを直接設定しない限り)。
カスタムロジックを追加せずに既存のリソースをラップする確立された方法は Definition を使うことです。この、独自 Resource を定義する単純化した方法は Definition を重要視しないということですか?
はい。
LWRP は書いたことがありません。Chef 12.5 の独自 Resource で ruby_block を使うことはできますか?
できます。
どのように独自 Resource レベルで冪等性を担保しますか(各 Resource ではなく、レベルを包含しているもの)? コード/Action 内からのどように現在の Resource を参照しますか? 例えば、どの Action を呼び出しますか? ある Action が他の Action のサブセットを包含する、等。
load_current_value と converge_if_changed でできます(例は chef-docker Cookbook を見てください)。他の Action から Action を呼び出すには、new_resource.run_action(:other_action) を使用することができます。
Cookbook 間で Resource を共有するにはどうすればよいですか?
Cookbook でそれを宣言し、Resource を使用したい Cookbook で「depends "that_cookbook"」を使用してください。
Action なしをデフォルトに指定できますか? つまり、caller が Action を明確に指定しなければなりませんか?
default_action :nothing と指定することができます。ユーザーが Action を指定しないかぎり何も発生しません。
プロパティは機能を拡張することができますか?
プロパティは完全に拡張可能です。Chef::Property から引き継いだクラスを作成し、そのクラスを property :x, MyPropertyClass で使用する場合、それがをプロパティを作成するのに使用します。
Resource ファイルはリモートにできますか? 例えば、http:// 等
remote_file Resource が必要です。https://docs.chef.io/resource_remote_file.html
Resource でどのように独自の ruby コードを書くことができますか? その場合、どのように冪等性を管理しますか? 通知は同様に動作しますか? 通知を Resource 内で動作させ、Resource 外で動作しないようにするにはどうすればよいですか?
独自 ruby コードで冪等性を担保するには load_current_value を実行し converge_if_changed を使用してください。chef-docker Cookbook にその例が載っています。通知は変更されていません(Resource 外のものについての通知はできませんが、Resource 自体は Recipe 内の他の Resource の購読や通知をすることができます)。