Zabbix APIを用いて監視自動登録できるまで

概要

日々、Zabbixへの監視登録業務を行っているとき、「これって自動化できるんじゃね?」という思いつきで実施した内容のまとめです。
Dockerを用いた検証環境構築から、実際に作ったスクリプトの紹介を行います。

使用技術

  • bash
  • Zabbix API
  • Docker

検証環境構築

まず、手っ取り早く Zabbix の検証環境が欲しかったので、公式が出してるDockerイメージを使って検証用のサーバを構築しました。使ったコマンドは以下になります。

Bash
$ docker run --name zabbix-appliance -t -p 80:80 -d zabbix/zabbix-appliance:latest

上記コマンドを実行したあと、http://localhsot/ にアクセスして、以下の画面が出てきたら無事検証環境が構築できてます。

初期のUsername/Password は Admin/zabbix なので、これを入力してサインイン。あとは、自動登録時に指定するホストなどを作っておきます。今回は以下をテスト用に作りました。

ホストtest_server_web
プロキシtest_proxy
テンプレートPING, SSH, HTTP, HTTPS
アプリケーションHTTPS

自動登録用のスクリプトの動作イメージとしては以下になります。

  • 引数に指定したファイルに記載のFQDNに対して、PING監視、22番ポート応答監視(SSH)、80番ポート応答監視(HTTP)、443番ポート応答監視(HTTPS)を追加。
  • test_server_web に引数に指定したファイルに記載のFQDNに対するhttps://${FQDN}の応答監視を追加。その際、アプリケーションはそれぞれ上記のHTTPSを指定。

検証環境も整ったので、自動登録スクリプトの方に移りたいと思います。

監視自動登録スクリプト

実際に使うスクリプトは以下のとおりです。
Zabbix API では各種操作をする際に、API tokenを発行する必要があります。そのため、get_token.shをまず実行して、そこで得たtokenを使って監視登録を行います。

Bash
#!/bin/bash

source ./zabbix_var

curl -s -H "Content-Type: application/json" -X POST ${ZabbixWeb} -d '
     {
          "jsonrpc": "2.0",
          "method": "user.login",
          "params": {
          "user": "Admin",
          "password": "zabbix"},
          "id": 1
     }' | awk -F '"' '{print $8}'
Bash
#!/bin/bash

### 各種変数読み込み
source zabbix_var

### ZabbixAPIの認証
auth=`bash get_token.sh`

