Puppet Enterprise 2017.2

ロールとプロファイルの概要詳細な例では、ロールとプロファイルの手法について説明しました。次に、ロールクラスを便利に、シンプルに保つためのさまざまなアプローチについて説明します。

ロールクラスはプロファイルよりもはるかにシンプルですが、ある程度の検討は必要です。 ロールを構築するにはいくつかの方法があるため、各自にあった方法を選ぶ必要があります。

注意

初期のロールコード

以前に、Jenkins masterサーバーを管理する目的で作成したロールは以下のとおりです。

class role::jenkins::master {
  include profile::base
  include profile::server
  include profile::jenkins::master
}

プロファイル例とは異なり、これは非常に現実的なロールです。 システムの複雑さは主にプロファイルによって処理されるため、ロールは単純でもかまいません。

ロール記述のルール

ロールクラスを記述するためのルールは以下のとおりです。

  1. ロールが行う唯一のことは、includeでプロファイルクラスを宣言することです。 ロールでコンポーネントクラスや通常のリソースを宣言しないでください。

    あるいは、ロールで条件分岐を使用し、使用するプロファイルを決定することもできます。 また、ロールが同じルールに準じていれば、他のロールクラスを含めることもできます。

  2. ロールは、独自のクラスパラメータを所有してはなりません。
  3. ロールは、プロファイルのクラスパラメータを設定してはなりません(プロファイルのクラスパラメータはデータルックアップで処理されます)。
  4. ロールの名称は、ビジネスが管理するノードのタイプの通称に基づいて指定されます。

    つまり、マシンに「Jenkins master」という名前を付けている場合は、role::jenkins::masterという名前のロールを記述するということです。 また、「web server」という名前を付けている場合は、role::nginxではなくrole::webという名前を使います。

読みやすさとメンテナンスしやすさのバランスを取る

高品質なロールがあると、読みやすさメンテナンスしやすさのバランスが取りやすくなります。プロファイルのセクションで「Don't Repeat Yourself」(DRY)原則について説明しましたが、ここでも同じ原則が適用されます。つまり、の場所でコードのセクションを複数の場所で繰り返すとメンテナンスの負担が増え、エラーの可能性も高くなりますが、コードは読みやすくなります。

プログラミングではほとんどの場合、繰り返しを避けることが推奨されます。 しかし、Puppetコードの複雑さはプロファイルによってほとんど制御されているため、繰り返すことでロールの操作性が高くなることもあります。

ほとんどのユーザ向けの推奨事項

まず、以下で説明する1つ目のアプローチから着手し(「きめ細かいロール」)、入念に検討を重ねたステップを踏んで少しずつ例外を作ることをお勧めします。

ほとんどのユーザにとって、1つのファイルでロール全体を確認できることは、繰り返しによるメンテナンスの負担よりも大きなメリットがあります。 繰り返しが負担になった場合は、後からアプローチを変更して繰り返しを減らすこともできます。 類似した複数のロールをより複雑なロールにまとめる、他のロールに含めることができるサブロールを作成する、または、複雑さをプロファイルにプッシュするといった対処が必要になる場合もあります。

そのような対処が必要になるまでは、繰り返しによる負担を受け入れ、読みやすさを優先させます。シンプルなアプローチだけで十分かもしれません。

1つ目のアプローチ: きめ細かいロール

最もシンプルなアプローチは、ノードのタイプごとに1つのロールを作成する方法です。 たとえば、Puppetのリリースエンジニアリングチームは、Jenkins masterの追加リソースを管理しています。 きめ細かいロールでは、少なくとも2つのJenkins masterロールがあります。 基本的なロールと

class role::jenkins::master {
  include profile::base
  include profile::server
  include profile::jenkins::master
}

RE固有のロールがあります。

class role::jenkins::master::release {
  include profile::base
  include profile::server
  include profile::jenkins::master
  include profile::jenkins::master::release
}

メリット:

  • 読みやすさ: 単独のクラスを見るだけで、ノードの各タイプを構成するプロファイルがすぐにわかります。
  • 簡略さ: それぞれのロールはプロファイルのリストになります。

デメリット:

  • ロールの膨張: ごくわずかな違いしかないノードが多数作成されると、ロールの数が急増します。
  • 繰り返し: 上記2つのロールはほぼ同じで、相違点は1つしかありません。これらが別々の2つのロールだとすると、相互の関係を理解理解するのが困難になり、更新も非常に面倒です。

2つ目のアプローチ: 条件分岐

条件分岐を使用し、密接に関係するノード間の相違点を処理する方法もあります。

class role::jenkins::master::release {
  include profile::base
  include profile::server
  include profile::jenkins::master

  if $facts['group'] == 'release' {
    include profile::jenkins::master::release
  }
}

メリット:

  • ロールの数が少ないため、メンテナンスも容易になります。

デメリット:

  • もしかすると、読みやすさは若干低下するかもしれません。 条件分岐は、特にこのようなシンプルなケースであれば読みにくくなることはありません。しかし、新しいカスタムfactをいくつか追加して複雑なロールに対処しようとする場合もあります。 この場合、読み手はこれらのfactの意味を把握しなければならないため、ロールの読みやすさが低下します。

    ノードの分類システムを裏返しにしないように注意してください。 ロールを分離し、ノード分類子を割り当てる方が適切な場合もあります。

3つ目のアプローチ: 入れ子構造のロール

繰り返しを減らすために、ロールを他のロールの中に含めるという方法もあります。 例えば以下のようなものです。

class role::jenkins::master {
  # Parent role:
  include role::server
  # Unique classes:
  include profile::jenkins::master
}

class role::jenkins::master::release {
  # Parent role:
  include role::jenkins::master
  # Unique classes:
  include profile::jenkins::master::release
}

