ItamaeとChefについての比較メモ

Chef Solo がオワコンというので気になってちょっと調べてみた感想。

背景

自分は Chef Solo を Vagrant と組み合わせて誰でも開発環境を作れるように、という目的で使っている。頑張ったのは 2013 年の話。

この時に頑張って以降はたまに pear package の install に失敗するとか、こまごました調整しかしてない。新しめの開発環境はわざわざ OS ごと仮想化しなくてもいいものを採用するので、古いものしかここにはない。これにプラスして Capistrano を導入して、commit されているものが deploy される、を実現した。今思うと遠い昔のようだ。(この春からは一部で GitHub + CircleCI + Heroku で自動 deploy にしている。)

production 環境の provisioning には使っていない。(特に変更を加えていないし、どうしても必要なものは手作業)

気になっていたこと

Itamae は Chef-like DSL というのは分かっていたけど、Chef-like だったらそもそもそんなにシンプルじゃないはずで、違いはどこにあるのか、といった辺りが気になっていた。

分かったこと

Chef は使い始めるのに必要なツールが案外多く、Chef を使いたいのに Knife を振りかざしてて、しかもこの Knife のサブコマンドがまた多くて、これ何やってるんだっけ感が強い。たぶん Rails の generator とかに影響受けてるんだと思うけど、さすがにボリューミーでつらい。

対して Itamae は itamae コマンドが叩ければok. ここのシンプルさはとても偉大だ。

resource を仮想化したあとにコマンドを叩く部分では Specinfra に依存している。この関係性は先にもっと大きく取り上げてよいように思う。自分の場合は Specinfra は Serverspec 用のものだと理解していたので、ちょっと悩んだ。

Specinfra がよくできているおかげで、Itamae で定義されたレシピは local でも ssh を通じた remote 上でも動く。remote には Itamae がインストールされている必要はない。

ということは Chef と同様のレシピがそのまま動くわけではない。Chef はレシピの実行にすべて Ruby が関わっているので、実行時にも Ruby の強力な記述力を活かせる。対して Itamae ではレシピの定義は Ruby だが OS にタッチする操作自体は Ruby で行っていない。ssh コマンド上で実行できる通常の OS のコマンドで実現する必要がある。

自分がそれを特徴的に感じたのは全 resource 共通で使える only_if, not_if 属性。

Chef ではここに文字列だけでなく Ruby の block も使える。Itamae はレシピ適用対象の OS で利用可能なコマンドを文字列で指定する。確かに。これしか方法はない。local でも remote でも使えるようにするための大きなトレードオフだと思う。

そうすると、複雑な条件を書こうと思うと sh script で使う test コマンドが活躍することになる。Ruby DSL で宣言的に記述できるという触れ込みがここで破綻する。ここは急に sh script の文脈になる。

新たに気になったこと

Itamae のドキュメント単体では node や attribute などの知識の補完が難しそう。そうすると結局 Chef のドキュメントに当たるのか、という問題がある。今後のドキュメントの整備が課題か。

まとめ

自分は provisioning の宣言的な記述には YAML より Ruby DSL の方がよいと思っている。Ansible の独自拡張 YAML は disposable infra にはいいかもしれないけど、変更を加えたり冪等性を確保するといった目的には使いにくいように思う。そして開発環境の provisioning は Docker をうまく使わない限りは disposable って難しいんじゃないかなと思っている。(開発環境だからこそ disposable じゃんていう指摘は正しいんだけど、ちょっとした変更のたびにゼロから環境作らなきゃいけなくてそれに長い時間掛かると、更新サボっちゃうでしょ?)

Itamae は Chef が持っている機能のうち DSL を切り出し、agent 的に動いてほしい部分は他のツールを併用して補うようにするなど、上手な割り切り方をしているように思う。何より itamae コマンド一つですぐに試せるのがサイコーによい。

古い環境とか Windows 対応は恐らく Chef の方にまだ一日の長がありそうだが、より新しめの環境にはマッチするのではないか。

ということで、次に新たに OS 丸ごと相手にしなければいけない時には Itamae を検討したい。

参考

Perlリハビリまとめ

最近のリハビリで、だいぶモダンな書き方ができるようになったような気がする。結局今回いじった箇所は全書き換えはしてないんでそんなに新しくなってないんだけど、テストを含めて割と新しい使い方ができるようになった雰囲気。

Perl は後付け後付けで機能を拡張しているうえに古い情報が蔓延していることもあって、きちんと整理された新しい書き方を修得するのにそれなりに時間も掛かるが、古いスクリプトをそのまま動かすこともでき、ちゃんと書き直せば新しい機能の恩恵にも与れるという懐の深さはやはり非常にありがたい。今回初めて Perl 5.8 ならではの機能も試したが、これが出たのがもう5年前ですよ。どうよこの枯れっぷり。PHP に爪のあかを飲ましてやりたい。1

