紙箱

覚えたことをため込んでいく

Atlassian BambooでCI環境を構築する

この記事はもともとTumblrに書いていた自分のブログ記事を転載したものです。投稿日時も当時の投稿日時を再現してあります。

やらないといけないと思いながらも、ずぼらでずっと後回しにしてた、CIサーバ構築作業を最近やりました。というのも、JIRAを契約するついでにお試しに登録していた、Atlassian Bambooのお試し期間が過ぎてしまったから。お試しすらしていない…

とりあえず解約するにしても試してからにしようってことで本腰入れて使ってみることにしました。でも、ネットで検索してもCircleCIいいよってのが多く、Bambooは「どう設定していいのかぱっとみわからなかった」みたいなのが多い印象。

たしかに、ぱっと見どう使っていいのかなんか分かりにくい…

でも、分かってしまえば仕組みは簡単でした。

Bambooって結局なんなのか

Amazon EC2を実行サーバとして利用する、CI環境です。Bamboo上にソースリポジトリと「Builder」や「Tester」の設定をしておくと、ソースをリポジトリにpushすると、Bambooが指定したEC2インスタンスを自動起動して、ソースチェックアウトからビルド&テストしてくれます。EC2インスタンスは自動停止します(これについては後述)

ポイントは

  • AmazonのAMIを指定するとそのサーバを起動して使うので、ビルド&テスト環境を自由に構築できる(自分でEC2上に環境構築して、そのインスタンスからイメージをつくればいいので)。自由度は高い
  • Bambooのコストとは別にEC2のコストがかかる
  • ビルトインで提供されているBuilderとかを使える状況であれば、出来合いのAmazonインスタンスを使えば即使える

って感じですか。 私はClojure+Leiningen+Midjeという環境が必要なので、サーバ設定を自前でできるのはありがたい。使ってみようという気が湧きました。

ただ、ドキュメントが猛烈に分かりにくいように思います。何ヶ所かつまって、検索すると、Atlassian自身のフォーラムに同じ質問が(英語で)上がってて解決したり、みたいなことがけっこうありました。

ワナ

私が一日無駄にしたワナが、Bamboo OnDemand(ダウンロード版)では、Atlassian提供のAmazon EC2イメージを使ってサーバ構築しないと、Bambooが接続するためのエージェントが起動しないってのがよくわかってなくて、それが分からなかったのが

tokyoリージョンにはイメージが提供されてない

ってことがわからなかったからです。なんとかビルドできる環境作っても、エージェント起動開始でずっとPending…ってなって困ってたのですが、そもそもエージェント・プログラムがサーバに入ってないのだからあたりまえです。

でもねえ、「Elastic Bamboo Global Settings」ってところに、いきなりリージョン選べってのがあるんですよ。そりゃTokyo選びませんか?

Global Settings画面 global settings

Bamboo OnDemandを使う場合は、ここは(ちゃんと動く環境ができるまでは)US East (Northern Virginia)固定でOK。デフォルトがたぶんそうなってるので、かえなきゃいいわけです。

すべて動くようになってから、EC2のイメージを(EC2の機能で)Tokyoリージョンにコピーして、Bamboo側もTokyoリージョンに変更、ということは可能ですが、Bambooインスタンスに接続するのはBamboo自身であって、自分でも顧客でもないのだから、インスタンスがTokyoで起動する意味もないわけで、ずっとUS Eastでもいいはず。

US Eastであれば、Bambooの「Image Configurations」画面に、すぐに使用可能なイメージがずらっと表示されます。Tokyoに変えていると、ここが空っぽです(空っぽなので、ほんとはここに既成イメージが表示されるなんてことが想像できない)

image configurations

Elastic Bambooの設定画面でAWS access key idを設定済みであれば、Startボタンを押すと、EC2でインスタンスが起動します。あとはEC2インスタンスにSSHでログインして、ビルド環境を構築した後、EC2側でインスタンスからイメージを作成し、そのイメージを、Image Configurationsに追加してやれば、独自のビルドサーバが作成できます。

ただ、Java+Maven+JUnitとかRubyとかPHPとかは、実はビルドやテストを実行できるだけの設定がすでに既成イメージにされているので、上記から適当にひとつ選んでもいいかもしれません。ただLargeイメージを使う意味がない場合は、既成イメージのAMI idを使って、インスタンスタイプだけをMicroに変更したような定義を一個作った方が、財布に優しいと思います。

