ぶていのログでぶログ

思い出したが吉日

puppetでカスタム関数を作る

この記事はPuppet Advent Calendar 2015 の二日目の記事です。 昨日は id:udzura さんのCheferのためのPuppet でした。


みなさんpuppetしてますかー?! 私はpuppetをガリガリ書いています! 最近、mysqlのserver-idを生成する カスタム関数を作りました! 今回は、その知見を共有します。

カスタム関数とは?

ユーザが独自に処理を定義できる、マニフェスト内で使える関数です。 puppetの標準関数では難しいような処理を定義することができます。

server-idの生成

blog.nomadscafe.jp

上記記事を参考に、LAN側のアドレスの第3,4オクテットからserver-idを生成します。 私は、カスタムFacterでLAN側のアドレスを取得できるようにしていて、マニフェスト上では $::localipaddress で参照できるようになっています。 今回はそのカスタムFacterを使って生成したいと思います。

実際のコード

以下のようなコードを、moduleパス配下の puppet/parser/functions 配下に配置します。

$ cat modules/custom/lib/puppet/parser/functions/mysql_server_id.rb
# ref.http://blog.nomadscafe.jp/2011/02/mysqlserver-id.html
module Puppet::Parser::Functions
  newfunction(:mysql_server_id, :type => :rvalue) do |args|
    octet3, octet4 = lookupvar('localipaddress').split('.')[2,3].map(&:to_i)
    octet3 * 256 + octet4
  end
end

mysqL_server_id という名前の関数を定義しています。 :type => :rvalue は戻り値があることを示しています。

カスタム関数内でFacterなどの変数にアクセスする場合は lookupvar を使います。

実行

$ puppet apply --modulepath=modules -e 'notice($::localipaddress) notice(mysql_server_id())'
Notice: Scope(Class[main]): 192.168.69.101
Notice: Scope(Class[main]): 17765
Notice: Compiled catalog for zipper-test.local in environment production in 0.06 seconds
Notice: Finished catalog run in 0.01 seconds

69 * 256 + 101 = 17765 で正しくserver-idが生成されていることがわかります。

カスタムFacterで十分では?

この例では、カスタムFacterでも同じことができます。 その場合、mysqlを使わないサーバでもカスタムFacterが生成されて無駄だなーっと思ったのでカスタム関数にしました。

まとめ

標準関数では難しいような処理をカスタム関数で定義すれば、シンプルにマニフェストを書く事ができるようになると思います。

カスタムFacterとの使い分けが難しいですが、もう少し複雑な処理(公式ドキュメントのサンプルではファイルを開いたりしている)を行う場合は、カスタム関数を使ったほうが柔軟に対応できると思います。

docs.puppetlabs.com