web-dev-qa-db-ja.com

レシピの属性をオーバーライドする

クックブックにデフォルトの属性があるとしましょう:

_default.nginx_upstreams = {
    'service1' => ['service1.server.com'],
    'service2' => ['service2.server.com'],
}
_

その後、最終的に私のレシピに到達するまで、ロールと環境で変更およびオーバーライドされます。そこで、属性に追加したい追加のサービスを計算します。私がこのようなことをしたら:

_node.nginx_upstreams.merge! {'service3' => ['service3.server.com']}
_

テンプレートで属性を使用しようとすると、テンプレートで_undefined method 'each' for nil:NilClass_を取得しようとします

_<% node.nginx_upstreams.each do |name, servers| %>
_

さらに、_WARN: Setting attributes without specifying a precedence is deprecated and will be removed in Chef 11.0_も取得します。有用な警告は、属性を通常の優先順位で設定する方法を教えてくれます(明らかに_node.set["key"] = "value"_を使用しますが、デフォルトの指定方法や属性のオーバーライド方法は教えてくれません)。

この問題を回避するには、次のようにします。

_upstreams = node.nginx_upstreams.to_hash
upstreams.merge! {'service3' => ['service3.server.com']}

template "nginx_config" do
    variables({:upstreams=>upstreams})
end
_

しかし、それはハックのように感じます。 このページ を超えてnode.set()に関するドキュメントを見つけることができません。しかし、方法を言いません。

それで...レシピ内からどのように属性(他のすべてと一緒に深くマージされる)を適切に設定しますか? node.set()呼び出しは実際に何をしますか?マージしたい優先順位を伝えることができますか?

38
Igor Serebryany

default.nginx_upstreamsdefault[:nginx_upstreams]およびdefault['nginx_upstreams']と同じです-規則では、後者の2つのうち1つを使用します。また、文字列をさらに使用する場合は、ここでも使用します。

属性ファイルでnginx_upstreamsを初期化する方法は、次のようにするのと同じです。

default['nginx_upstreams']['service1'] = ['service1.server.com']
default['nginx_upstreams']['service2'] = ['service2.server.com']

そして、その前にdefault['nginx_upstreams'] = {}を初期化する必要はありません。これらはハッシュではなく属性であり、はるかにスマートです。 :)

レシピ内からの属性の変更は次のように行われます。

node.default['nginx_upstreams']['service3'] = ['service3.server.com']

優先順位を変更する必要がある場合は、setの代わりにoverrideまたはdefaultを使用できます。優先名(node['nginx_upstreams']またはnode.nginx_upstreams)を省略すると、set優先順位が使用されます。しかし、これは非推奨であり、すぐに削除されます-それが警告のすべてです。 属性に関するマニュアルページ をチェックしてください。すべてが実際にあるからです。

44
Draco Ater

Chef属性についてさらに詳しく知りたいと思ったので、ノード属性のオーバーライドでこの質問を参照するユーザーにとって非常に重要です。

ファイルメソッドは属性に対応します

クックブックの属性ファイル内またはレシピ内で次のメソッドを使用します。これらのメソッドは、同じ名前の属性タイプに対応しています。

  • オーバーライド
  • default
  • normal(またはset、setはnormalのエイリアス)
  • _unless
  • 属性?

属性の優先順位

属性は常に、シェフクライアントによって次の順序で適用されます。

  1. クックブック属性ファイルにあるデフォルト属性
  2. レシピにあるデフォルト属性
  3. 環境にあるデフォルトの属性
  4. ロールにあるデフォルト属性
  5. クックブック属性ファイルにあるforce_default属性
  6. レシピにあるforce_default属性
  7. クックブック属性ファイルにある通常の属性
  8. レシピにある通常の属性
  9. クックブック属性ファイルにあるオーバーライド属性
  10. レシピにあるオーバーライド属性
  11. ロールにあるオーバーライド属性
  12. 環境にあるオーバーライド属性
  13. クックブック属性ファイルにあるforce_override属性
  14. レシピにあるforce_override属性
  15. Chef-client実行の開始時にOhaiによって識別された自動属性

ここで、リストの最後の属性は、ノードに適用されるものです。

つまり、OHAI属性の優先順位が最も高く、クックブック属性ファイルのデフォルト属性の優先順位が最も低くなります。

注:ユーザーの利益のために、 属性 のChefドキュメントから重要な詳細を提供しました。 URLが移動されるか無効になる場合があるためです。

10
Saravanan G

だから、掘り下げた後、私は答えを見つけました:

node.set
node.setはnode.normalのエイリアスであるため、node.setではなくnode.default(またはnode.override)を使用します。通常のデータはノードオブジェクトに保持されます。したがって、node.setを使用すると、ノードオブジェクトにデータが保持されます。 node.setを使用するコードが後で削除され、そのデータが既にノードに設定されている場合、そのデータは残ります。

通常の属性とオーバーライド属性は、chef-clientの実行の開始時にクリアされ、その時点でのクックブックとレシピのコードに基づいて実行の一部として再構築されます。

node.set(およびnode.normal)は、最初のシェフクライアントの実行時にデータベースのパスワードを生成するなどの目的でのみ使用する必要があります。このタイプのデータを保存するには、データバッグの使用が推奨されるため、このような場合でも避ける必要があります。

4
AngryChef