VPCのVPN状態をCloudWatchカスタムメトリクスを使わずに監視し、異常があればLambdaを使ってChatworkに投稿する仕組みを作ってみた

CloudWatch

どうも!AWS初心者の西村祐二@大阪です。

CloudWatchのメトリクスにVPCのVPN接続がサポートされました!
今までVPCのVPN接続状態を監視するためにはカスタムメトリクスを作りCloudWatchへ情報をとばす必要があったのですが、
それが不要となり簡単に監視することができるようになりました。 今回は前作成したChatworkへアラートをとばす仕組みを利用し VPNに異常があればLambdaを使ってChatworkに通知するものを作ってみようと思います。

どんな監視ができるのか

まず、今回追加された機能を見てみましょう。

マネージメントコンソールへアクセスし、CloudWatchサービスの画面へ移動し「アラームの作成」をクリックします。 スクリーンショット_2017-05-16_14_35_302

VPNの項目「VPNメトリクス」が追加されていることがわかります。 スクリーンショット_2017-05-16_14_35_48

VPNメトリクスを選択すると大きく3つに分類されています。

  • Across All VPN Tunnels

スクリーンショット_2017-05-16_14_48_52

全VPNの「TunnelDataIn」「TunnelDataOut」「TunnelState」の監視ができる模様。
(まとめて監視設定できるのではく、全VPNがDOWNしたらアラート飛ばすイメージ?)

  • VPN Tunnel Metrics

スクリーンショット_2017-05-16_14_49_13

VPNトンネルのグローバルIPアドレス1つずつに
「TunnelDataIn」「TunnelDataOut」「TunnelState」の監視ができる模様。
VPNトンネルの両IPを監視することによって、
・両方UP状態なら冗長状態
・片方DOWNなら縮退状態
など細かな監視もできるかと思われます。

(VPCのVPN接続(ハードウェアVPN接続)ではAWSの冗長性確保の思想により自動的に2つのVPNトンネル(グローバルIPアドレス)が設定されます。そのため、1つのトンネルに障害が発生し使用出来なくなった場合でも、仮想プライベートゲートウェイは自動的にもう1つのトンネルにルーティングします。)

  • VPN Connection Metrics

    スクリーンショット_2017-05-16_14_49_25

それぞれのVPN接続に対して「TunnelDataIn」「TunnelDataOut」「TunnelState」の監視ができる模様。
VPN接続の監視は実際に通信断が発生したかどうか監視できるかと思います。

アラーム設定をしてChatworkに投稿してみる

検証用にVPCのVPN接続環境を作ってみたのですが
うまくUP状態にならず、今回はDOWN状態を検知するのみの検証となります。(もっと勉強します。。)

事前準備

・VPCのVPN環境を用意
下記ページがとても参考になります。

[Amazon VPC] ハードウェアVPN接続を設定する

・SNSとLambdaを使ってChatworkへ投稿する仕組みを用意

下記のページよりSNSとLambdaを使ってChatworkへ投稿する仕組みが作成できます。

Serverless Framework + Lambda(Python) を使ってChatworkにCloudWatchのアラートを投稿

シナリオ1:1つのVPN接続が通信断(DOWN)したときにChatworkへ通知する

VPCのVPN接続のステータス監視アラームを作成

CloudWatchの「アラームの作成」→「VPNメトリクス」→「VPN Connections Metrics」→対象のVpnIdの「TunnelState(TunnelState)」行のチェックボックスにチェックを入れて、「次へ」ボタンクリック。

スクリーンショット_2017-05-16_14_49_252

アラームの定義は下記画像のように設定し「アラーム作成」ボタンをクリック。しばらく待つとChatworkへ通知がきます。

スクリーンショット_2017-05-16_18_51_55

VPN接続は
DOWN時:0
UP時:1
となるので、判定条件「>=0」とき通知を飛ばす設定にしています。(ずっとDOWNしているので)
通知の送信先は前回作成したSNSトッピクスを利用して「sls-cloudwatch」としています。

結果:Chatworkの画面

問題なく通知が来ました!

スクリーンショット_2017-05-16_18_38_52

CloudWatchから取得できたデータ

Lambdaのログを確認すると下記のようなデータが渡ってきました。