ともかく、US Eastリージョンで既成イメージをベースに環境構築する(あるいはそのまま使う)ってことだけ忘れなければ、そんなにはまることなくさっさと動かし始められると思います。ただEC2につないでるだけですから…

EC2インスタンスの自動停止

Bambooの設定に、リモートサーバのエージェントが何分以上アイドルになったらインスタンスを止めるかって設定があって、デフォルトが10分なんですが、10分経っても落ちません。実は、サーバの自動停止にはもうひとつ条件があって、なぜかドキュメントに書いてなくて、AtlassianフォーラムのQ&Aで見つけたのですが…

  • EC2の支払いが最小になるように、EC2の最小課金時間(通常は1時間?)の間は起動し続ける

ということのようです。

EC2のインスタンスは、起動サーバ単位で1時間いくら、なんですが、この1時間というのは「1時間未満はすべて1時間とみなす」という条件がついてます。よって、1分で停止しても1時間分取られます。

Bambooは、ソースがプッシュされるたびに毎度サーバを起動&停止するのではなく、1時間以内であれば、同じインスタンスを使い回そうとします。アイドル時間が10分たっても、1時間以内にまた別のビルド要求が来るかもしれないので、ギリギリまでは起動し続けます。そのまま要求がこないと、最小課金時間が過ぎるちょっと前に(私が見てた限りでは55分くらいで)自動停止します。 なかなかがんばってるなーと思いました。

Capabilityの設定

Bambooに設定できる各種コマンドは「Capability」と呼んで、インスタンス設定画面の既成インスタンス一覧にある「View Capabilities」を押すと、そのイメージにあるコマンド等を設定できます。

Ant, Grails, Maven, Node.js, PHPUnit, JDK, Mercurial, Gitは始めから入っています。あと、設定画面には出ていないけど、サーバにログインしてみると、/optの下に既にJDK8やMaven 3.2が入ってたりもするので、それらは、サーバをいじらずに、Capabilityに定義を追加するだけで、使い始められます。

私はClojureソースをビルドするためにLeiningenをサーバに入れたので、次のように定義を足しました。

leiningen

このようにCapabilityを足すと、この後のタスク設定なんかで、「Leiningen」を選択できるわけです。

ステージとジョブ、タスク

ビルドプランの設定はまあ直感的だと思います。 ステージ・ジョブ・タスクの区別が分かりにくいかなーと思いました。

  • ひとつのプランは複数のステージを持てる
  • ステージは順番に実行される
  • ひとつのステージは複数のジョブを持てる
  • ジョブは 並列に 実行される
  • ジョブは複数のタスクを持てる。
  • タスクは順番に実行される

という構造で、ジョブが並列に実行されるってことだけ分かってればいいかと。

以下の画像では、

  • 「Build Project」という名前のステージが
  • 「Build Source」というひとつのジョブを持っていて、そのジョブが
  • 「Source Code Checkout」「Maven 3.x」「Command」という3つのタスクを持っている

という構造です。

plan

タスクは、Bambooにもともといくつか用意されていて(「Source Code Checkout」とか)、それらを並べるだけでいいです。サーバイメージに自分でインストールしたコマンドについては、「Command」タスクを使って、Executableを指定できます。

こんな感じです。先にCapabilityを設定しているので、コンボボックスでLeiningenを選択できるようになっています。

task settings

上記イメージのように、JVM系コマンドの場合、JAVA_HOMEとPATHをせっていしなくちゃいけません。Bambooエージェント自体はJava 6で動いている(サーバ設定いじると変えられますが、エージェントが起動しなくなります)ので、タスクの設定で、使用したいJVMを指定してください。 上記画像ではJava 8を設定しています。ちなみに、Java 8は既成イメージの始めから入ってました(なぜかCapabilityには入ってないので、自分で足しましたが)

ビルドしたいソースが、チェックアウトしたソースのサブディレクトリの場合は、「Working sub directory」にリポジトリトップからの相対パスを書きます。私の場合、javaソースは「java」というサブディレクトリに、Clojureソースは「clojure」というサブディレクトリに入れているので、「clojure」を指定しています。

言葉で書くと長ったらしいですが、設定自体はさくさく終わります。

あとはビルドプランを一発手動実行して、動くようならOK。リポジトリにソースがプッシュされたら、勝手にビルドが走ります。

Bambooについて日本語で書いてるブログがほとんど見つからなかったので、書いてみました。