はじめに
業務で新たにVPC → CloudWatch Logsに接続をするVPCエンドポイントを作成したところ、VPC内に既存でCloudWatch Logs APIを使用しているサービスの通信が吸われてしまったので備忘録として残しておきます。
作成の背景
新規作成のLambdaに、①VPC内のRDSに接続してレコード削除➁CloudWatch Logs APIを使用してRDSのCPU使用率を取得するという二つの役割を持たせる為、VPC内にLambdaを配置するVPC Lambdaを作成する事にしました。(今考えるとそもそもの設計が悪い気がする・・・。)
そしてVPC → CloudWatchの接続を可能にするためVPCエンドポイントを作成しました。
しかし、VPCエンドポイントを作成して一週間後「Zabbixでメトリクスが取れていない」という事が判明......
何が起きていたのか
既存のVPC内にCloudWatchを使用してメトリクスを取得し、Zabbixの画面上に表示する機能があったのですが、元々以下の経路をたどっていました。
EC2上のZabbixエージェント → NATゲートウェイ → インターネットゲートウェイ → CloudWatch Logs API
これがVPCエンドポイント作成後、
EC2上のZabbixエージェント → VPCエンドポイント → CloudWatch Logs API(AWS内部ネットワーク経由)
に変更されていました。
そしてそんな影響があるとはつゆも知らない私はEC2 → VPCエンドポイントのSGの設定行っておらず、メトリクスが取得できていなかったんですね。
なぜ経路が変わるのか?
そもそも、boto3クライアントがAWSのAPIを使用する際、内部的にlogs.ap-northeast-1.amazonaws.com
という風なエンドポイントに通信を行っています。
つまりDNSによる名前解決が行われています。ここでAWSドキュメントに以下の記載があります。
インターフェイス VPC エンドポイントを使用して利用可能な AWS のサービスにアクセスする場合は、エンドポイントでプライベート DNS 名をオンにします。プライベート DNS 名をオンにすると、サービスドメイン名のクエリはプライベート IP アドレスに解決されます。これらのプライベート IP アドレスは、インターフェイスエンドポイントに関連付けられた各サブネットに作成した Elastic Network Interface の IP アドレスです。AWS PrivateLink 経由でサービスドメイン名 (例: ec2.us-east-1.amazonaws.com ) を使用して、AWS API 呼び出しを実行することもできます。
プライベート DNS 名がオンになっていない場合、サービスドメイン名またはエンドポイントドメイン名は AWS リージョンのパブリック IP アドレスに解決されます。
ざっくり要約すると、
「VPCエンドポイントを作成した際にプライベートDNSをオンにするよ。プライベートDNS名がオンだとVPCエンドポイントを通るよ。プライベートDNS名がオフの場合はパブリックIPアドレスに名前解決されるよ。」
との事です。
つまり、元々パブリックIPを使用していた経路が自動的にVPCエンドポイントを通る経路に変更されてしまっていたのです。
AWSインフラ、ネットワーク周りの知識とAWSのサービスの知識の複合技が必要になって難しいです・・・。
皆さんは影響調査をしっかりしてSGの設定などを怠らないようにしましょう。
参考資料
AWS公式ドキュメント - How do I use an interface Amazon VPC endpoint to resolve default service domain names?