{
  'Records': [
    {
      'EventSource': 'aws:sns', 
      'EventVersion': '1.0', 
      'EventSubscriptionArn': 'arn:aws:sns:ap-northeast-1:xxxxxx', 
      'Sns': {
        'Type': 'Notification', 
        'MessageId': 'xxxxxx', 
        'TopicArn': 'arn:aws:sns:ap-northeast-1:xxxxxx', 
        'Subject': 'ALARM: "test" in Asia Pacific - Tokyo', 
        'Message': '{
          "AlarmName":"test",
          "AlarmDescription":"test-vpn",
          "AWSAccountId":"xxxxxx",
          "NewStateValue":"ALARM",
          "NewStateReason":"Threshold Crossed: 1 datapoint (0.0) was greater than or equal to the threshold (0.0).",
          "StateChangeTime":"2017-05-16Txx:xx:xx.xx+0000",
          "Region":"Asia Pacific - Tokyo",
          "OldStateValue":"INSUFFICIENT_DATA",
          "Trigger":{
            "MetricName":"TunnelState",
            "Namespace":"AWS/VPN",
            "StatisticType":"Statistic",
            "Statistic":"AVERAGE",
            "Unit":null,
            "Dimensions":[{
              "name":"VpnId","value":"vpn-xxxxxx"}],
              "Period":60,
              "EvaluationPeriods":1,
              "ComparisonOperator":"GreaterThanOrEqualToThreshold",
              "Threshold":0.0,
              "TreatMissingData":""
              ,"EvaluateLowSampleCountPercentile":""}}'
              ・・・・

シナリオ2:VPN接続の1つのVPNトンネルに障害が発生したときにChatworkへ通知する

VPNトンネル用のグローバルIPアドレスのステータス監視アラームを作成

CloudWatchの「アラームの作成」→「VPNメトリクス」→「VPN Tunnels Metrics」→対象のIPの「TunnelState(TunnelState)」行のチェックボックスにチェックを入れて、「次へ」ボタンをクリック。

スクリーンショット_2017-05-16_14_49_13

アラームの定義は下記画像のように設定し「アラーム作成」ボタンをクリック。しばらく待つとChatworkへ通知がきます。

スクリーンショット_2017-05-16_19_27_02

VPNトンネルもVPN接続と同様に
DOWN時:0
UP時:1?
となるので、判定条件「>=0」とき通知を飛ばす設定にしています。(ずっとDOWNしているので)
通知の送信先は前回作成したSNSトッピクスを利用して「sls-cloudwatch」としています。

結果:Chatworkの画面

こちらも問題なく通知が来ました!対象のIPも取得できています。

スクリーンショット_2017-05-16_18_39_18

CloudWatchから取得できたデータ

Lambdaのログを確認すると前回と同じ構造のデータが渡ってきてました。

{
  'Records': [
    {
      'EventSource': 'aws:sns', 
      'EventVersion': '1.0', 
      'EventSubscriptionArn': 'arn:aws:sns:ap-northeast-1:xxxxxx', 
      'Sns': {
        'Type': 'Notification', 
        'MessageId': 'xxxxxx', 
        'TopicArn': 'arn:aws:sns:ap-northeast-1:xxxxxx', 
        'Subject': 'ALARM: "test-vpnip-status check" in Asia Pacific - Tokyo', 
        'Message': '{
          "AlarmName":"test-vpnip-status check",
          "AlarmDescription":null,
          "AWSAccountId":"xxxxxx",
          "NewStateValue":"ALARM",
          "NewStateReason":"Threshold Crossed: 1 datapoint (0.0) was greater than or equal to the threshold (0.0).",
          "StateChangeTime":"2017-05-16Txx:xx:xx.xxx+0000",
          "Region":"Asia Pacific - Tokyo",
          "OldStateValue":"INSUFFICIENT_DATA",
          "Trigger":{
            "MetricName":"TunnelState",
            "Namespace":"AWS/VPN",
            "StatisticType":"Statistic",
            "Statistic":"AVERAGE",
            "Unit":null,
            "Dimensions":[{
              "name":"TunnelIpAddress",
              "value":"xx.xx.xx.xx"}],
              "Period":60,
              "EvaluationPeriods":1,
              "ComparisonOperator":"GreaterThanOrEqualToThreshold",
              "Threshold":0.0,
              "TreatMissingData":"",
              "EvaluateLowSampleCountPercentile":""}}', 
              ・・・・

おまけ

「Across All VPN Tunnnels」をVPN接続のアラーム設定したときにCloudWatchから取得できたデータ

"Dimensions"が空っぽでデータが渡ってきてました。

{
  'Records': [
    {
      'EventSource': 'aws:sns', 
      'EventVersion': '1.0', 
      'EventSubscriptionArn': 'arn:aws:sns:ap-northeast-1:xxxxxxxx', 
      'Sns': {
        'Type': 'Notification', 
        'MessageId': 'xxxxxxxx', 
        'TopicArn': 'arn:aws:sns:ap-northeast-1:xxxxxxxx', 
        'Subject': 'ALARM: "all-vpn-status-check" in Asia Pacific - Tokyo', 
        'Message': '{
          "AlarmName":"all-vpn-status-check",
          "AlarmDescription":null,
          "AWSAccountId":"xxxxxxxx",
          "NewStateValue":"ALARM",
          "NewStateReason":"Threshold Crossed: 1 datapoint (0.0) was greater than or equal to the threshold (0.0).",
          "StateChangeTime":"2017-05-16Txx:xx:xx.xxxx+0000",
          "Region":"Asia Pacific - Tokyo",
          "OldStateValue":"INSUFFICIENT_DATA",
          "Trigger":{
            "MetricName":"TunnelState",
            "Namespace":"AWS/VPN",
            "StatisticType":"Statistic",
            "Statistic":"AVERAGE",
            "Unit":null,
            "Dimensions":[],
            "Period":60,
            "EvaluationPeriods":1,
            "ComparisonOperator":"GreaterThanOrEqualToThreshold",
            "Threshold":0.0,
            "TreatMissingData":"",
            "EvaluateLowSampleCountPercentile":""}}', 
            .....

まとめ

いかがだったでしょうか。
新しくサポートされたCloudWatchのVPNメトリクスを使って、VPNの状態をChatworkへ通知する仕組みを作ってみました。

VPN接続の状態だけでなく、VPNトンネルのIPの状態も簡単に監視でき、
また、ステータスの他にDataの入出力も監視できるので、簡単かつより詳細に監視する仕組みを作れそうです。