ただ、

  • 標準じゃないモジュールを探しまわるとか
  • リファレンスリファレンスリファレンス

うぜえよ。

CPAN モジュールは多過ぎるしうっかり手を出すと依存関係が面倒くさいし。まぁその辺含めてこうしろと言ってくれる、放任しない教師としてベストプラクティスはみんなにオススメなのかもしれないんだけど。

最後にまとめると、「書き直す機会があればやはり Ruby にしたいという気持ちが強くなった」のは間違いないっす。以前よりは Perl きらいじゃなくなったけどね。それがいちばんの収穫かなぁ。Golf系でない方法でコードを短くしていけばまだそれなりに耐えられるし。多少記法が違ってもコードそのものの見通しのよさには関係ないっつーことか2

[追記] あ。まだ調べてないのがあった。その辺りは、

  • 日付処理は Class::Date
  • 例外処理は Error

にしてみた。

DateTime は確かに便利なんだけど上で書いた依存性地獄に近いので却下。Fink にも deb にもパッケージがあるから扱いは楽だけど、そうでない環境に行ったときを考えると恐ろしい。Class::Date は pure Perl で小さすぎず大きすぎないところがよい。日付計算もできるのであれこれ道具を持ち替える必要がない。時刻の扱いは弱いけど、そのときは時刻だけにフォーカスしたものをまた探せばいいかな。そんなに必要ないと思うけど。ISO 8601 フォーマットって初めて知った。

例外は書き方が Error の方が分かりやすかったのでとりあえず選んでおく3。例外オブジェクトそのものの定義は Exception::Class が書きやすいかもしんないけど、eval して catch してっつーのはちょっと Perl 的すぎる感じがいやだ。Error.pm なら try {} catch with {} finally {} など分かりやすい。

例外オブジェクトはとりあえず Error::Simple を継承した適当なオブジェクトを作っておけばいいんじゃないのかしらんと踏んでいる。この辺、独自の知識やノウハウが必要ないのも Error.pm の方がよさげと判断するところ。ただ継承は Ruby なら class < だけで済むのに Perl だと package ; use base になってしまうというところが邪魔くさいんだけど 。もうそこはしゃあないか。ちっ。

以下は Perl 関連のエントリを並べ直してみたもの。

あと今まで書いたり書かなかったりしてたほんとに細かいけどフツーに使うのは、

  • use lib (@INC をいじる代わり)
  • use base (@ISA をいじる代わり)

これしかし逆に言うと lib とか base とかモジュールの名前としておいしい名前を使えなくなってしまっているのよね。

  • File::Basename
  • File::Spec
  • Cwd qw( realpath )

は必須。strict と warnings も必須。

本格的な Web アプリには使ってないのでその辺は知らない。テンプレートは HTML 目的で書き始めたけど、HTML 以外にも使ってます。

今度こそ最後。テストは個人的には Test::Unit::Case と Test::Unit::Runner を使う。Test::Harness 系というか Test::Simple 系というか、まぁ Test::Base なんだけど、あまりに Perl っぽすぎて独自すぎていやなので。

  1. というか Perl 5 らしい使い方にようやく追いついたのが実情なんだけど、Perl 5 が出たのはすでに10年以上前という… 

  2. 書きやすさは違うけど。モダンな書き方を目指すなら Perl より Ruby の方が短くしやすいし書きやすいと思う。 

  3. 散々ベストプラクティスを持ち上げといて実際自分はその通りにしないあまのじゃくっぷり。 

alog いじりたい

Lightweight Language Day and Night レポート

alog についてはとても軽く触れられているんだけど、

  • プロキシ動作して
  • Web サイトに付箋をはれる

って、wema2 への要望に書いたことそのまんまじゃん! 動いてるならいじりたいよー。これはね、公開サイトに使うんじゃなくて、内部で使うのにいいんですよ。制作中の Web サイトへの修正項目をメモするとか、参考にしているサイトのここに注目! みたいなポイントを書くとか。サイトじゃなくて Web アプリでもいいし、例えば ruby-lang.org のここをこう直せ、とかいう要望を書くために使ってもいいと思うけど。

こういう目的のためには Wiki である必要はないというか、Wiki じゃない方がいいんです。まさにほしかったものそのまま! だと思っているけど、落ち着いて資料読むか。まず。

試したい試したい試したーい。

作者さんの日記にリンクしておこう

いまさら 1.6 ですが何か

つーかアンケート対象の日本 Ruby の会の人らの使用歴長すぎ。

