search
LoginSignup
4

More than 5 years have passed since last update.

posted at

updated at

Organization

Facterを単体で使う

Puppet advent calendar 14日目のようです。いつの間にか折り返していました。まだまだ先は長いのじゃ...

今回はFacterの話。

Facterとは

そのノードに関する様々な情報を取得する仕組みです。ChefでいうOhaiです(ここで読者の8割が「あ〜ね」って言う)。

Puppetの依存で入ってくるツールですが、単体でもインストールできます。

$ gem install facter

早速 facter コマンドで使えます。 factor と間違えないこと!

$ facter hostname
web001
$ facter fqdn
web001.example.com

この hostname だの fqdn だのは、Puppetのコードの中ではトップレベルの変数名に対応してくれます。なので、以下のようにいきなり参照できます。

if $::hostname == 'web001' {
  #...
}

利用できるfacterの一覧は単に facter と打てば出てきます。

$ facter | head
architecture => x86_64
augeasversion => 1.1.0
blockdevice_sr0_model => QEMU DVD-ROM
blockdevice_sr0_size => 432128
blockdevice_sr0_vendor => QEMU
blockdevice_vda_size => 85899345920
blockdevice_vda_vendor => 0x1af4
blockdevices => sr0,vda
domain => example.com
facterversion => 2.4.4

JSONなどのフォーマットで取得する

--json というオプションを渡すと出力がJSONフォーマットとなります。ほかに、 --yaml もあるみたいです。また、以下のように複数の値も取れます。

$ facter hostname fqdn ipaddress --json
{
  "hostname": "puppetserver001",
  "fqdn": "puppetserver001.example.com",
  "ipaddress": "192.0.2.1"
}

外部アプリケーション(Fluentdとか)との連携に便利でしょう。

拡張Facterを直接使う

明日から使えるかもしれないカスタムfacter5選 の通り、Facterは拡張して上書きしたり、自分で定義できるのですが、結構テストがめんどくさいものだったりもします。

この場を借りて、実際のサーバーで値を確認する方法を説明します。

例えば以下のような、AWSのインスタンスのタグからDBのロール(masterかslaveか)を取得するようなCustom Facterをテストしたいとします。

require 'puppet'
require 'json'

Facter.add(:db_role) do
  setcode do
    begin
      json = Facter::Core::Execution.exec('/usr/bin/aws ec2 describe-instances --instance-id $( cat /var/lib/cloud/data/instance-id )')
      if !json or json.empty?
        Puppet.notice "Faild to getting db role: maybe instance is not on AWS. skipping."
        'error'
      else
        data = JSON.parse(json)
        current_instance = data["Reservations"][0]["Instances"][0]
        if db_info = current_instance["Tags"].find{|t| t["Key"] =~ /^db_role$/i }
          db_info["Value"]
        else
          'unknown'
        end
      end
    rescue => e
      Puppet.err "Error on getting db role: #{e.class}, #{e.message}. skipping."
      'error'
    end
  end
end

このファイルを、どこでもいいんですが /usr/local/lib/facter/db_role.rb とかに置いておきます。そうすると、 FACTERLIB という環境変数でFacterのロードパスを追加できるので、それで参照可能になります。
FACTERLIB は絶対パスじゃないとダメのようです。要注意)

$ FACTERLIB=/usr/local/lib/facter facter db_role  
slave

なお、Puppet4に付属するFacter 3.1では、 --custom-dir というオプションでも指定可能なようですが、ここではFacter 2.4.x でも互換の挙動を紹介しておきます。

詳細な作り方は公式ドキュメントを。


ということで明日は(明日も...) @kijibato さんです。ご支援感謝。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
4