読者です 読者をやめる 読者になる 読者になる

Jenkinsと完全にサヨナラして、CircleCIに移行した話

CI Jenkins CircleCI

長らくCIはJenkinsを利用して開発をしてきて、Hudson時代からご愛顧してきたのですが、この春から新しくスタートしたプロジェクトではJenkinsを利用しないという決断をしました。

f:id:a-yamada:20150702122832p:plain

Jenkinsとサヨナラした理由

複数プロジェクトで共有して利用するのがツライ

うちの会社では共通で用意されたJenkinsがあって(それなりにスペック高くて、slaveもぶら下がってる)、色々なプロジェクトがそれを利用しています。

このケースの問題点は何よりもランタイムやSDKを共有してしまうことにあります。全てのビルドに副作用を与えることなく、ランタイムやSDKを追加・更新するのが簡単ではありません。それを滞りなくやるには事前にどのビルドが何を使っているかを把握したり、利用者にお伺いを立てたりとかの調整ごとも発生します。

じゃあプロジェクト1つで専有Jenkinsを立てれば解決かというと、影響範囲のスコープは狭められますが決してそれは本質の解決ではありません。

願望:1つのビルドが自由に気軽にランタイムやSDKを選択できて、かつ他のビルドに副作用を起こさない仕組みであること

運用するのがかなりツライ

自分たちのDCやAWS上で構築・運用していかなければならないので、その運用コストは軽視できません。

Jenkinsはただの開発ツールじゃなくて、ライフラインの一つです。リリースをJenkinsに頼っているのであれば、ダウンタイムがあってはいざというときにリリースができなくなって開発に大きな影響を及ぼします。特に弊社はWeb系なので、リリースしたいときにできないとかは致命的。

そのような性質を持つため、Jenkinsの扱いはただの開発ツールの運用じゃなくてproduction運用とほとんど同じだと思ってます。色々監視を入れたり、冗長化したりということが当然必要になってきます。

願望:運用したくない

属人的になりやすいJenkins職人

Jenkinsのビルドを作るのは、ある意味職人的な作業です。単純にタスクをキックするだけであれば簡単ですが、実際にはジョブをモノリシックではなくパイプライン制御をしたり、GitHubからのWebhookを処理したり等、効果的にJenkinsを使うには俗にいうJenkins職人の尽力が欠かせません。

そして、Jenkins職人は設定やジョブの作成だけじゃなく、サーバサイド・インフラの知識もそれなりに求められます。

しかし、実際Jenkinsで運用するジョブはサーバサイド、フロントエンド、ネイティブ、インフラの運用スクリプトの実行等、あまりにも多くの領域にまたがっています。Jenkins職人が全ての領域に精通しているってケースはまず無いので、当然各領域の専門家の協力が必要になります。

となると、それぞれの専門家がジョブを作るにしても、Jenkinsについてそれなりに知っておかねばなりません。Jenkinsを

願望:それぞれの領域の専門家による、自由で気軽なCIを

Jenkinsは最強に汎用性が高くて自由度があると思ってますが、以上のツライ理由がさようならを決めた理由(の一部)です。

こんにちはCircleCI

で、今のプロジェクトではCircleCIを選択しました。

circleci.com

ウチのプロジェクトでは結構評判いいです。最近は結構他のプロジェクトでも使い始めてます。

運用なし

Jenkinsの運用にかけてた人的コストがなくなりました。一度調子悪いときありましたが、それ以降はほとんどダウンタイム無しで稼働しています。

コンテナ数での課金ですが、それなりに札束で叩けばビルドがつまってどうにもならんってことは無いので、札束重要です。

あとは、プロジェクトスタート時から素晴らしいCI環境が既にあるってのはやっぱりいいですね。初速が全然違います。

職人不在

CircleCIはcircle.ymlという設定ファイルでビルドの制御を記述します。リポジトリに置いておく設定ファイルなので、Gitでバージョン管理できます。

また、circle.ymlで全て完結できるので、Jenkinsの操作を覚えてポチポチやるより障壁の低い作業です。

あと何か困ってもコンテナにSSHできるのがめちゃくちゃ便利です。

CircleCIが苦手なところ

もちろん、CircleCIにもその特性上苦手なところがあります。

任意のタイミングでのジョブ実行

Push/Pull Reqeustに反応してジョブが動き出すので、任意のタイミングの実行には向いていません。

任意のタイミングでのDeploy等がそれに該当しますが、今のプロジェクトではHubotにdeployを命令したら、Hubot側でdeployブランチを作ってPushしてくれるようにしています。そのため、その弱点は十分カバー可能です。

コンテナ型ゆえの弱点

CircleCIではジョブ実行毎にコンテナが起動して、終了したら消えます。そのため、コンテナにバンドルされていないSDKツールについてはcircle.ymlでセットアップする必要があります。

キャッシュを利用することで緩和されますが、S3から取ってくる分のオーバヘッドはあります。

その辺の考慮については以前投稿したエントリをご覧ください。

stormcat.hatenablog.com

今のプロジェクトでやってる運用

今のプロジェクトでやってる運用を一部ですが紹介しておきます。

  • Pull Request駆動でのCI
  • サーバサイド(Go+Java)のビルド
  • フロントエンド(Node/TypeScript/React)のビルド
  • Androidのビルド
  • Dockerイメージのビルド+Private Docker Registryへのpush
  • Terraformでのインフラの構築、更新
  • Amazon ECSのTask Definitionの更新、ClusterのServiceのUpdate(今のプロジェクトにおける実質のdeploy)
  • Roadworkerでのドメインの管理、更新
  • ビルド時にAPIドキュメントを自動生成して、Artifactとして保存(staticで見れるようになる)

まとめ

Jenkinsのツライ面が無くなって、今のところはいいことだらけですね。特にJenkinsが無くて困ってることが無いので、このまま突き進みます。

Goodbye Jenkins.