前々から fluentd のプラグインを書いてみようと思っていたので、ec2 の metadata をレコードに追加するようなプラグインを書いてみました。
takus/fluent-plugin-ec2-metadata
プラグインの書き方は @tagomoris 先生の “fluentdのためのプラグインをイチから書く手順(bundler版)” が大変参考になったので、プラグインを書いてみたい人は見るとよさそうです。 あとは、@sonots 先生の fluent-plugin-record-reformer をかなり参考にさせていただいたのと、Ruby 初心者なので“パーフェクトRuby”にもお世話になりました。
なにをするプラグインか?
### Input
foo.bar {"message":"hello ec2!"}
### Output
web.foo.bar {
"role_tag" : "web",
"instance_id" : "i-28b5ee77",
"instance_type" : "m1.large",
"az" : "us-west-1b",
"vpc_id" : "vpc-25dab194",
"message" : "hello ec2!"
}
たとえばこんな感じにレコードを出力してくれます。 先週の月曜日に Immutable Infrastructure Hackathon at :D というイベントをやっていたときに、 EC2 で Immutable Infrastructure 前提ならホスト名ベースででなく EC2 のタグに入れた Role ベースで集計するのがいいのではないか思ったのがきっかけで、 それっぽいプラグインがなかったので作ってみた感じです。
サーバに名前をつけるという行為はもはや古い慣習であり、クラウドネイティブな思考を妨げる足かせになります。
クラウドでは、サーバはソフトウェアのように扱われます。いつでも必要に応じて立ち上げ、不要になれば簡単に削除することができます。 そのような状況で、サーバ1台1台に手動でユニークな名前をつけていくことは、オートスケールをはじめとするクラウドの恩恵を失うことになります。 ではどのようにサーバを管理するべきかというと、DNS で名前をつけるのではなく、 EC2 のタギング機能を使ってサーバの属性を記述し、識別するべきである、と述べられています。
と、@mirakui さんがおっしゃっていたり、
また、ホストがどんどん新しくなるので、負荷観測の連続性をどのように確保するか、などメトリクス情報の保存や可視化に関する課題もあります。
@stanaka さんのブログにも上記のような内容が書いてあり、 AWS 上で fluentd を使っていて EC2 のタグ毎に集計したい場合は役に立つプラグインなのではないかと思っています。
設定ファイル
設定ファイルは下記のような感じで、タグの書き換えに便利な tag_parts もサポートしております。
EC2 のタグのプレースホルダー名は若干悩んだところですが、aws-sdk で返ってくるフィールド名に合わせて tagset_xxx
にしました。
<match foo.**>
type ec2_metadata
aws_key_id YOUR_AWS_KEY_ID
aws_sec_key YOUR_AWS_SECRET/KEY
output_tag ${instance_id}.${tag_parts[0]}
<record>
tag ${tagset_name}
instance_id ${instance_id}
instance_type ${instance_type}
az ${availability_zone}
vpc_id ${vpc_id}
</record>
</match>
今後について
テストコードが EC2 に依存していて TravisCI ではテストできないので、どうしようか考え中です。 CircleCI だとこんなカンジで EC2 にインスタンス立ち上げてよしなにテストしてくれるようなことができそうなので、その辺りを調べてみようかと思っていますが、 これ使ってテストすればいいのではというアイデアがありましたら、教えていただけると大変助かります!
あとは必要最低限のプレースホルダーは用意しましたが、これも使いたいみたいなのがあればお知らせください。 もちろんそのほかのバグ報告や PR もウェルカムです:D