Recruit Engineers Advent Calendar 2019 の3日目(12/3)のエントリーです。
アプリケーションのテスト、ビルドなどを始め様々な用途で使われるJenkinsですが、私は以下のような運用作業の自動化に利用しています。
- Ansible Playbookの実行
- アプリケーションのリリース
- エラーログの集計と通知
- perfコマンドの実行やJVMのスレッドダンプ取得などの緊急時の作業
- データベースのスキーマ変更
- データベースドキュメントの更新
ここで何が問題になるかというと、手作業でジョブを環境毎に用意する負荷が高く、ミスもしやすいことです。例えば、開発環境でテストした運用ジョブが本番環境には反映されておらず、想定通りに運用できてなかったということが発生します。サービスに影響を与えなくても、後にそのジョブを修正する人が差異に気がついて混乱することもあります。 (お気持ち的なところですが、私はvimとかzshのようにシンプルにテキストエディタで設定できるツールが好きです。そんな自分にとってJenkinsのGUIでのジョブの設定は苦痛に感じます。)
- 運用系のスクリプト(BashやPythonが多い)をGit管理してJenkinsからはそれを呼ぶだけにする。(これは最初からやってた)
- ジョブから環境依存設定を切り出してジョブの設定ファイル (config.xml) をGit管理する & 各環境に自動配置する。
このように環境差異の問題は解決しました。しかし、xmlなので中にPipelineスクリプトが書いてあったりすると特殊文字がエスケープされて絶望的に見づらい状態ですし、手でぽちぽち設定しなければいけないことは変わってません。
実現したいこと:
- Jenkinsのジョブを見やすい形式でGit管理すること
- Gitリポジトリの内容をもとにジョブを自動で配置、更新すること
既にJenkins Configuration as Codeというものがあり、ジョブの自動登録もできそうなのですが、Yamlの中にGroovyを書いて、さらにそのスクリプトの文字列の中にGroovyを書いて…というノリについていけそうになかったので、可能な限りシンプルな仕組みを作ってみることにしました。
その結果がこちらです。 iinm/jenkins-template
使い方は、
- jobsというディレクトリにPipelineスクリプトを配置する。これがそのままジョブになります。
- ビュー(ジョブをグループ化して表示する機能)を使いたければ、viewsというディレクトリにjobs配下のPipelineスクリプトへのシンボリックリンクを配置する。
update_jobs.sh
,update_views.sh
を順に実行してジョブとビューを追加、更新する。- あとは、リポジトリに更新時に
jenkins_update
というジョブが(2),(3)を自動実行する。
という流れになっています。
注意点としては、
update_jobs.sh
を実行すると必ずジョブを一度実行します。なぜこんな作りなのかというと、Pipelineスクリプトで定義したパラメータの設定はJobを実行しないと更新されないからです。(JENKINS-41929)実際のジョブの実行を防ぐために、Pipelineスクリプトの最初のstageで必ずJUST_UPDATE_JENKINSFILE
というパラメータをチェックする必要があります。- ジョブ、ビューの追加、更新は出来ますが削除には対応してません。
ということで、ちょっとBashスクリプトを書いただけですが画面からのジョブ設定から解放されました 🎉