#背景
AWS上にVPC、及びそのVPCへのVPN接続が大量にある。そんな中でVPNが切れたか切れてないかを監視したい。(tunnelのUP数を数える。)
しかしVPNは結構な頻度で増減する。その為、都度ZABBIXにホスト追加したり、Templateにアイテム追加したりとかやってられるか( ゚Д゚)ゴルァ!
そこでZABBIXのAutoDiscovery機能を使い、自動でVPNの監視項目が増える様にする。
構想
ZABBIXに「VPN-Connection」というホストを作る。
このホストに「VPN-Monitoring」Templateを作って付ける。
この「VPN-Monitoring」TemplateにAutoDiscoveryとアイテムのプロトタイプを設定する。
AWS CLIからVPN情報を持ってきて、それをZABBIX Senderで纏めて送る。
利用環境
- 64bit Ubuntu 16.04
- ZABBIX Sever 3.0.2
- ZABBIX Sender 3.0.2
- Python3
ZABBIX Template
「ディスカバリルール」に次の様に設定する。
名前 : vpn.connection.discovery
タイプ : Zabbixトラッパー
キー : vpn.connection.discovery
ディスカバリルール内の「アイテムのプロトタイプ」に次の様な設定を追加。
名前 : Monitoring of {#VPNNAME} - {#VPNID}
タイプ : Zabbixトラッパー
キー : vpn.conn[{#VPNID}]
AutoDiscoveryは、ZABBIX に対して指定されたデータを送信すると働く。この指定されたデータ形式を今回の設定に合わせて書くと次の様な形になる。
{"data":[
{"{#VPNID}":"vpn-1234","{#VPNNAME}":"Tokyo"},
{"{#VPNID}":"vpn-5678","{#VPNNAME}":"Osaka"},
]}
なお、「一個のホストに対して上記のJSONで纏めて送られてきたモノ」が有効なアイテムとして登録される。
つまり上記JSONでは、TokyoとOsakaが登録される。この後NagoyaやFukuokaが増えた場合は、必ず次ぎのような形式で送信する必要がある。
{"data":[
{"{#VPNID}":"vpn-1234","{#VPNNAME}":"Tokyo"},
{"{#VPNID}":"vpn-5678","{#VPNNAME}":"Osaka"},
{"{#VPNID}":"vpn-9876","{#VPNNAME}":"Nagoya"},
{"{#VPNID}":"vpn-4321","{#VPNNAME}":"Fukuoka"},
]}
仮に次ぎの様なJSONを送った場合、TokyoとOsakaは無くなったモノとして扱われ、指定された期日(標準では30日)が過ぎると監視項目が削除される。
{"data":[
{"{#VPNID}":"vpn-9876","{#VPNNAME}":"Nagoya"},
{"{#VPNID}":"vpn-4321","{#VPNNAME}":"Fukuoka"},
]}
AutoDiscovery用データを送るコード
ZBX_SERVER = '123.45.67.89'
ZBX_TARGET_HOST = 'VPN-Monitoring'
# ここで利用する{#VPNID}や{#VPNNAME}等の項目名は、「アイテムのプロトタイプ」の項目名と一致している必要がある。
placelist = ["Tokyo","Osaka","Nagoya"]
vpnidlist = {"Tokyo":"abc", "Osaka":"def", "Nagoya":"ghi"}
proplist = []
for place in placelist :
prop = {
'{#VPNID}':vpnidlist[place],
'{#VPNNAME}':place,
}
proplist.append(prop)
JSONDATA = {}
JSONDATA['data'] = proplist
cmd1 =["/usr/bin/zabbix_sender", "-z", ZBX_SERVER, "-s", ZBX_TARGET_HOST, "-k", "vpn.connection.discovery", "-o", json.dumps(JSONDATA), "-vv"]
result = subprocess.call( cmd1, shell=False )
cmd1 で、ZABBIX Senderから上記の様な形でAutoDiscoveryが機能して、次の様な名前の監視項目が追加される。
Monitoring of Tokyo - abc
これで項目が出来たので、次のように値を送れば良い。
監視結果情報を送るコード
VPN_ID = '監視対象VPNのID'
TUNNEL_UPS = 'Up状態のtunnelの数。AWS CLIで取得。'
KEY = 'vpn.conn[' + VPN_ID + ']'
cmd2 =['/usr/bin/zabbix_sender', '-z', ZBX_SERVER, '-s', ZBX_TARGET_HOST, '-k', KEY, '-o', str(TUNNEL_UPS), '-vv']
result = subprocess.call( cmd2, shell=False )
注意
- cmd1 を実行した後、ZABBIX Sever でAutoDiscoveryが動いて監視項目が追加され、データを登録出来る様になるまで時間が掛かります。なので、cmd1とcmd2の間にスリープを入れるなどして時間を空ける必要があります。
- 今回の場合、cmd2をVPN毎に値を送っていますが、値を纏めて送れば負荷を減らす事が出来ます。