Puppet(バージョン5.5)のコードデザインに問題があります。 ucarpを処理するためのコンポーネントモジュールを作成しました。モジュール eyp-systemd を利用して、systemd内にucarpサービスを登録します。ここで、異なるサービス(私の場合は実際にはhaproxyとbind9)を管理する2つの独立したプロファイルモジュールからucarpモジュールを使用したいと思います。基本的にこれは次のようになります。
class ucarp {
systemd::service { 'ucarp':
# list of parameters
}
}
define ucarp::vip {
# defines a virtual IP to be shared among several nodes
}
# ====================
class profile_haproxy {
include ::ucarp
::ucarp::vip { 'haproxy': }
# setup haproxy
}
# =====================
class profile_bind9 {
include ::ucarp
::ucarp::vip { 'bind9': }
# setup bind9
}
これは簡単で、うまく機能します。
ここで実際の問題:ucarp上で実行されるサービスの後にucarpサービスを注文することをお勧めします。これは、afterパラメーターを使用して可能です。
class ucarp(
Array[String] $after,
) {
systemd::service { 'ucarp':
after => $after.join(' '),
# list of other parameters
}
}
これには、include ::ucarp
をに置き換える必要があります
class { '::ucarp':
after => ['haproxy'],
}
または
class { '::ucarp':
after => ['bind9'],
}
それぞれ。もちろん、これはすぐに「重複宣言」エラーにつながります。
私が実際に望んでいるのは、すべてのafter
パラメーターをsystemd :: serviceに渡すことができる単一の文字列に収集するクラスucarpの単一のインスタンス化です。 どうすればよいですか?
現在、2つの可能な解決策が思い浮かびます。
systemd::service::after
は、サービス定義ファイル内の対応するエントリを管理します。これは私が本当にやりたくないことです。一般的に、私はフォージモジュールを変更することを躊躇します。この場合、変更もかなり大きいようです(インターフェイスの変更を含む)。ucarp::order_after
に自分で定義した型を導入します。プロファイルモジュールは、このタイプの仮想インスタンスを定義します。次に、ucarpクラスはpuppetdbクエリを使用して、ucarp::order_after
のすべてのインスタンスを収集できます。ここでの大きな欠点は、エクスポートされたリソースではなく、仮想リソースのみを扱っていることです。したがって、実際にはpuppetdbを関与させる必要はまったくなく、このアプローチは醜い回避策になります。さらなる解決策はc4f4t0rに触発されています:
after
サービスでucarpコンポーネントクラスをインスタンス化することであるucarpプロファイルモジュールを導入します。 after
サービスのリストは、hieraによって提供されます。class profile_ucarp( Array [String] $ after、 ){ class {':: ucarp': after => $ after 、 } }
profile_ucarp.after: -'haproxy' -'bind9'他のプロファイルクラスが
ucarp
クラスをインスタンス化する必要はもうありません-潜在的な重複宣言の問題を削除します。このソリューションは、上記の2つよりも優れていると思います。それでも、コードのみに関連する問題を修正するためにhieraを使用することは、hieraの誤用であるため、私は満足していません。今は考えられない可能性が他にもあるといいのですが。
Contains関数を使用して、クラスパラメータをhieraに配置する必要があります。
プロファイルモジュールでは、クラスのプロファイルを格納するためにhieraを使用していないため、クラスを複製しているため、クラスprofile :: haproxyとprofile :: bindは1つだけにすることができます。
class profile::ucarp {
contain ::ucarp
contain ::ucarp::vip
}
class profile::haproxy {
contain ::haproxy
}
#now I can create a role using this profiles
class role::elb {
contain ::profile::ucarp
contain ::profile::haproxy
}
Hiera内で、ホストの機能に基づいてパラメーターを保存できるようになりました。エラーを回避したい場合は、puppetdocの役割とプロファイルを使用してデザインを確認してみてください。
人形のドキュメントから
Having classes contain other classes can be very useful, especially in larger modules where you want to improve code readability by moving chunks of implementation into separate files.
However, unlike resources, Puppet does not automatically contain classes when they are declared inside another class. This is because classes can be declared in several places via include and similar functions. Most of these places shouldn’t contain the class, and trying to contain it everywhere would cause huge problems.
Instead, you must manually contain any classes that need to be contained.