web-dev-qa-db-ja.com

hieraを使用して別のノードのファクトにアクセスする

私たちがやろうとしているのは、iptablesのファイアウォールルール(puppetlabs /ファイアウォール)を生成することです。私たちのノードは、概念的に次のようにグループ化されています。

-- site1
---- shared1
------ specific1
------ specific2
---- shared2
------ specific3
------ specific4

ノード「specific4」は常に「shared2」のポート8080と「site1」のポート10000にアクセスする必要があります。 「specific1」も同様に「shared1」の8080にアクセスする必要があります。ルールはノードごとに常に同じになりますが、どのグループに属しているかに依存します。

これを重複せずにhieraで表現する方法を見つけるのに苦労しています。完全に別のノードから事実を取得することは可能ですか?

私はこのようなことをしたいと思います(簡略化):

--
hosts:
  Host specific4:
    rules:
      rule:
        port: 8080
        ip: get_ip(get_my_shared())

しかし、明らかに、yamlファイルから関数を呼び出すことはできません。これを実現する最善の方法は、カスタムファクトを使用することでしょうか?私はまだ実際にhieraを使用したことがないので、ベストプラクティスとそうでないものがわかりません。正しい方向への穏やかな押し込みが最もありがたいです。

編集:

これは私が行った解決策ですが、エクスポートされたリソースを使用できる場合は、puppetdb-queryへの依存関係を削除できます。

# helper for creating rules from an array
define firewall_rules($port, $service_type) {
    $source = $name
    firewall { "$port $service_type $source":
        proto       => 'tcp',
        dport       => $port,
        state       => 'NEW',
        source      => "$source",
        action      => 'accept'
    }
}

class profile::specific inherits profile {
    $site = hiera('site')
    $shared = hiera('shared')
    $query = "site=\"$site\" and shared=\"$shared\""
    $shared_hosts = query_nodes($query)
    $specific_port = hiera('specific_ports', '8080')
    firewall_rules { $shared_hosts:
        port           => $specific_port,
        service_type   => 'SPECIFIC'
    }
}

次に、hieraデータに基づいてsiteおよびsharedファクトをエクスポートし、puppet-stdlibを使用してホスト上のfileリソースからそれらをロードします。

class profile::facts {

    $site       = hiera('site', 'none')
    $shared     = hiera('shared', 'none')
    $specific   = hiera('specific', 'none')
    $role       = hiera('role', 'none')
    $grouping   = "site=$site\nshared=$shared\nspecific=$specific\nrole=$role"

    notify { "facts being set: $grouping ": }

    file { ['/etc/facter/', '/etc/facter/facts.d/']:
        ensure  => directory,
        owner   => 'root',
        group   => 'root'
    }->
    file { '/etc/facter/facts.d/grouping.txt':
        ensure  => file,
        owner   => 'root',
        group   => 'root',
        mode    => '0775',
        content => $grouping
    }
}

私が言ったように、これは機能しますが、可能であればエクスポートされたリソースを使用したいと思います。私が遭遇した問題は、エクスポートを実行しているリソースが、収集のために独自のIP /ホストもエクスポートできないことでした。何かを見逃したかもしれませんが、そのリソースを含むノードが実現されたときではなく、リソースが解析されたときにエクスポートが行われるため、それは不可能だと思います。

2
Josh Smeaton

したがって、特定のホストが別のホストのファクトから情報を取得するようにしますが、ファクトがどのホストから取得されるかは、特定のホストの構成によって異なります。あれは正しいですか?

その場合は、エクスポートされたリソースを使用し、タグを使用して使用する特定のリソースを指定することもお勧めします。これは、ホストが別のホストの事実を知るには基本的に2つの方法があるためです。どちらもstoreconfigsを有効にする必要があります。 1つは、パペットマスターがstoreconfigsバックエンドが何であれ明示的なルックアップを実行することです。これをカプセル化するモジュールは知らないので、独自に作成する必要があるかもしれません。もう1つは、ソースホストがファクトを含むリソースをエクスポートするためのものです。これは簡単で、以下で説明します。

独自のリソースタイプを作成してファイアウォールルールをラップすると、これは簡単になります。これにより、ファイアウォールルールをエクスポートしている他のクラスとの衝突が防止されます。

define site_firewall ($ipaddr) {
  firewall { '500 allow site access':
    chain       => 'OUTPUT',
    destination => $ipaddr,
    proto       => 'tcp',
    port        => 10000,
  }
}

次に、各サイトはsite_firewallの独自の定義をエクスポートする必要があります。

@@site_firewall { $hostname:
  ipaddr => $ipaddress,
}

Hieraでは、階層のどこかに、各ホストがメンバーであるサイトを定義します。

sitename: site1

次に、ホストクラスで、適切なsite_firewall定義をインスタンス化します。

Site_firewall <<| name == hiera('sitename', 'default') |>>

同様の設定が共有ホストにも適用されます。

サイトと共有ホストでファイアウォールルールが必要な場合は、特定のホストに複数のファイアウォールルールがあるため、名前ではなくタグを使用する必要があります。特定のホスト:

@@firewall { "500 allow site traffic from ${hostname}":
  tag    => hiera('sitename', 'default-site'),
  source => $ipaddress,
  proto  => 'tcp',
  port   => 10000,
}
@@firewall { "500 allow shared traffic from ${hostname}":
  tag    => hiera('sharedname', 'default-shared'),
  source => $ipaddress,
  proto  => 'tcp',
  port   => 8080,
}

サイトホストでは、これらのホストのファイアウォールルールを収集する必要があります。

Firewall <<| tag == $hostname |>>

編集:ああ。エクスポートされたリソースで発生した問題を見つけたと思います。少なくとも、これは私がここで適切に文書化する落とし穴です。

デフォルトのパラメータを持つリソースがあり、それらのパラメータを明示的に設定せずにそのリソースをエクスポートする場合、パラメータのデフォルトは、ホストrealizingによって提供されます。それをエクスポートするもの。

つまり、このリソースタイプの定義がある場合:

define foo ($bar = $fqdn) {
  notice($bar)
}

そして、ホストbaz.example.comからエクスポートします。

@@foo { 'title': }

そして、あなたはホストquux.example.comでそれを実現します:

Foo <<| |>>

その場合、$barの値は「quux.example.com」になります。

代わりに、次のようにbaz.example.comからエクスポートする場合:

@@foo { 'title': bar => $fqdn }

その場合、$barの値は実際には「baz.example.com」になります。

3
asciiphil

さて、あなたのユースケースに適したオプションは、「storeconfigs」を有効にしてから「エクスポートされたリソース」を使用することだと思います。ここでは、いくつかの例を含むこのトピックに関するいくつかのドキュメントを見つけることができます: http://docs.puppetlabs.com/guides/exported_resources.html

http://www.masterzen.fr/2009/03/08/all-about-puppet-storeconfigs/

2
Pascal Schmiel