ツールを作ろうと思うモチベーションと、作る流れ

以下は完全に自分の独断と偏見で書いており、こうすべき!と押し付けるものでは一切ないことを明記しておきます。また、ツールって言ってるのはコマンドラインツールが主です。

モチベーション

なぜツールを作ろうと思うのか

何かやるのに手数が多い

オペレーションの工数が多くてそれが人間の手作業であるとき、往々にしてミスは発生する。 ヒューマンエラーを極力なくすために、自動化できるところは自動化すべきである。 操作がコード化されたら、その振る舞いに対してテストを書いて検証することもできる。

例えば Auto Scaling Group で管理された + ELB に吊るされた Elasticsearch のノード入れ替えは、以下の手順で行う必要があった(インスタンス起動時に Elasticsearch が立ち上がること + EC2 Discovery を仮定)。

  1. 退役させるノードを1台選ぶ(対象ノード)
  2. 対象ノードを ELB から外す
  3. Draining が終わって完全に外れるまで待つ
  4. (Elasticsearch 1系のみ) 対象ノードの _shutdown API を叩いて、shard が別のノードに退避するのを確認
  5. 対象ノードを Terminate
  6. ASG により新しいノードが追加、shard が配置されるのをされるのを確認
  7. 残りのノードに対して 1. から繰り返す

これを手作業でやると、

  • リクエストを受け付けているのに、ELB から外さずクラスタから外してしまう or Terminate して 503 を返す
  • 複数台一気に Terminate してしまって shard が複製ごと吹っ飛ぶ

ような事故が起こりえる。

AWS も Elasticsearch も API が提供されているので、構築から状態確認まですべてプログラマブルに行える。 こういうのはワンコマンドで完結するよう自動化すべきである。

なお、上記の Elasticsearch ノード入換を自動化するツールは esnctl である。

実行コマンド or API リクエストが複雑

AWS の操作は awscli 経由でできるわけだけど、あれは API の薄いラッパーなので人間にはわかりづらい。 ヒューマンフレンドリーに入力値を与えたい、ヒューマンフレンドリーかつ行指向的に出力したい…

AWS はまだ awscli があるからなんとかなるかもしれないけど、他の SaaS だとコマンドラインツールがなくて SDK しか提供されてない、あるいは SDK すらないことが往々にしてある。 そういう場合は curl その他で頑張ろうとせずに、ツールを書いたほうが楽な気がする。 認証周りが面倒なので。

…とはいえ UNIX 哲学的には、awscli の出力を JSON にした上で jq などのツールをパイプで繋いでいくのが正しい。 でも結局入力がどうにもならないのと、awscli 自体 Python で少々もたつくというのがあって、小さなツールを書くという発想に至ってしまうのであった…。

既存のものが使えないか探す