この例では、role::jenkins::masterrole::serverを含めることでボイラープレートを減らしています。 role::jenkins::master::releaserole::jenkins::masterが含まれると、role::serverも自動的に取得されます。 このアプローチでは、ロールは以下のことを行うだけで済みます。

  • 最も類似性の高い「親」ロールを含める。
  • 親と区別するため、小さなクラスをいくつか含める。

メリット:

  • ロールの数が少ないため、メンテナンスも容易になります。
  • ノード分類子の可視性が向上します。

デメリット:

  • 読みやすさの低下: ロールの実際のコンテンツを見るには、より多くのファイルを開く必要があります。1つ下の階層を開くだけなら大きな問題にはなりませんが、3階層、4階層下まで開くとなると非常に面倒です。

4つ目のアプローチ: ノードごとに複数のロールを作成

一般に、ノードには1つのロールのみを割り当てることを推奨します。 ノードが1つのプライマリサービスを提供するインフラの場合は、この方法が最善です。

ただし、ノードが複数のプライマリサービスを提供する場合は、複数のロールを割り当ててもかまいません。

たとえば、アプリケーションサーバー、データベースサーバー、Webサーバーで構成されることの多い大規模なアプリケーションがあるとします。 開発時により軽量なテストを可能にするため、「オールインワン」ノードタイプを開発者に提供することにしました。 これを実現するには、新しいrole::our_application::monolithicクラスを作成します。これには、3つの通常ノードを構成するすべてのプロファイルを含めることができますが、ノード分類子を使用してこれらのオールインワンマシンに3つすべてのロール(role::our_application::approle::our_application::dbrole::our_application::web)を割り当てる方が簡単かもしれません。

メリット:

  • ロールの数が少ないため、メンテナンスも容易になります。

デメリット:

  • 多用途のノードを説明する実際の「ロール」はありません。ノードに何が搭載されているかを示す唯一の情報源は、ロールとノード分類子に分散しているため、構成を理解するためには相互参照が必要になり、結果として読みやすさが低下します。
  • 複雑なアプリケーションの通常バージョンとオールインワンバージョンには、他にもう1つ微妙な相違点があり、それを把握しておく必要があります。つまり、「通常の」ロール がより複雑になる可能性があるということです。このような種類のノードを説明するロールを別に作成すると、ロールと繰り返しの数が増えるにもかかわらず、全体的な複雑さが軽減される可能性があります。

5つ目のアプローチ: スーパープロファイル

プロファイルには他のプロファイルが含まれている場合もあるため、「すべてのプロファイルには、そのサービスを提供する完全なノードを管理するために必要な、他のプロファイルを含める必要がある」という追加ルールを社内で設定するかどうか決めることができます。

たとえば、profile::jenkins::masterクラスにはprofile::serverprofile::baseの両方を含めることができ、ノード分類子にprofile::jenkins::masterを直接割り当てることによって、Jenkins masterサーバーを管理することができます。 言い換えると、ロールが通常行うすべての作業を「メイン」プロファイルが行うため、ロールレイヤが不要になるということです。

メリット:

  • このようにすると、複雑なサービスの依存関係がより明確になります。
  • コードをどのように概念化するかによって、あらゆる面で簡単にできるかもしれません。

デメリット:

  • 柔軟性の低下: ロールの組み合わせ数が減り、要件の異なるノードに対して、依存関係の代替実装を使用する能力が低下します。
  • 読みやすさも大幅に低下します。 入れ子構造のロールと同様、ノードの構成要素をまとめた明確でわかりやすいリストの利点が失われます。 入れ子構造のロールとは異なり、「上位」の完全なシステム構成(ロール)と「中位」のテクノロジのグループ化(プロファイル)との明確な区別も失われます。 どのプロファイルもシステム全体として意味を成すわけではないため、どれが上位のプロファイルか常に把握する方法が必要です。

    厳密にレイヤを分割するよりも、連続的な階層の方が理論的に考えやすいという人もいます。 組織のユーザ間で同意が取れれば、「プロファイルとプロファイル」アプローチの方が有意義かもしれません。 しかし、本当にその方法でいいのかが明確でない限り、その方法は使用しないことを強くお勧めします。ほとんどの場合は、真のロールとプロファイルアプローチの方がうまくいきます。 実績のある方法を優先してください。

6つ目のアプローチ: ノード分類子にロールを構築する

Puppet言語でロールを構築し、ノード分類子を使用してノードに割り当てる代わりに、分類子の柔軟性を利用してロールを直接構築する方法もあります。 たとえば、PEコンソールに「Jenkins masters」グループを作成し、それをprofile::baseprofile::serverprofile::jenkins::masterクラスで割り当てます。これは、基本的なrole::jenkins::masterクラスとほぼ同じジョブを実行することになります。

重要: この方法を採用する場合、分類子にプロファイルのパラメータを設定しないようにしてください。 引き続きHiera/Puppetルックアップを使用し、プロファイルを設定します。

これは、プロファイルには他のプロファイルを含めることもできるからです。クラスパラメータを設定するためにノード分類子が使用するリソースライクな動作とは相性がよくありません。

メリット:

  • ノード分類子はより強力になり、ノード管理におけるコラボレーションの中心となります。
  • 読みやすさの向上: PEコンソールのノードページには、そのロールの完全なコンテンツが表示されます。ここでは、roleモジュールのマニフェストを相互参照する必要はありません。

デメリット:

  • 柔軟性の低下: Puppet言語の条件分岐は、PEコンソールを含む大半のノード分類子よりも柔軟性と利便性に優れています。
  • ロールはプロファイルと同じコードリポジトリにはないため、同じコードプロモーションプロセスを行うことが困難になります。
Back to top