Amazon VPCでVPNコネクションの状態をAPI監視する

VPCでデータセンターと接続する

Amazon VPCは、仮想プライベートネットワークを構築できるサービスです。プライベートネットワークという名前から、一切インターネットに接続されないネットワークを組むことができます。インターネットに繋げるときにはインターネットゲートウェイ(igw)の設定、バックネットとVPN接続するときにはバーチャルプライベートゲートウェイ(vgw)の設定が必要です。今回はバックネットとの接続状態を監視する小さなプログラムをご紹介します。

VPNコネクションの状態を確認する

VPNコネクションの状態は、AWS管理コンソールのVPC内にあるVPN Connectionsから確認することができます。1つのコネクションには2つのトンネルが張ってありまして、それぞれの状態を確認することができます。グリーン(UP)なら接続OK、レッド(DOWN)なら接続NGです。画面から直ぐに確認できますが、運用を考えるとプログラムでチェックしたいですよね。

未接続の状態

TUNNEL1つ繋がった状態。1つでも通信できます。

TUNNEL2つ繋がった状態。2つ繋がっていれば安心。

VPCのAPIを使う

VPNコネクションの状態を確認するためのコマンドが用意されています。ec2-describe-vpn-connectionsです。早速使ってみましょう。

$ export EC2_URL=https://ec2.ap-northeast-1.amazonaws.com
$ export AWS_ACCESS_KEY=******************
$ export AWS_SECRET_KEY=******************
$ export PATH=$PATH:/opt/aws/bin/:/home/ec2-user/scripts/lib/
$ export EC2_HOME=/opt/aws/apitools/ec2
$ ec2-describe-vpn-connections 
VPNCONNECTION	vpn-XXXXXXXX	available	ipsec.1	cgw-XXXXXXXX	vgw-XXXXXXXX	true
TUNNEL	27.0.1.XXX	UP	Fri Nov 23 10:14:44 UTC 2012		0
TUNNEL	27.0.1.YYY	UP	Fri Nov 23 10:14:36 UTC 2012		0
ROUTE	192.168.100.0/24	static	available

たしかに接続状態を取得できましたね。では次に、UPが含まれている行数を取得してみたいと思います。

$ ec2-describe-vpn-connections | grep TUNNEL | grep UP | wc -l
1

1とでましたね。1つのVPNコネクションが取れる値は、0/1/2のどれかになります。では、この値をCloudWatchにカスタムメトリクスとして上げてみましょう。

$ sudo vi check_vpn_connection.sh
#!/bin/bash
 
IS_CONNECT=$(ec2-describe-vpn-connections | grep TUNNEL | grep UP | wc -l)

INSTANCE_ID=`curl -s http://169.254.169.254/latest/meta-data/instance-id`
INSTANCE_AZ=`curl -s curl http://169.254.169.254/latest/meta-data/placement/availability-zone/`
INSTANCE_REGION=${INSTANCE_AZ%?}

mon-put-data --region $INSTANCE_REGION --metric-name VpnConnection --namespace EC2/VPN --value $IS_CONNECT

これを2分に1回とかCronで回してみてはいかがでしょうか。そして、CloudWatch側では5分の平均が0のときにアラームするとかどうだろう。

*/2 * * * * * check_vpn_connection.sh

それではCloudWatchで統計をみてみましょう。概ね繋がりっ放しですね。おそらくデータのやり取りが無いときにタイムアウトしているかと思います。ここらへんはVPCの設定ではなくルータ側の設定ですね。

おまけ:mon-put-dataの重さに耐えかねる

1分に1回とかCloudWatchにメトリクスを上げるときに標準ツールとして用意されているコマンドを使うと、JVMが裏で走り始めます。毎回新規に立ち上がるので非常に重いです。そこで、軽量なツールを使ってみたいと思います。

botoを使ってカスタムメトリクスを投げる

軽量で軽快というキーワードで思い浮かんだのが、RubyとPython。ということで、今回はPythonでやってみます。

$ sudo vi mon-put.sh
#!/usr/bin/python  
# coding: utf8  
import sys,boto,boto.ec2,datetime
argvs = sys.argv

from boto.ec2.cloudwatch import CloudWatchConnection
AWS_ACCESS_KEY = "******************"
AWS_SECRET_ACCESS_KEY = "******************"
def main():  
  try:
    conn = boto.ec2.cloudwatch.connect_to_region(
      aws_access_key_id=AWS_ACCESS_KEY ,
      aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
      region_name="ap-northeast-1")
    metrics = conn.put_metric_data(argvs[1],
      argvs[2],
      float(argvs[3]),
      datetime.datetime.now(),
      argvs[4],
      None,None)
  except Exception,e:
    print e
    raise

main()

呼び出すときはこんな感じ。

$ ./mon-put.sh EC2/VPN VPNConnection $IS_CONNECT Count

これをやる前JVMはCPU使用率50%でしたがw、Pythonにしたら8%程度になりました。めでたしめでたし。

まとめ

AWSの状態を監視したいとき、まずはAWS APIを活用しましょう。定期的にチェックをしてCloudWatchに上げたり、SNSに通知することで、サーバにログインせずとも詳細な状態を把握することができるようになります。今日から君も非ログイン検査だ!

参考資料

Amazon Virtual Private Cloud FAQ