walter-logo

 APソリューショングループの相野谷(@ainoya)です.このたびATLと共同で,CIやCDにおけるビルドパイプラインの実行を手助けする小さなツールwalterを開発しました.

開発の動機: Jenkinsプラグインに強く依存するビルドパイプライン設定

 Jenkinsを使ってCIを実現する場合,複数のジョブを繋げて一連の処理フロー(ビルドパイプライン)を作るのが一般的かと思います.Jenkinsには,ビルドパイプラインを構成するための便利なプラグインがあり,これを使って失敗時の実行制御や,ジョブの並列実行制御を簡単に設定できます.

 ところが,こうしたプラグインで実際にCIを運用してみると,ちょっと惜しい点がいくつか出てきました.

  • パイプラインの全体実行フローをJenkins上でしか確認できない
  • Jenkinsジョブを実際にキックするまで動作が確認できない
  • 設定の移行がしづらい.GUI中心で行うビルドパイプライン設定を簡単に他のJenkinsへエクスポートできない
  •  dockerやansibleを使って,サーバ構成をソースコードと同じように集約して管理できているのに,Jenkins上でのビルド設定だけJenkins側に寄ってしまっている….この不満点を解決するために,Goでwalterという小さなツールを書きました.

    walterの概要

     walterというツールでは次のようなことができます;

  • 設定ファイルでのビルドパイプラインの記述: ansible playbookやtravis-ciの設定ファイル(travis.yml)のように,コードベースと同じ管理方法で設定ファイルを扱いやすくする
  • ローカル環境でもビルドパイプラインの実行が可能: CIサーバなしでビルドパイプラインを実行できる
  • シンプルな利用方法: 複雑なGUIや,専用のDSLを理解しなくとも単純な記述でビルドパイプラインが構成できる
  •  walterの動作は単純で,独自の設定ファイル(yaml)に記述した実行ルールにしたがって,ジョブを順番に実行していきます.記述方法はtravis-ciの設定ファイル(travis.yml)に似ていますが,walterではジョブの並列実行処理を簡単に書けるようになっています.

    ユースケース

    walterではpipeline:の下にビルドパイプラインの実行順序と,処理の内容を記述します. 各ジョブの詳細はstageで定義された各プロパティに書いていきます.

    各ジョブの設定を記述するstageは次のプロパティを持っています.

  • stage_name: stageの名前
  • stage_type: stageの記述形式.commandと設定すると,command:プロパティに書いたシステムコマンドを実行する.(省略した場合のデフォルトはcommand)
  • command: ジョブで実行するシステムコマンドの記述
  • run_after: 設定したstageが実行終了した後に実行したいstageを記述します.後述の通り,run_afterに記述したジョブは並列で実行される
  •  具体例として,walterのサンプル設定ファイル(pipeline.yml)を下に示します.

     上記でpipeline.ymlに定義されたビルドパイプラインは下図のように表すことができます. 図に示した通り,pipelineのトップレベルに定義したstageは,それぞれのジョブの終了を待って順番に実行されます.一方,run_afterに記述されたジョブは並列に実行されます.

    walter-pipeline-sample

    その他の実行例として,dockerコンテナをビルドしつつアプリケーションを用意する…というサンプルを用意しています.ご参考にしていただければと思います.

    walterを試してみる

     GitHubでwalterのビルド済みバイナリを配布しているので,これをダウンロードすればwalterを実行できます.試しに,mac環境でwalterを実行してみましょう.

    1. mac用ビルド済みバイナリを取得.
    2. sampleのビルドパイプライン設定ファイルを取得.
    3. walterを実行します.-cオプションで実行対象のビルドパイプライン定義ファイルを指定します.(無指定時のデフォルトは./pipeline.ymlです)

    pipeline-execution

     pipelineで指定した順序通りにstageが実行されたでしょうか?stageの記述や実行順序を変更してみて,挙動が変わるか確かめてみてください.そしてbugが見つかったらissuesまでお願いいたします:-)

    Microservices with walter

     複数のサービス/サーバ群で構成されるアーキテクチャでは,各々のサービス間に依存関係がある場合,それによってデプロイ順序に制約がかかります.もとはモノリシックだったサービスが,分割されて複数サービスとして運用されるようになった場合にありがちです.

     こうした場合にも,前述で説明したwalterの使い方を応用すれば,複数のサービス/サーバ群で構成されるアーキテクチャのビルドパイプラインも楽に記述できます. 下図のように,事前にあるべき必要な2種類のサービスを先にデプロイしておき,それに依存する残りの4種のサービスをデプロイする,といった要件にも対応可能です.

    walter-msa

     複数サーバのプロビジョニングに関しては,ansibleだけでもwait_for記法や並列実行オプションを使えば実現可能です.しかしながら個人的な感覚としては, ansibleは適切な粒度で実行したほうが取り回しがしやすいと考えています.ansibleによるプロビジョニングの実行単位を適度に区切りつつ, walterでそれらの実行単位をつなぎあわせ,制御することで全体構成の見通しを良くするのが狙いです.

    開発の現状と今後の予定

     現状のビルドパイプラインの構成方法に対する不満点を解決するために,walterというツールを書きました.コードの品質はまだまだプロトタイプの状態ですが,エラー処理やリトライ機構などを中心に品質を上げていく予定です.もちろん,社内での実運用を通しての改善も随時フィードバックしていきます.また,さらなる利便性を向上を目指して,

  • ジョブ間のメッセージパッシング機能強化: パイプラインの実装はgoroutineを使っているので,これを活用して各ジョブの実行データの連携を強化する
  • より分かりやすい記述: yaml形式での煩雑な記述からの脱却.ビルドパイプラインの記述方法を見通しの良いものにする(DSLにしたくないが,記述性とのトレードオフを考えたい).
  • ChatOpsとの親和性強化: Slackへの対応,より細やかな通知連携機能の強化
  • Jenkinsとの連携: ビルドパイプライン実行中のジョブ進捗をJenkins(または外部)に適切にフィードバックする仕組み
  • などなど機能の充実に取り組んでいく予定です.

    コードはGitHubで公開しているので,皆様に使っていただき使用感を教えていただければ幸いです.

    TAGS: