この記事は Puppet Advent Calendar 2015 の11日目の記事です。 昨日は @udzura さんのPuppet - Defined Type の使い所を考える - Qiita でした!
みなさんpuppetizeしてますか!!! 今日は私が普段使っているカスタムfacterをご紹介します。
前提
Master/Agent構成でpuppetを使っておらず、 Standalone構成で使っています。 その上で、以下の様なカスタムfacterを定義しておくと便利なのではないかと思います。
1. environment
環境を定義するカスタムfacterです。 production, staging, などを定義しておくと何かと便利です。 基本的には、FQDNで判別しています。 もっとかっこよく、VMのmetadataとかから取りたいなぁ。っていうかそうしよう!(いま閃いた
environmentって打つのがめんどくさいので env
も定義しています。
Facter.add(:environment) do setcode do case Facter.value(:fqdn) when /jp$|\.jp$/ 'production' when /pb$|\.pb$/ 'staging' when /pbdev$|\.pbdev$/ 'development' else nil end end end Facter.add(:env) do setcode do Facter.value(:environment) end end
2. hieradir
hieraを使う時の :datadir:
に指定する際に使用します。
vagrantとその他の環境でパスが違うので、そこを吸収するために使用しています。
Facter.add(:hieradir) do setcode do if Facter.value(:location) == 'local' # vagrant provisionでのapply実行時に見えるように '/vagrant/hieradata' else # その他は任意のpathに依存したapplyは想定してないので固定 # どうしても変更したいなら # FACTER_hieradir=/path/to # すればよい '/var/puppet/current/hieradata' end end end
3. localipaddress / localipaddress_interface
ローカル側のIPとそのインターフェイス名です。
facterで ipaddress_<インターフェイス名>
で取得できますが、
サーバによってインターフェイス名が違ったりする(例えば、bondを組んでいたり)ので便利です。
localipaddress
Facter.add(:localipaddress) do setcode do interface = Facter.value("localipaddress_interface") ip = Facter.value("ipaddress_#{interface}".to_sym) ip end end
localipaddress_interface
require 'ipaddr' Facter.add(:localipaddress_interface) do setcode do # private network RFC1928 # Vagrant環境はクラスCのみにする def private_network?(ipaddr) iprange = [ IPAddr.new('192.168.0.0/16') ] if Facter.value(:fqdn) !~ /\.pbdev/ iprange.concat([ IPAddr.new('172.16.0.0/12'), IPAddr.new('10.0.0.0/8'), ]) end iprange.any? {|i| i.include? IPAddr.new(ipaddr) } end interfaces = Facter.value(:interfaces).split(',') interfaces.find do |interface| ip = Facter.value("ipaddress_#{interface}".to_sym) # デバイスはあってもIPがついていない場合は次のデバイスに next unless ip private_network? ip end end end
4. location
DCが複数あり、それにより設定を変える必要がある(DNSの向け先とかProxyサーバのIPとか)ため追加しました。 DCが複数なくても、vagrantとDCみたいな定義にすると、vagrantだけ設定を変えるみたいなことが簡単に定義できると思います。
判別はグローバルIPでやっています (以下はマスクしています)
Facter.add(:location) do setcode do # NyahのDBロールはWANを持たせない if Facter.value(:localipaddress_interface) == "eth0" 'nyah' else case Facter.value(:network_eth0) when (DC1のIPアドレス帯) 'DC1' when (DC2のIPアドレス帯) 'DC2' when (DC3のIPアドレス帯) 'DC3' else 'vagrant' end end end end
5. operatingsystemmajrelease
以下のコード内のコメント通りで、facter2.1未満で存在せず未定義の変数となってしまって エラーになってしまうので互換性を保つために定義しています。
# facter2.1未満では存在しないので、 # 下位互換のためにカスタムファクタで定義する Facter.add(:operatingsystemmajrelease) do setcode do Facter.value(:operatingsystemrelease).match(/^\d+/)[0] end end
以上です。 役に立つ情報はありましたでしょうか? これ以外にも便利なカスタムFacterがあったらぜひ教えて下さい 🙇🏻
明日は kijibato さんです!