### 引数のチェック
if [ $# != 1 ]; then
    echo "引数の数が不正です"
    exit 1
fi

IFS=

while read line; do

    HostName=`echo $line | awk '{print $1}'`
    IPaddress=`echo $line | awk '{print $2}'`

### アライブ・ポート監視の登録

    curl -d '
    {
        "jsonrpc": "2.0",
        "method": "host.create",
        "params": {
            "host": "'${HostName}'",
            "interfaces": [
                {
                    "type": 1,
                    "main": 1,
                    "useip": 1,
                    "ip": "'${IPaddress}'",
                    "dns": "",
                    "port": "10050"
                }
            ],
            "groups": [
                {
                    "groupid": "'${group_id}'"
                }
            ],
            "proxy_hostid": "'${zabbix_proxy_id}'",
            "templates": [
                {
                    "templateid": "'${SSH_id}'"
                },
                {
                    "templateid": "'${HTTP_id}'"
                },
                {
                    "templateid": "'${HTTPS_id}'"
                },
                {
                    "templateid": "'${PING_id}'"
                }
            ],
            "ipmi_authtype": 0
        },
        "auth": "'${auth}'",
        "id": 1
    }' -H 'Content-Type: application/json' ${ZabbixWeb}

done < $1



Bash
#!/bin/bash

### 各種変数読み込み
source zabbix_var

### ZabbixAPIの認証
auth=`bash get_token.sh`

### 引数のチェック
if [ $# != 1 ]; then
    echo "引数の数が不正です"
    exit 1
fi

IFS=

while read line; do

    HostName=`echo $line | awk '{print $1}'`
    IPaddress=`echo $line | awk '{print $2}'`

    ### ${HostName}_HTTPS の追加

    curl -s -d '{
        "jsonrpc": "2.0",
        "method": "httptest.create",
        "params": {
            "name": "'${HostName}'_HTTPS",
            "hostid": "'${test_server_web_id}'",
            "applicationid": "'${app_HTTPS_id}'",
            "agent": "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)",
            "delay": 120,
            "steps": [
                {
                    "name": "'${HostName}'_HTTPS",
                    "url": "https://'${HostName}'/",
                    "status_codes": "200",
                    "no": 1,
                    "timeout": 60
                }
            ],
            "verify_host": "1",
            "verify_peer": "1"
        },
        "auth": "'${auth}'",
        "id": 1
}' -H "Content-Type: application/json-rpc" ${ZabbixWeb}

done < $1
Bash
#!/bin/bash

### 各種変数読み込み
source zabbix_var

###ZabbixAPIの認証
auth=`bash get_token.sh`

### 引数のチェック
if [ $# != 1 ]; then
    echo "引数の数が不正です"
    exit 1
fi

IFS=

while read line; do

    HostName=`echo $line | awk '{print $1}'`
    IPaddress=`echo $line | awk '{print $2}'`


    ### ${HostName}_HTTPS に対応するトリガー追加

    curl -s -d '{
        "jsonrpc": "2.0",
        "method": "trigger.create",
        "params": {
            "description": "https://'${HostName}'/",
            "expression": "{test_server_web:web.test.fail['${HostName}'_HTTPS].avg(\"420\")}=1",
            "priority": "2",
            "url": "https://'${HostName}'/"
        },
        "auth": "'${auth}'",
        "id": 1
    }' -H "Content-Type: application/json-rpc" ${ZabbixWeb}


done < $1

自動登録スクリプトの説明

上記プログラムにおいて、大事なのは curl で Zabbix サーバに各種情報をポストしている部分です。この部分について、monitoring_web_scenario.shに使われている以下の部分を例にして説明します。

Bash
curl -s -d '{
        "jsonrpc": "2.0",
        "method": "httptest.create",
        "params": {
            "name": "'${HostName}'_HTTPS",
            "hostid": "'${test_server_web_id}'",
            "applicationid": "'${app_HTTPS_id}'",
            "agent": "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)",
            "delay": 120,
            "steps": [
                {
                    "name": "'${HostName}'_HTTPS",
                    "url": "https://'${HostName}'/",
                    "status_codes": "200",
                    "no": 1,
                    "timeout": 60
                }
            ],
            "verify_host": "1",
            "verify_peer": "1"
        },
        "auth": "'${auth}'",
        "id": 1
}' -H "Content-Type: application/json-rpc" ${ZabbixWeb}

上記のコマンドでは curl コマンドを使っているので、用いてるオプションなどを以下に記します。

-dPOSTメソッドでリクエストを送信します。また、ここで指定した値がリクエストボディに入ります。
-Hリクエストヘッダーに使用する値を指定します。

Zabbix APIを通して、Zabbixサーバに監視を登録するには、JSON形式のデータをZabbixサーバに渡してあげる必要があります。つまり、上記のcurlコマンドについては、

リクエストヘッダーに Content-Type: application/json-rpc を指定して、-dオプション以下にあるJSON形式のデータをZabbixサーバにPOSTメソッドでリクエストを送信

という意味になります。詳しくは公式のリファレンスを御覧ください。JSON形式の中身については、各項目の名前にもある通り、ざっと以下のような意味です(数が多いので、少数の項目について説明します)。

methodどのメソッドを使うかを指定。今回はWebシナリオの追加なのでhttptest.create
nameWebシナリオ名
hostidWebシナリオを作成するホストのid
applicationidアプリケーション欄に指定する対象のid
agentURL応答を確認するときのエージェント
delayWebシナリオの実行間隔
stepsWebシナリオに指定するステップの詳細

他の項目については、公式のリファレンスをご覧ください。

まとめ

今回はZabbix APIを使った監視自動登録について説明しました。監視登録作業は、少数であればGUIでポチポチやるのでもよいのですが、100個や1000個の監視を登録したり、定期的に追加・変更する必要があるのであればAPIを用いて一括登録・変更したほうが絶対に良いです。
また、今回は登録する部分だけのスクリプトを紹介しましたが、実務で使う場合だと以下のようなことに注意する必要があります。

  • 想定通りの監視登録ができたかどうかはどうやって保証するか
  • スクリプト実行時にエラーが出た場合、ハンドリングをどうするか
  • あとから作業者や作業内容が追えるようにするにはどうすればいいか

特にエラーハンドリングについては、考えるべきことが多いため難しい問題ですが、より安全を期する場合はそのことも織り交ぜてスクリプトを作成する必要がありますね。

ABOUT US
ルート数学博士 × インフラエンジニア
インフラエンジニアとして日々邁進中。業務で得た知識やIT初級者に役立つ記事、はたまたIT技術の裏に潜む数学理論を解説します。