はじめに

アプリケーションのエンドポイントやURLの監視をCloudWatch Syntheticsで行うことができるそうです。

CloudWatch Syntheticsとは何ぞやについて以下の公式ブログを参照して下さい。
https://aws.amazon.com/jp/blogs/aws/new-use-cloudwatch-synthetics-to-monitor-sites-api-endpoints-web-workflows-and-more/

外部と通信できないクローズドな環境における、CloudWatch Syntheticsでの監視方法について様々な記事を漁ってみたのですが、あまり無いようだったので備忘録として残してみます。

システム構成図

以下のよう構成で実現したいと思います。
今回は飽くまで動作検証という立ち位置です。

代替テキスト

参考URL
https://aws.amazon.com/jp/blogs/mt/monitor-your-private-endpoints-using-cloudwatch-synthetics/
https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_VPC.html#CloudWatch_Synthetics_Canaries_VPC_troubleshoot

構築手順

  1. Canary実行ログ保存用のS3バケットを作成する

  2. プライベートサブネットの作成

  3. VPCエンドポイント(S3,monitor)用セキュリティグループの作成

  4. VPCエンドポイント(S3,monitor)の作成

  5. EC2インスタンス(Webサーバ用)の作成

  6. IAMポリシー、ロールの作成

  7. Syntheticsの設定

  8. 動作確認

1. Canary実行ログ保存用のS3バケットを作成する

Canary実行ログはS3に保存することができます。
バケット名やバージョニング等については適宜、要件に沿うように変更して下さい。

設定項目 設定値 備考
リージョン ap-northeast-1 Canaryと同じリージョンを選択すること
パブリックアクセスをすべてブロック ON

アクセスポリシーに関しては以下を設定します。
bucketnameVPCIDについては適宜修正して下さい。

アクセスポリシー
{
    "Version": "2012-10-17",
    "Id": "Policy1585781604328",
    "Statement": [
        {
            "Sid": "Stmt1585781599291",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": [
                "arn:aws:s3:::<bucketname>",
                "arn:aws:s3:::<bucketname>/*"
            ],
            "Condition": {
                "StringEquals": {
                    "aws:sourceVpc": "<VPCID>"
                }
            }
        }
    ]
}

2. プライベートサブネットの作成

特別な設定はしないので、こちらは割愛します。
新規に作成するなり、流用するなりでOKです。

なお、Canary(Lambda)やVPCエンドポイントも同じプライベートサブネットを利用する(=プライベートIPアドレスを消費する)ので、それらを考慮したアドレスレンジで作成して下さい。

3. VPCエンドポイント(S3,monitor)用セキュリティグループの作成

VPCエンドポイント用のセキュリティグループを事前に用意しておきます。

HTTPSの443ポートを開けましょう。
ソースIPの開け方はできるだけ絞った方が良いと思います。
(私の環境では10.0.3.0/24と10.0.4.0/24がプライベートネットワークのアドレスです)

5.png

4. VPCエンドポイント(S3,monitor)の作成

今回はインターネット接続が無い環境の為、VPCエンドポイントを経由してS3やmonitorのサービスを利用します。
以下の手順に従って、それぞれのVPCエンドポイントを作成して下さい。

なお、Interface型のVPCエンドポイントはお金がかかっちゃうので注意して下さい。

ルートテーブルはプライベートサブネット用のルートテーブルを選択します。
代替テキスト

プライベートDNS名を利用する場合はチェックを入れて下さい。
セキュリティグループには先程作成したものを指定します。
6.png

ポリシーはデフォルトのフルアクセスのままで。
7.png

それぞれのステータスが使用可能になるのを確認します。
8.png

5. EC2インスタンス(Webサーバ用)の作成

ここについても手順は割愛します。
わざわざサーバを起動せず、S3で静的webホスティングさせてSorryページを監視するとかでも検証としては大丈夫だと思います。

一つだけ注意点として、EC2に割り当てるセキュリティグループにはLambdaからのHTTP:80を許可してあげて下さい。

