こんにちは!現場のインフラやSREの現場を支えるエンジニアの皆さん、日々の運用作業にお疲れ様です。
「新しいサーバーを100台立てたから、Zabbixにも100台登録しなきゃ……」
「今夜のリリース作業のために、全監視対象のメンテナンスモードをポチポチ手動で有効化するのか……」
そんな絶望的な作業を、画面の前で一人でやっていませんか?
これを手作業でやっているうちは、まだ真のオブザーバビリティへの道半ばです。今回は、Zabbix APIとPythonを組み合わせて、ホストの登録・削除、そしてメンテナンスモードの切り替えを完全に自動化する方法を、現場の知見をたっぷり詰め込んで優しく解説します。
これをマスターすれば、あなたの毎日のルーティン作業は劇的に楽になり、もっと本質的な設計やトラブルシューティングに集中できるようになりますよ。さあ、一緒に扉を開けましょう!
—
1. なぜZabbix APIなのか?(ツールの本質を理解する)
Zabbixは非常に強力なオープンソースの監視ツールですが、標準のWebUIだけで何百台ものサーバーを管理しようとすると、指が何本あっても足りません。
そこで登場するのが Zabbix JSON-RPC API です。
Zabbixの裏側で動いているWebインターフェースは、実はこのAPIを叩いて動いています。つまり、人間がブラウザでポチポチやっている操作は、すべてPythonなどのプログラムからAPI経由で完全に再現できるということです。
APIを使うメリットは主に3つあります:
1. ヒューマンエラーの根絶:手動入力によるホスト名のタイポや、グループの設定ミスが消滅します。
2. IaC(Infrastructure as Code)との融合:TerraformやAnsible、CI/CDパイプラインと連携させ、「サーバー構築と同時にZabbix監視を開始する」という世界が作れます。
3. 爆速の一括処理:メンテナンスモードの切り替えなどを一瞬で全ノードに適用できます。
—
2. 準備:Python環境とAPIの基礎知識
まずは、PythonからZabbix APIを叩くための環境を整えましょう。特別なライブラリは不要で、標準の `requests` ライブラリがあれば十分です。
pip install requests
Zabbix APIの基本構造
Zabbix APIへのリクエストは、すべて HTTP POST で行います。送信するデータ(ペイロード)のフォーマットはJSONで、以下の決まりきった形(JSON-RPC 2.0準拠)をしています。
{
“jsonrpc”: “2.0”,
“method”: “api.string”,
“params”: {
// メソッドごとのパラメータ
},
“auth”: “ここにアクセストークンが入る”,
“id”: 1
}
このシンプルな構造さえ理解していれば、どんな複雑な操作も怖くありません。
—
3. 実装:認証から自動化スクリプトまで
それでは、実際に動くPythonスクリプトを見ていきましょう。
今回は、「認証トークンの取得」「ホストの一括登録」「メンテナンスモードの切り替え」「ホストの削除」を一つの実用的なスクリプトとしてまとめました。
ご自身のZabbixサーバーのURLや認証情報(ユーザー名・パスワード)に合わせて書き換えて使ってください。
import requests
import json
==========================================
設定エリア(環境に合わせて変更してください)
==========================================
ZABBIX_URL = “http://<あなたのZabbixサーバー>/zabbix/api_jsonrpc.php”
ZABBIX_USER = “Admin”
ZABBIX_PASS = “zabbix”
class ZabbixAPIClient:
def __init__(self, url, user, password):
self.url = url
self.auth_token = None
self.request_id = 1
self.authenticate(user, password)
def _send_request(self, method, params):
“””APIリクエストを送信する共通メソッド”””
headers = {‘Content-Type’: ‘application/json-rpc’}
payload = {
“jsonrpc”: “2.0”,
“method”: method,
“params”: params,
“auth”: self.auth_token,
“id”: self.request_id
}
self.request_id += 1
response = requests.post(self.url, data=json.dumps(payload), headers=headers)
res_data = response.json()
# エラーハンドリング
if “error” in res_data:
raise Exception(f”Zabbix API Error [{res_data[‘error’][‘code’]}] {res_data[‘error’][‘message’]}: {res_data[‘error’][‘data’]}”)
return res_data.get(“result”)
def authenticate(self, user, password):
“””1. 認証トークン(Auth Token)の取得”””
print(“[INFO] Zabbixへ認証を試行中…”)
payload = {
“jsonrpc”: “2.0”,
“method”: “user.login”,
“params”: {
“username”: user,
“password”: password
},
“id”: self.request_id
}
response = requests.post(self.url, data=json.dumps(payload), headers={‘Content-Type’: ‘application/json-rpc’})
res_data = response.json()
if “result” in res_data:
self.auth_token = res_data[“result”]
print(f”[SUCCESS] 認証成功! Auth Token: {self.auth_token}”)
else:
raise Exception(“認証に失敗しました。ユーザー名とパスワードを確認してください。”)
def create_host(self, host_name, ip_address, group_id, template_id):
“””2. ホストの自動登録”””
print(f”[INFO] ホスト ‘{host_name}’ ({ip_address}) を登録します…”)
params = {
“host”: host_name,
“interfaces”: [
{
“type”: 1, # 1 = エージェントインターフェース
“main”: 1, # 1 = デフォルト
“useip”: 1, # 1 = IPアドレスを使用
“ip”: ip_address,
“dns”: “”,
“port”: “10050”
}
],
“groups”: [
{“groupid”: group_id}
],
“templates”: [
{“templateid”: template_id}
]
}
result = self._send_request(“host.create”, params)
host_id = result[“hostids”][0]
print(f”[SUCCESS] ホスト登録完了 (Host ID: {host_id})”)
return host_id
def set_maintenance(self, host_ids, maintenance_name, duration_minutes=60):
“””3. メンテナンスモードの切り替え(一括設定)”””
print(f”[INFO] 対象ホスト群のメンテナンスモードを設定します({duration_minutes}分間)…”)
import time
active_since = int(time.time())
active_till = active_since + (duration_minutes 60)
params = {
“name”: maintenance_name,
“active_since”: active_since,
“active_till”: active_till,
“hosts”: [{“hostid”: hid} for hid in host_ids],
“timeperiods”: [
{
“timeperiod_type”: 0, # 0 = 1回限り
“period”: duration_minutes 60
}
]
}
result = self._send_request(“maintenance.create”, params)
print(f”[SUCCESS] メンテナンス設定完了 (Maintenance IDs: {result[‘maintenanceids’]})”)
def delete_host(self, host_id):
“””4. ホストの削除”””
print(f”[INFO] Host ID: {host_id} を削除します…”)
result = self._send_request(“host.delete”, [host_id])
print(f”[SUCCESS] ホスト削除完了 (Host ID: {result[‘hostids’][0]})”)
==========================================
実行スクリプトのメイン処理
==========================================
if __name__ == “__main__”:
try:
# クライアントの初期化(自動でログインが行われます)
zabbix = ZabbixAPIClient(ZABBIX_URL, ZABBIX_USER, ZABBIX_PASS)
# 【例1】ホストの新規登録
# ※ 注意: あらかじめZabbix上に存在する「グループID」と「テンプレートID」を指定してください
TARGET_GROUP_ID = “2” # 例: Linux servers
TARGET_TEMPLATE_ID = “10001” # 例: Template OS Linux
new_host_id = zabbix.create_host(
host_name=”web-server-01″,
ip_address=”192.168.1.50″,
group_id=TARGET_GROUP_ID,
template_id=TARGET_TEMPLATE_ID
)
# 【例2】登録したホストをメンテナンスモードにする
zabbix.set_maintenance(
host_ids=[new_host_id],
maintenance_name=”Emergency Patching – web-server-01″,
duration_minutes=30
)
# 【例3】不要になったホストの削除(コメントアウトを外すと実行されます)
# zabbix.delete_host(new_host_id)
except Exception as e:
print(f”[ERROR] 処理中にエラーが発生しました: {e}”)
—
4. 現場で役立つプロの知見(ハマりどころとTips)
実際にこのスクリプトを現場の環境に投入する際、知っておくべき「生きた知見」をいくつか共有しておきます。
1. IDのハードコードを避ける
今回のサンプルではグループIDやテンプレートIDを直接(`”2″` のように)書いていますが、実際の運用では名前ベースで検索(`hostgroup.get` や `template.get`)を行ってから動的にIDを取得するように実装するのが、メンテナンス性を保つ秘訣です。
2. エラーハンドリングの重要性
Zabbix APIは、存在しないIDを指定したり、すでに登録済みのホスト名を登録しようとすると、明確なエラーコードとメッセージを返してくれます。スクリプト側で `try-except` を必ず組み込み、ログを残すように設計しましょう。
3. WebhookやChatOpsとの連携
このPythonスクリプトを例えば GitHub Actions や Jenkins、社内SlackのBot(ChatOps)からキックできるようにしておけば、「Slackで `/zabbix-maintenance on web-server-01` とつぶやくだけで、自動でAPIが叩かれてメンテナンスモードになる」という、最高にモダンな運用環境が完成します。
—
まとめ
今回は、Zabbix APIとPythonを組み合わせて、ホストの登録・削除、そしてメンテナンスモードの自動化を行う方法を解説しました。
「面倒くさい作業はすべて機械にやらせる」
これこそが、私たちエンジニアが身につけるべき最高のスキルの一つです。最初は難しく感じるかもしれませんが、一度APIの構造を掴んでしまえば、あなたの運用ライフは劇的に変わります。
ぜひ、まずは手元のテスト環境でこのコードを動かしてみてください。
あなたの毎日の作業が、少しでも楽になり、よりクリエイティブな時間に変わることを応援しています!