すでに適切なソリューションがあるのに一から自作するのは無駄なので、まずは既存のプロダクトを徹底的に調査する。 GoogleGitHub で関係ありそうなワードを並べて検索している。 自分の Chrome はアドレスバーで「gh hogehoge」と入力すれば、GitHub で検索できるようにしてある (e.g., gh hogehoge -> https://github.com/search?utf8=%E2%9C%93&q=hogehoge )*1

f:id:dtan4:20170709174052p:plain

関係ありそうなリポジトリがヒットしたら、

  • README
  • 実装言語
  • コード

を読んで、実際に使えるかどうか判断する。 Go などで実装されていてバイナリが配布されていれば、実行が楽なので良い。 そうでなくとも Docker image が配布されていれば、手元の環境によらず実行できるのでよい*2

良さそうなら実際に手元へダウンロードして実行し、挙動を確認する。

あとは

  • コミット履歴
  • “Last commit” の日付
  • スター数
  • 作者

を見る。 特に複数リポジトリヒットしたときは要チェック。

コミット数がある程度積まれており、なおかつ Last commit が直近であれば、継続的にメンテナンスされてるということで順位が上がる。 スター数が多ければ、それだけポピュラーであるかつ各所で使われてる可能性が高いので良い。 あとは作者が(信用できると思う)企業や人、以前使って良かった別プロダクトの作者であれば、多少信用度は上がる。 中身が大切なので参考程度ではあるが。

以上調べてそれでもそのまま使えるものが無ければ、自分でツールを作ることになる。

OSS として作る

自社のビジネスロジックと密結合したものならともかく、大抵のツールは既存のポピュラーなサービス (e.g., AWS, GCP) や OSS (e.g, Kubernetes, Terraform) の上に成り立つものである(自分が作るツールの場合)。 つまり、自分たちだけが使うシステムというよりは、他人・他社も基盤技術として使うソフトウェアの使い勝手を良くするものであることが多い。

自分たちの困っていることは、同じ OSS を使う他の人も困ってるんじゃないか?と思う*3。 なので、いまこの問題を解決するツールを作れば自分たちだけでなく他の人も幸せになれる。 そうして世界の何処かにいる他の人に使ってもらえたら、自分たちの気づかなかったフィードバックやバグ修正をもらえるかもしれない。 あとは公開しておけば、そのまま自社や自分自身のブランディングにもなりえる。

というわけで、ビジネスロジックや機密情報を含まない、公開して会社的に問題ないものは OSS として作るようにしている。 もちろん今の所属先ではこれが認められている。

リポジトリオーナーを自分にするのか会社にするのか

前述したように今はそのへん自由にやってるけど、基準として

  • 自分が一人でサクッと作る -> 自分
  • チームのプロジェクトでやるとかで、自社メンバー複数人で作る -> 会社
    • 社員間でコードレビューを行うような場合

でやってる。 実際はほとんど前者、つまり自分オーナーで公開させてもらってる。

このへん企業によってはルールが決まってそう。

ツール名

プロダクトに名前をつける時に気をつけたいこと - Qiita

ググラビリティ大切。 一方でキラキラしすぎるのも良くない。

言語

適材適所ではあるけど、基本 Go で書いている。 2年前までは Ruby 使ってたけど、2016年に入ったあたりから徐々に乗り換えた。

  • ロスコンパイルできる
    • 社の開発環境は Mac に統一されてるので、それよりは OSS 公開するときのメリットが強い
  • ワンバイナリに収まるので、Homebrew 等での配布が楽
    • 社内向け private tap が存在しており、インストール & アップデートはそれ経由でやる
    • private gem 時代もあったけど、rbenv 下の Ruby バージョンそれぞれに入れないとカレントディレクトリによっては使えない事案が多発した
  • 実行速度
  • 標準ライブラリ・外部ライブラリともに豊富
    • メジャーなサービスなら大抵 SDK が用意されている

という点で選択している。

(ほとんどそんなこと無いけど)SDK がなかったり、あと DSL 自作するような場合は Ruby など他の言語も選ぶ。

作るにあたって

UNIX 哲学を意識してやる。 一つのことをうまくやる、他のプログラムと協調して動くようにする。 例えば世の中には awk, cut, tr, sed, … といった出力加工の便利ツールがたくさんあるので、変にフィルタを実装せずプレーンな出力のみ提供するようにする。

ドキュメントはちゃんと書く。 OSS として作るならもちろんそうだし、社内向けツールも実際のユーザやあとから手を入れる人のことを考えてちゃんと書く。

業務としてやる場合はデッドラインが存在するので、そこは細かいところにこだわり過ぎないようバランス取るようにする。 品質と実装スピードを両方高レベルで担保できるよう腕を磨くのが大切。

そういう意味でも、必要最小限の機能を実装した「小さなツール」を心がけるのは大切。

プロモーション

ツール作っても実際使われなければ無駄なだけなので、特に他人に使ってもらう場合プロモーションはちゃんとする。 社内ツールなら適切な場所(チャットや GitHub Issue)で広報する、OSS ならブログを書く。

同時に、フィードバックもちゃんと受けられるようにしておく。

まとまりがないけど以上。


なぜこんなもの書こうと思ったのか

よく自分の仕事内容の一部として「自動化や開発支援のツールを書いてます」って紹介するけど、どういうモチベーションでツール作ろうと思うのか & どうやっているのかというのをまとめたくなったので書いた。 ろくに文章がまとまってない気がする…。

ところで、こんな文章書いてる時間があるのなら

コードを書けという話ですね。

去年就職してからプライベートでコード書く時間が逓減したけど、最近また週末にもコード書くようになってきたから細々でも維持したい…

おわりに

リポジトリの新鮮度をよくチェックすると言いながら、自作の放置されたプロダクトの存在に心を痛めるのでした。

*1:query: https://github.com/search?utf8=%E2%9C%93&q=%s

*2:Haskell で実装されたツールとかこうなってると個人的には嬉しい。環境構築が面倒なので

*3:Terraforming や Kubernetes 系ツールはこれがでかい