こんにちは!現場を渡り歩くシニアエンジニアの先輩です。
突然ですが、皆さんのチームのJenkins、「誰がいつの間にか設定を変えてしまい、ビルドが突然壊れた」なんていう恐怖体験はありませんか?
GUIでポチポチと設定を変更できるJenkinsは便利ですが、その手軽さゆえに「変更履歴がブラックボックス化する」「誰が何を変えたか分からない」という、CI/CDにおける最大のアンチパターンを生みがちです。
本記事では、Jenkinsの裏側にある設定ファイル(`config.xml`など)をPythonで監視し、変更があれば自動でGitに記録(コミット)した上で、Slackに差分(diff)を飛ばす「要塞化システム」の作り方を手取り足取り伝授します。
これをマスターすれば、明日から「設定の変更迷子」や「原因不明のビルド崩壊」におびえる必要はなくなりますよ。さあ、一緒に極上の自動化の世界へ足を踏み入れましょう!
—
1. ツールの役割:なぜJenkinsの設定監視が必要なのか?
一般的に、JenkinsはCI/CDの中核を担うオーケストレーターです。しかし、多くの現場では「とりあえず動くから」と、マスターノード上で直接ジョブの設定が変更されています。
ここで問題になるのが、「Infrastructure as Code(IaC)からの逆行」です。
コードレビューを通さずに直接本番環境の設定がいじられる状態は、セキュリティ的にも運用の観点からも非常に危険です。本来、Jenkinsの設定もコードとしてバージョン管理されるべきですが、レガシーな環境ではそれが難しいことも多い。
そこで今回のアプローチです。
「人はGUIで直してしまうもの」という現実を受け入れ、その変更を自動で検知してコード化(Git管理)し、チーム全員に監視の目を光らせる」。この仕組みが、あなたの現場を救います。
—
2. 基礎セットアップ:監視の舞台裏を知る
まずは、Jenkinsがどのように設定を保存しているかを知りましょう。
Jenkinsのジョブやシステム設定は、すべてJenkinsのホームディレクトリ(通常 `/var/lib/jenkins` や `~/.jenkins`)の下に、XMLファイルとして保存されています。
例えば、あるジョブの設定は以下のようなパスにあります。
/var/lib/jenkins/jobs/<ジョブ名>/config.xml
今回は、このディレクトリをPythonスクリプトで定期的にスキャンし、前回の状態と比較する仕組みを作ります。
事前準備:必要なPythonライブラリ
今回のスクリプトでは、外部ライブラリを最小限に抑え、標準ライブラリとGit操作用の `gitpython`、そしてSlack通知用の `requests` を使います。以下のコマンドでインストールしておいてください。
pip install GitPython requests
—
3. 実装:変更検知・Git自動化・Slack通知スクリプト
それでは本丸であるPythonスクリプトを公開します。
`jenkins_watcher.py` という名前で保存してください。コード内のコメントをしっかり読みながら、ご自身の環境に合わせてパスを書き換えてくださいね。
import os
import sys
from datetime import datetime
from git import Repo
import requests
==========================================
設定エリア(ご自身の環境に合わせて変更してください)
==========================================
JENKINS_HOME = “/var/lib/jenkins” # Jenkinsのホームディレクトリ
REPO_PATH = “/path/to/your/jenkins-config-repo” # 変更を記録するローカルGitリポジトリのパス
SLACK_WEBHOOK_URL = “https://hooks.slack.com/services/YOUR/WEBHOOK/URL” # SlackのWebhook URL
==========================================
def sync_configs():
“””Jenkinsのホームディレクトリから設定ファイルをGitリポジトリへ同期する”””
if not os.path.exists(REPO_PATH):
print(f”Error: Git repository path not found: {REPO_PATH}”)
sys.exit(1)
repo = Repo(REPO_PATH)
# 簡易的にJenkinsホームから必要な設定XMLをGitリポジトリへコピーする処理
# (実際には rsync や shutil を使って jobs/ 配下の config.xml をまるっと同期します)
os.system(f”rsync -av –delete –include=’/’ –include=’config.xml’ –exclude=” {JENKINS_HOME}/jobs/ {REPO_PATH}/jobs/”)
return repo
def check_and_notify(repo):
“””Gitの差分をチェックし、変更があればコミットしてSlackに通知する”””
# 変更(Untracked / Modified)があるかチェック
if not repo.is_dirty(untracked_files=True):
print(f”[{datetime.now()}] 変更は検出されませんでした。”)
return
# 変更点をステージング
repo.git.add(A=True)
# 差分(diff)を取得してSlack通知用のメッセージを作成
diff_output = repo.git.diff(‘–cached’)
# コミットメッセージの作成
commit_message = f”Auto-backup: Jenkins config changed at {datetime.now().strftime(‘%Y-%m-%d %H:%M:%S’)}”
repo.index.commit(commit_message)
# リモートリポジトリへプッシュ(必要に応じて有効化)
# origin = repo.remote(name=’origin’)
# origin.push()
print(f”[{datetime.now()}] 変更を検知し、コミットしました。”)
# Slackへ通知
send_to_slack(diff_output)
def send_to_slack(diff_text):
“””Slackに検知した差分を送信する”””
# メッセージが長すぎる場合は切り詰める(Slackの制限対策)
if len(diff_text) > 3000:
diff_text = diff_text[:3000] + “\n…(以下略)…”
payload = {
“text”: f”🚨 Jenkinsの設定変更が検知されました!\n\n{diff_text}\n”
}
response = requests.post(SLACK_WEBHOOK_URL, json=payload)
if response.status_code != 200:
print(f”Failed to send Slack notification: {response.status_code}, {response.text}”)
if __name__ == “__main__”:
git_repo = sync_configs()
check_and_notify(git_repo)
—
4. 動作確認(HelloWorld的ステップ)
スクリプトができたら、正しく動くかテストしてみましょう。
1. 手動での設定変更シミュレーション
Jenkinsの適当なジョブの構成画面を開き、説明文(Description)を適当に変更して「保存」を押します。
2. スクリプトの手動実行
python jenkins_watcher.py
3. 結果の確認
- Gitリポジトリ側で `git log` を叩き、自動コミットが生成されていることを確認します。
- Slackチャンネルに、以下のようなリッチな差分(diff)通知が飛んできたら大成功です!
> 🚨 Jenkinsの設定変更が検知されました!
>
> diff –git a/jobs/sample-job/config.xml b/jobs/sample-job/config.xml
> — a/jobs/sample-job/config.xml
> +++ b/jobs/sample-job/config.xml
> @@ -5,3 +5,3 @@
> –
> +
>
—
5. 先輩からの実践アドバイス:運用の極意
このスクリプトをさらに実務で活かすための、シニアならではのハックをいくつか授けます。
- cronで定期実行する
このスクリプトをLinuxの `cron` に登録し、例えば「1時間に1回」あるいは「10分に1回」定期実行させましょう。
/10 /usr/bin/python3 /path/to/jenkins_watcher.py > /dev/null 2>&1
- リモートリポジトリ(GitHub/GitLab)へのプッシュ
サンプルコード内ではコメントアウトしていますが、`repo.remote(name=’origin’).push()` を有効にしておけば、Jenkinsの設定変更履歴がそのままGitHub上で誰でもレビュー可能な資産になります。
- 通知のスパムを防ぐ
もし頻繁にビルド成果物やビルド番号(`nextBuildNumber` など)の変更で差分が出てしまう場合は、スクリプト内の `rsync` や除外設定(`–exclude`)をチューニングして、本当に重要な `config.xml` だけを監視対象に絞るのがコツです。
—
まとめ
今回は、Jenkinsの隠れた設定ファイルをPythonで監視し、変更を自動でGitとSlackに連携する仕組みを解説しました。
これを導入するだけで、チームのセキュリティ意識は劇的に向上し、「誰が変えたっけ?」という不毛な犯人探しから解放されます。自動化の網の目をくまなく張り巡らせて、安心して開発に集中できる環境を自分の手で作り上げましょう。
それでは、あなたのCI/CDパイプラインが今日もスムーズに走り続けることを祈っています!