なぜ 1.6 か
本番環境が古いから。(セキュリティ fix は有償で当たってますが。)
1.6 で書くときの参考資料
本家リファレンスと tDiary のコード。正直、今後公開されてるアプリが 1.8 対応ばかりになるとパk(ry …にくくなって困る。

まぁ Ruby は基本的に more better perl というか、伝統的に Perl がよく使われていたシーンで書きやすい Perl としてしか使ってない(今のところそういう方針なの)ので、そんなに困るところはないんだけど。

※ 本番環境を上げなきゃなぁとは思ってますが、具体的なスケジュールはありません。

もっともだなとつくづく思った

若いウチはあまりモノが見えていない方がいい (CNET 梅田blog)

自分で言うのもなんだが自分は「わけ知り」な方だと思う。調べ物はきらいじゃないし、知識欲もあるし、ツボにハマると完全主義な面が顔をのぞかせてえらいことになる。少なくともただのばかではないつもりだ。しかしその反面、あれこれ情報を集めた結果、推進力を失うこともあるし、欲張りすぎてどうにもならなくなることもある。

まず進むこと。

この難しさを近年ようやく実感している。以前は難しいとすら感じていなかった。つまり進もうともがいていなかったっつーことなんだろうと思う。目標よりも障害の方がはっきり見える、そういう生き方をしていたのだろう。それは今も根本的には変わっていない。悪いクセだ。

みんな portal 的なサイトってまだ見てるんだなぁ

なんとなく昨日の analog の結果を見たらアクセスがいつもの3倍も!

なんだそりゃーと思ったらどうやら

@nifty:デイリーポータル Z(なんだこの無駄に改行の多いソースは)

経由がいつものアクセスよりちょっと多いくらいにあった。どうもトップページのトピックスに取り上げられたらしいが、その部分だけバックナンバーがないのでどういう紹介だったのかは分からない。集合写真の撮り方のアクセスだけ異常に多いのでここにリンクを張られたのは間違いないけど。remote host のトップは infoweb.ne.jp だったので @nifty 会員てマメだなぁというか、そんな印象を持ってしまった。

しかし待てよ。計算が合わないな。これの影響でもせいぜい 2倍強にしかならないはずなのに。ロボットのクロールが重なったか?

RDoc と Pdoc

RDoc は Pdoc よりも素朴だ。

  • Pdoc は pod での記述を要求するが、
  • RDoc は # でコメントを書くだけでよい。一部 RD の記法も利用できる。

Pdoc は、

sub method

と同じ

=head1 method()?$

を要求する(余計な空白とか入っちゃだめ)が、

RDoc は、

#
# ここのドキュメント
#
def method

各定義前のドキュメントが自動的に method や class のドキュメントとして採用される

長いドキュメントをソース中に埋め込むには pod 形式を採用している Pdoc の方が向いていると思われる。Ruby にも RD があるからその方がよいのではないかと思うが、# を利用した方が使い始めの敷居が低いのは確かだ。

しかしうらめしいのは RDoc と RDTool を併用できないというところであろう。RDTool が Ruby のドキュメントツールの標準として確立されていなかった(事実上の標準だったかもしれないが)たために、せっかくの RD を活かしきれない形になってしまっているように感じる。LL な人たちはあの # を何行も何行も書くのって苦痛じゃないの? # 形式って自然とコメント書くのが億劫になってよくないと思うのは自分だけなんだろうか?

RDoc の get

本家の sourceforge が Ruby core に取り込まれたので project を inactive にしてしまった。1.6系で RDoc を使いたい場合は

ruby-lang.org の CVSWEB から落とすしかない。

参考

RDoc を使うにはとりあえず

を読むとよい。

しかし

Ruby 1.8 に取り込まれて以降、RDoc は Ruby 1.8 に依存した機能もあるようで、RDoc 使うには 1.8 インストールが最もよい、という結論が出ました。

今日のビックリ

from Rubyコーディング規約

メソッド定義の中にはコメントは記述しない。(コメントが必要だと思われるようなコードにはリファクタリングを行う。)

マジっすか。Ruby の世界は(マテ)割り切りがすごい。でも自分には絶対無理だと思う。コメント書くのが好きだからっつーのもあるかもしんないけど。

[2007-09-11 追記] 中ではなく def の前に RDoc 形式で書くようにすればいい。定義の中に書きたいのはちょっとトリッキーな処理をしているとか、何らかの補足が必要なケース。だから定義中には書かずに済むようなコードを書きましょうということですな。今はそれほどおかしなことではないように感じる。

あとはこの辺は参考にすべきかと思った。

メソッド名は、すべて小文字とし、単語の区切りに`_'を用いる。メソッド名には動詞の原形を使用する。

ファイル名は、すべて小文字とし、単語の区切りに`-'を用いる。また、ファイル中の主な定義クラスの名前を変換したものをファイル名に使用する。(モジュールを名前空間として使用する場合は、ディレクトリを使用して階層構造を表現する。)

これは好きじゃない。まぁ標準のメソッドとの整合性を考えるとしょうがないんだけど。

真偽値を返すメソッド名は、動詞または形容詞に`?'を付け、形容詞に `is_'は付けない。

is_形容詞はなぜ推奨されないのだろう? 長くなるから? 自分は ? が出てくると正規表現の方に意識が引きずられるので ? は極力使いたくない。

About

例によって個人のなんちゃらです