6. IAMポリシー、ロールの作成

Canaryの実態はLambdaとなっています。

Canaryの仕組みとしてLambdaからCloudWatchやS3へアクセスしますので、Lambdaに付与するアクセス権限を事前に作成しておきます。(何故かCanaryの設定画面からIAMロールを新規作成できなかったため)

以下のポリシーが付与されているIAMロールが作成できればOKです。

IAMポリシーその➀
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetBucketLocation"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream",
                "logs:PutLogEvents",
                "logs:CreateLogGroup"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListAllMyBuckets"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Resource": "*",
            "Action": "cloudwatch:PutMetricData",
            "Condition": {
                "StringEquals": {
                    "cloudwatch:namespace": "CloudWatchSynthetics"
                }
            }
        }
    ]
}
IAMポリシーその➁
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents",
                "ec2:CreateNetworkInterface",
                "ec2:DescribeNetworkInterfaces",
                "ec2:DeleteNetworkInterface",
                "ec2:AssignPrivateIpAddresses",
                "ec2:UnassignPrivateIpAddresses"
            ],
            "Resource": "*"
        }
    ]
}

7. Syntheticsの設定

いよいよ本題のSyntheticsを設定していきます。

[CloudWatch]から[Canary]を選択して[Canaryを作成]をクリックします。
9.png

[設計図を使用する]と[ハートビートのモニタリング]を選択します。
10.png

[アプリケーションまたはエンドポイントURL]に構築したwebサーバのIPアドレスを入力します。
12.png

[スクリプトエディタ]には既にコードが記述されています。
黒塗りになっている部分に上記で入力したwebサーバのIPアドレスが自動で記述されます。

なお、[Environment variables]で環境変数を設定できるようです。
13.png

[スケジュール]と[データ保持]でCanaryの実行スケジュールと保持するデータの期間が選択できます。
Canaryがタイムアウトで処理に失敗する場合は、[追加設定]のタイムアウトの時間を延ばすとよさそうです。

とりあえず今回はデフォルトのままにしてみます。
14.png

[データストレージ]には冒頭に作成したS3を、[アクセス許可]には先程作成したIAMロールを指定します。
何故か、新しいロールを作成が選択できません。
15.png

CloudWatch Alarmと連携することができるそうです。
監視結果の通知先として使えそうです。
16.png

オプションの[VPC設定]にてLambdaをVPCに設定することができます。
今回、LambdaはVPC内のプライベートサブネットにアタッチする構成ですので設定していきます。
17.png

[Active tracing]オプションを有効にすると、X-Rayでトレースできるそうです。

一通り設定が完了したら、[Canaryを作成]をポチりしてみましょう。
18.png

裏でLambda作ったりしているので、そこそこ時間がかかるっぽいですね。
19.png

無事に作成されました。
20.png

8. 動作確認

最後に動作確認してみたいと思います。

作成直後に既に動作しているので、しばらく待つと以下のように成功ステータスになります。
以降は設定した間隔(今回は5分間隔)でステータスが更新されていきます。
21.png

ちょろっと中身を見ていきます。

右下に詳細が記載されています。
[Status]がPassedになっていれば、[Destination URL]に存在するwebページ(index.html)が正常にアクセスできていることになります。
23.png

[Screenshots]をクリックすると以下のように監視先のスクリーンショットが表示されます。
24.png

次にCanaryの実行ログの保存先を確認していきます。
以下のように正常にCanaryの実行ログがログストリームとして出力されています。
25.png

S3には実行によって生成されたhtmlファイルやJSONなどが出力されています。
26.png

最後に

以下、構築をしていてハマったポイントです。

・DocumentRootにhtmlファイルを置いておかないとタイムアウトエラーになる
・LambdaもVPCに設定する必要がある
・Canaryはプライベートサブネットに置かなければならない
・EC2のSGにLambdaからのURL監視用の通信(HTTP:80)を許可する必要がある

以上

TOP