AWS Trusted Advisor を使って関連づけられていない Elastic IP アドレスが存在する場合に通知してみる

2023.02.12

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

いわさです。

先日こちらの記事を作成した際に大量に Elastic IP アドレスを作成していました。
検証後に Elastic IP アドレスの削除を忘れており関連付けられていない Elastic IP アドレスがいくつか存在している状態になっていました。

Elastic IP アドレスで料金が発生する条件はいくつかあるのですが、どこにも関連付けられていない状態というのは料金が発生する条件のひとつとなっています。

検証環境なので削除し忘れは避けたいなということで何かしら通知をさせる仕組みを考えてみました。
いくつか方法が考えられると思いますが、今回は最初に思いついた AWS Trusted Advisor を利用する方法を確認してみたので結果を紹介します。

Trusted Advisor は関連付けられていない Elastic IP Address をチェックしてくれる

Trusted Advisor のコスト最適化チェック機能のひとつとして関連付けられていない Elastic IP Address を検出することが出来ます。

注意点として Trusted Advisor はサポートプランの利用状況に応じて使用出来る機能に制限があります。
今回利用したいコスト最適化機能を使いたい場合は Business、Enterprise On-Ramp、または Enterprise Support プランが必要となっています。

通常は画面からステータスを更新、あるいはレコメンデーション通知機能を使って一定感覚でメールレポートを受信する機能が備わっています。
今回はよりピンポイントな通知を期待したいので、EventBridge を使ってみます。

Trusted Advisor の EventBridge 機能

Trusted Advisor では EventBridge 経由で特定チェック項目のステータス変更イベントを検出することが出来ます。

上記ドキュメントの記載されているとおりベストエフォートベースでのイベント配信となり、確実に配信される保証はされていませんが、今回のような検証環境で念の為設定しておきたいという程度の温度感であれば利用出来そうです。

早速作ってみましょう。
カスタムイベントでも良いですが、イベントパターンのテンプレートが用意されているのでこちらを使うと便利です。
AWS のサービスで Trusted Advisor を選択するとイベントタイプで「項目の更新ステータスの確認」を選択することが出来ます。
特定のチェックで、対象のチェック項目を選択することが出来ます。

上記で設定されるcheck-nameが対象のチェック項目になるのですが、日本語で設定されているので違和感を感じる方も多いかもしれません。
おそらく日本語マネジメントコンソールの不具合で、このままだと動作しないので修正する必要があります。

イベントパターン上部のサンプルイベントで Trusted Advisor 用のサンプルイベントが用意されています。
イベント名が連番になっているのでひとつづつ確認する必要があるのがちょっとつらいですが、サンプルイベント5が Elastic IP アドレスの関連付けチェックのものでした。

こちらの check-name を使って先程のイベントパターンを以下のように修正しましょう。

{
  "source": ["aws.trustedadvisor"],
  "detail-type": ["Trusted Advisor Check Item Refresh Notification"],
  "detail": {
    "check-name": ["Unassociated Elastic IP Addresses"]
  }
}

あとは適当な SNS トピックを今回は通知先に設定しました。
Trusted Advisor 関係はバージニア北部にリソースを作成する必要があるのでトピックもバージニア北部に用意します。

イベントが発生するタイミングはステータスの更新のタイミング

では試してみます。
まずは関連付けされていない Elastic IP アドレスを作成します。

しかし、作成してしばらく待ってみても通知は発生しませんでした。
Config のようにリソース変化したタイミングでイベントが発生するわけではないです。

では次に Trusted Advisor の画面上でチェック項目のステータス更新を行ってみましょう。
次のアイコンで更新が可能です。

ステータスが更新されると即通知が送信されました。

Trusted Advisor でのイベント通知は項目のステータスが更新されたタイミングと連動しているようです。
まぁよく見るとドキュメントに書いてあるのですが。

EventBridge を使用して、Trusted Advisor のチェックがステータスを変更するときに検出できます。その後、ルールに指定した値のステータスが変更されたときに、EventBridge は、1 つ以上のターゲットアクションを呼び出します。

自動で短い間隔でのステータス更新は難しそう

今回のシナリオであれば 1 日に 1 回くらいチェックしてくれれば十分な気もしますが、短い間隔でチェックしたい時にどうしたら良いのか確認してみました。

まず Trusted Advisor のステータス更新タイミングは FAQ ページに記述があります。

よくある質問 - AWS サポート | AWS

Q: Trusted Advisor の結果はどれぐらい頻繁に更新できますか?

最小更新間隔は、チェックの結果により異なります。個々のチェックをリフレッシュすることも、または [まとめ] ダッシュボードの右上隅にある [すべてを更新] を選択してすべてのチェックを一括で更新することもできます。Trusted Advisor ダッシュボードにアクセスすると、直近の 24 時間以内に更新されなかったチェックは、自動的に更新されます。これには、数分かかる場合があります。チェックタイトルの右側に最新の更新日時が表示されます。また、ビジネス、エンタープライズ On-Ramp、またはエンタープライズサポートのお客様の場合、Trusted Advisor データは毎週自動で更新されます。

ダッシュボードにアクセスしたタイミングで直近の更新がなかった場合、あるいは毎週自動での更新がされるようです。
ただ、画面で更新することは出来たのでどうにか自動化したいところです。

AWS Support API では RefreshTrustedAdvisorCheck を使うことでリフレッシュを行うことが出来るようです。
最初はこれだって感じがしました。

更新にあたって check-id が必要になるので、DescribeTrustedAdvisorChecks で ID を先に取得します。

※取得コマンドの実行結果はこちら
% aws support describe-trusted-advisor-checks --language ja --region us-east-1 | jq -r '.checks[] | [.id, .name] | @csv'
"rSs93HQwa1","Amazon RDS パブリックスナップショット"
"xSqX82fQu","ELB セキュリティグループ"
"aW7HH0l7J9","Auto Scaling の起動設定"
"dx3xfbjfMr","Route 53 トラフィックポリシー"
"gH5CC0e3J9","EBS Cold HDD (sc1) ボリュームストレージ"
"b73EEdD790","Amazon Route 53 フェイルオーバーリソースレコードセット"
"N425c450f2","IAM 証明書ストアの CloudFront 独自 SSL 証明書"
"L4dfs2Q4C5","廃止されたランタイムを使用する AWS Lambda 関数"
"L4dfs2Q4C6","AWS Lambda VPC 対応関数 (マルチ AZ 冗長性なし)"
"cF171Db240","Amazon Route 53 ネームサーバー権限委譲"
"cG7HH0l7J9","EBS マグネティック (スタンダードボリュームストレージ)"
"sU7XX0l7J9","IAM グループ"
"N420c450f2","CloudFront 代替ドメイン名"
"COr6dfpM04","Amazon EBS のプロビジョニング不足のボリューム"
"COr6dfpM03","Amazon EBS の過剰にプロビジョニングされたボリューム"
"jtlIMO3qZM","RDS クラスターパラメータグループ"
"COr6dfpM06","メモリサイズについてプロビジョニング不足の AWS Lambda 関数"
"COr6dfpM05","メモリサイズについて過剰にプロビジョニングされた AWS Lambda 関数"
"f2iK5R6Dep","Amazon RDS Multi-AZ"
"jEhCtdJKOY","RDS サブネットグループあたりのサブネット"
"a2sEc6ILx","ELB リスナーのセキュリティ"
"ePs02jT06w","Amazon EBS パブリックスナップショット"
"R365s2Qddf","Amazon S3 バケットバージョニング"
"Wxdfp4B1L2","AWS Well-Architected パフォーマンス効率化のための高リスク問題"
"Wxdfp4B1L3","AWS Well-Architected セキュリティのための高リスク問題"
"8wIqYSt25K","ELB Network Load Balancer"
"Wxdfp4B1L4","AWS Well-Architected 信頼性のための高リスク問題"
"Wxdfp4B1L1","AWS Well-Architected コスト最適化のための高リスク問題"
"opQPADkZvH","Amazon RDS バックアップ"
"L4dfs2Q3C2","エラー率が高い AWS Lambda 関数"
"L4dfs2Q3C3","過度にタイムアウトが発生している AWS Lambda 関数"
"vjafUGJ9H0","AWS CloudTrail ロギング"
"7fuccf1Mx7","RDS クラスターロール"
"ru4xfcdfMr","Route 53 最大ヘルスチェック数"
"dV84wpqRUs","RDS DB 手動スナップショット"
"xuy7H1avtl","Amazon Aurora DB インスタンスアクセシビリティ"
"0t121N1Ty3","AWS Direct Connect 接続の冗長性"
"RH23stmM01","AWS Resilience Hub の回復スコア"
"RH23stmM02","AWS Resilience Hub ポリシーに違反しています"
"hc0dfs7601","単一の AZ で HSM インスタンスを実行している AWS CloudHSM クラスター"
"DqdJqYeRm5","IAM アクセスキーローテーション"
"7DAFEmoDos","ルートアカウントの MFA"
"tfg86AVHAZ","EC2 セキュリティグループルールの増大"
"kM7QQ0l7J9","VPC インターネットゲートウェイ"
"HCP4007jGY","セキュリティグループ - 制限されていない特定のポート"
"Pfx0RwqBli","Amazon S3 バケット許可"
"Hs4Ma3G191","RDS クラスターのスナップショットとデータベースのスナップショットは、保管中に暗号化されている必要があります"
"Hs4Ma3G192","RDS DB インスタンスは、パブリックアクセスを禁止する必要があります (PubliclyAccessible 設定によって判断されます)"
"Hs4Ma3G193","RDS DB インスタンスでは、保管中の暗号化が有効になっている必要があります"
"Hs4Ma3G194","RDS スナップショットはプライベートである必要があります"
"Hs4Ma3G195","CloudFront ディストリビューションでは、オリジンアクセスアイデンティティが有効になっている必要があります"
"Hs4Ma3G196","AWS Config が有効になっている必要があります"
"B913Ef6fb4","Amazon Route 53 エイリアスリソースレコードセット"
"Hs4Ma3G197","Amazon Elasticsearch Service のドメインでは、保管中の暗号化が有効になっている必要があります"
"Hs4Ma3G198","RDS DB インスタンスでは、削除保護が有効になっている必要があります"
"1iG5NDGVre","セキュリティグループ- 無制限アクセス"
"Hs4Ma3G190","RDS クラスターでは削除保護が有効になっている必要があります"
"nNauJisYIT","Amazon RDS セキュリティグループのアクセスリスク"
"Hs4Ma3G188","GuardDuty が有効になっている必要があります"
"Hs4Ma3G189","RDS DB インスタンスのために拡張モニタリングが設定されている必要があります"
"1e93e4c0b5","Amazon EC2 リザーブドインスタンスのリース有効期限切れ"
"C056F80cR3","Amazon Route 53 高 TTL リソースレコードセット"
"6gtQddfEw6","DynamoDB の読み込みキャパシティ"
"Hs4Ma3G199","データベースのログ記録が有効になっている必要があります"
"XG0aXHpIEt","RDS DB インスタンス"
"wuy7G1zxql","Amazon EC2 アベイラビリティーゾーンのバランス"
"Hs4Ma3G170","S3 Block Public Access 設定が有効になっている必要があります"
"Hs4Ma3G171","S3 バケットはパブリック読み取りアクセスを禁止する必要があります"
"Hs4Ma3G172","S3 バケットはパブリック書き込みアクセスを禁止する必要があります"
"Hs4Ma3G173","S3 Block Public Access 設定は、バケットレベルで有効になっている必要があります"
"Hs4Ma3G174","CodeBuild GitHub または Bitbucket ソースリポジトリの URL は OAuth を使用する必要があります"
"Hs4Ma3G175","CodeBuild プロジェクトの環境変数には、クリアテキストの認証情報が含まれていてはなりません"
"Hs4Ma3G176","ACM 証明書は、指定した期間の経過後に更新される必要があります"
"CLOG40CDO8","Auto Scaling Group ヘルスチェック"
"aW9HH0l8J6","EC2-Classic Elastic IP アドレス"
"wH7DD0l3J9","EBS スループット最適化 HDD (st1) ボリュームストレージ"
"iK7OO0l7J9","ELB Classic Load Balancer"
"DAvU99Dc4C","利用頻度の低い Amazon EBS ボリューム"
"pYW8UkYz2w","RDS マスターあたりのリードレプリカ"
"pR7UU0l7J9","IAM ポリシー"
"eI7KK0l7J9","EBS アクティブなスナップショット"
"Hs4Ma3G166","重要なクラスターイベントのために、RDS イベント通知サブスクリプションが設定されている必要があります"
"Hs4Ma3G167","S3 バケットではサーバー側の暗号化が有効になっている必要があります"
"Hs4Ma3G168","S3 バケットは、リクエストが Secure Socket Layer を使用することを必須化する必要があります"
"Hs4Ma3G169","バケットポリシーで他の AWS アカウントに付与される S3 許可は制限されている必要があります"
"fW7HH0l7J9","Auto Scaling グループ"
"P1jhKWEmLa","RDS 合計ストレージクォータ"
"Hs4Ma3G180","Amazon Elasticsearch Service のドメインエラーの CloudWatch Logs へのログ記録が有効になっている必要があります"
"Hs4Ma3G181","SSL/HTTPS リスナーを使用する Classic Load Balancer は、AWS Certificate Manager によって提供された証明書を使用する必要があります"
"Hs4Ma3G182","Classic Load Balancer のリスナーは、HTTPS または TLS ターミネーションで設定されている必要があります"
"Hs4Ma3G183","Application Load Balancer は、http ヘッダーをドロップするように設定されている必要があります"
"Hs4Ma3G184","Application Load Balancer と Classic Load Balancer のログ記録が有効になっている必要があります"
"Hs4Ma3G185","作成する IAM カスタマーマネージドポリシーでは、サービスのためにワイルドカードアクションを許可してはなりません"
"Hs4Ma3G186","AWS WAF Classic グローバルウェブ ACL ログ記録が有効になっている必要があります"
"Hs4Ma3G187","Amazon Elasticsearch Service のドメインへの接続は、TLS 1.2 を使用して暗号化されている必要があります"
"12Fnkpl8Y5","漏洩したアクセスキー"
"8CNsSllI5v","Auto Scaling グループ リソース"
"k3J2hns32g","利用率が高すぎる Amazon EBS マグネティックボリューム"
"hjLMh88uM8","アイドル状態の Load Balancer"
"Hs4Ma3G177","ロードバランサーに関連付けられた Auto Scaling グループは、ロードバランサーのヘルスチェックを使用する必要があります"
"Hs4Ma3G178","セキュリティグループは、許可されたポートのために無制限の着信トラフィックのみを許可する必要があります"
"BueAdJ7NrP","Amazon S3 バケット ロギング"
"Hs4Ma3G179","SNS トピックは、AWS KMS を使用して保管中に暗号化されている必要があります"
"xdeXZKIUy","ELB クロスゾーン負荷分散"
"gW7HH0l7J9","CloudFormation スタック"
"gI7MM0l7J2","EBS プロビジョンド IOPS SSD (io2) ボリュームストレージ"
"Hs4Ma3G150","Elasticsearch ドメインは、ノード間で送信されるデータを暗号化する必要があります"
"Hs4Ma3G151","重要なデータベースパラメータグループイベントのために、RDS イベント通知サブスクリプションが設定されている必要があります"
"Hs4Ma3G152","重要なデータベースインスタンスイベントのために、RDS イベント通知サブスクリプションが設定されている必要があります"
"EM8b3yLRTr","ELB Application Load Balancer"
"rT7WW0l7J9","IAM サーバー証明書"
"Hs4Ma3G153","RDS インスタンスは、データベースエンジンのデフォルトのポートを使用してはなりません"
"Hs4Ma3G154","重要なデータベースセキュリティグループイベントのために、RDS イベント通知サブスクリプションが設定されている必要があります"
"N415c450f2","CloudFront ヘッダー転送とキャッシュヒット率"
"Hs4Ma3G144","未使用の IAM ユーザー認証情報は削除される必要があります"
"iqdCTZKCUp","ロードバランサー最適化"
"gI7MM0l7J9","EBS プロビジョンド IOPS SSD (io1 ボリュームストレージ)"
"Hs4Ma3G145","Amazon ECS タスク定義には、安全なネットワークモードとユーザー定義が必要です。"
"Ti39halfu8","Amazon RDSアイドル状態のDBインスタンス"
"Hs4Ma3G146","パブリック IP アドレスが ECS サービスに自動的に割り当てられてはなりません"
"j3DFqYTe29","EC2 インスタンスセキュリティグループルールの増大"
"Hs4Ma3G147","Amazon Elasticsearch Service のドメインは VPC 内に存在する必要があります"
"Hs4Ma3G148","Elastic Beanstalk 環境では、拡張ヘルスレポートが有効になっている必要があります"
"Hs4Ma3G149","Elastic Beanstalk マネージドプラットフォームの更新が有効になっている必要があります"
"Cb877eB72b","削除された Amazon Route 53 ヘルスチェック"
"796d6f3D83","コンテンツ配信の最適化 (CloudFront)"
"Hs4Ma3G160","IAM 認証は RDS インスタンス用に設定されている必要があります"
"Hs4Ma3G161","IAM 認証は RDS クラスター用に設定されている必要があります"
"Hs4Ma3G162","RDS の自動マイナーバージョンアップグレードが有効になっている必要があります"
"Hs4Ma3G163","RDS DB クラスターは、タグをスナップショットにコピーするように設定されている必要があります"
"Hs4Ma3G164","RDS DB インスタンスは、タグをスナップショットにコピーするように設定されている必要があります"
"Hs4Ma3G165","RDS インスタンスは VPC にデプロイされている必要があります"
"keAhfbH5yb","RDS イベントサブスクリプション"
"c5ftjdfkMr","DynamoDB の書き込みキャパシティ"
"Hs4Ma3G155","EC2 インスタンスは AWS Systems Manager によって管理される必要があります"
"Cm24dfsM13","Amazon Comprehend エンドポイントアクセスリスク"
"Hs4Ma3G156","Systems Manager によって管理される EC2 インスタンスは、パッチのインストール後にパッチコンプライアンスのステータスが [COMPLIANT] である必要があります"
"ZRxQlPsb6c","使用率の高いAmazon EC2インスタンス"
"Hs4Ma3G157","Systems Manager によって管理される EC2 インスタンスは、関連付けのコンプライアンスのステータスが [COMPLIANT] である必要があります"
"bW7HH0l7J9","Kinesis リージョンあたりのシャード"
"Hs4Ma3G158","SSM ドキュメントはパブリックであってはなりません"
"Cm24dfsM12","Amazon Comprehend 十分に活用されていないエンドポイント"
"Hs4Ma3G159","Elastic File System は、AWS KMS を使用して保管中のファイルデータを暗号化するように設定されている必要があります"
"nO7SS0l7J9","IAM インスタンスプロファイル"
"dx3xfcdfMr","Route 53 ホストゾーン"
"PPkZrjsH2q","Amazon EBS プロビジョンド IOPS (SSD) ボリュームアタッチ設定"
"Hs4Ma3G130","Lambda 関数は、サポートされているランタイムを使用する必要があります"
"Hs4Ma3G131","Lambda 関数のポリシーは、パブリックアクセスを禁止する必要があります"
"Hs4Ma3G132","Database Migration Service のレプリケーションインスタンスがパブリックであってはなりません"
"lN7RR0l7J9","EC2-VPC Elastic IP アドレス"
"Z4AUBRNSmz","関連付けられていない Elastic IP Address"
"dBkuNCvqn5","RDS セキュリティグループあたりの最大認証数"
"H7IgTzjTYb","Amazon EBS スナップショット"
"Hs4Ma3G122","VPC フローログ記録は、すべての VPC で有効になっている必要があります"
"Hs4Ma3G123","EC2 インスタンスは、パブリック IPv4 アドレスを有していてはなりません"
"gjqMBn6pjz","RDS クラスター"
"Hs4Ma3G124","EC2 インスタンスは、インスタンスメタデータサービスバージョン 2 (IMDSv2) を使用する必要があります"
"Hs4Ma3G125","API Gateway は、WAF ウェブ ACL に関連付けられている必要があります"
"Qch7DwouX1","使用率の低い Amazon EC2 インスタンス"
"Hs4Ma3G126","DynamoDB Accelerator (DAX) クラスターは、保管中に暗号化される必要があります"
"Hs4Ma3G127","API Gateway REST および WebSocket API 実行ログ記録が有効になっている必要があります"
"Hs4Ma3G128","API Gateway REST API ステージは、バックエンド認証のために SSL 証明書を使用するように設定されている必要があります"
"Hs4Ma3G129","API Gateway REST API ステージでは、AWS X-Ray トレースが有効になっている必要があります"
"G31sQ1E9U","使用率の低い Amazon Redshift クラスター"
"Hs4Ma3G140","IAM ルートユーザーアクセスキーは存在してはなりません"
"Hs4Ma3G141","MFA は、コンソールパスワードを有するすべての IAM ユーザーのために有効になっている必要があります"
"Hs4Ma3G142","ハードウェア MFA は、ルートユーザーのために有効になっている必要があります"
"Hs4Ma3G143","IAM ユーザーのパスワードポリシーには強力な設定が必要です"
"N430c450f2","オリジンサーバーの CloudFront SSL 証明書"
"3Njm0DJQO9","RDS オプショングループ"
"tV7YY0l7J9","EBS プロビジョンド IOPS (SSD ボリューム集計 IOPS)"
"Hs4Ma3G133","IAM カスタマーマネージドポリシーは、すべての KMS キーで復号アクションを許可してはなりません"
"ty3xfcdfMr","Route 53 再利用可能な委託セット"
"Hs4Ma3G134","IAM プリンシパルは、すべての KMS キーで復号アクションを許可する IAM インラインポリシーを有していてはなりません"
"Hs4Ma3G135","AWS KMS キーは、意図せず削除されてはなりません"
"gfZAn3W7wl","RDS DB セキュリティグループ"
"Hs4Ma3G136","Amazon SQS キューは保管中に暗号化される必要があります"
"Hs4Ma3G137","IAM ポリシーは、完全な「*」管理者権限を許可してはなりません"
"Hs4Ma3G138","IAM ポリシーが IAM ユーザーにアタッチされていてはなりません"
"7qGXsKIUw","ELB Connection Draining"
"Hs4Ma3G139","IAM ユーザーのアクセスキーは、90 日以下の日数ごとにローテーションされる必要があります"
"Hs4Ma3G230","S3 バケットサーバーのアクセスログを有効化する必要があります"
"Hs4Ma3G231","ステートレスネットワークファイアウォールのルールグループは空であってはなりません"
"Hs4Ma3G110","CloudTrail では、保管中の暗号化が有効になっている必要があります"
"UUDvOa5r34","RDS リザーブドインスタンス"
"Qsdfp3A4L1","Microsoft SQL Server 用にオーバープロビジョンされた Amazon EC2 インスタンス"
"oQ7TT0l7J9","IAM ロール"
"Hs4Ma3G229","CloudFront ディストリビューションでは、カスタムオリジンへのトラフィックが暗号化される必要があります"
"Hs4Ma3G108","CloudTrail 証跡は、Amazon CloudWatch Logs と統合されている必要があります"
"Hs4Ma3G109","CloudTrail ログファイルの検証が有効になっている必要があります"
"jL7PP0l7J9","VPC"
"Hs4Ma3G221","OpenSearch のドメインでは、監査ログ記録が有効になっている必要があります"
"Hs4Ma3G100","Amazon SageMaker ノートブックインスタンスは、インターネットに直接アクセスできないようになっている必要があります"
"Hs4Ma3G222","OpenSearch ドメインエラーの CloudWatch Logs へのログ記録が有効になっている必要があります"
"Hs4Ma3G101","Amazon Elastic MapReduce クラスターマスターノードは、パブリック IP アドレスを有していてはなりません"
"Hs4Ma3G223","OpenSearch ドメインでは、ノード間で送信されるデータが暗号化される必要があります"
"Hs4Ma3G102","Amazon Redshift クラスターへの接続は、転送中に暗号化する必要があります"
"Hs4Ma3G224","OpenSearch ドメインは VPC 内に存在している必要があります"
"Hs4Ma3G103","Amazon Redshift クラスターは、パブリックアクセスを禁止する必要があります"
"Hs4Ma3G225","OpenSearch Service ドメインでは、保管中の暗号化が有効化されている必要があります"
"Hs4Ma3G104","Redshift クラスターは、拡張 VPC ルーティングを使用する必要があります"
"Hs4Ma3G226","Auto Scaling グループの起動設定を使用して起動された Amazon EC2 インスタンスには、パブリック IP アドレスを使用しないでください"
"Hs4Ma3G105","Amazon Redshift では、メジャーバージョンへの自動アップグレードが有効になっている必要があります"
"Hs4Ma3G227","CloudFront ディストリビューションでは、カスタム SSL/TLS 証明書が使用される必要があります"
"Hs4Ma3G106","Amazon Redshift クラスターでは、監査ログ記録が有効になっている必要があります"
"Hs4Ma3G228","CloudFront ディストリビューションでは、HTTPS リクエストを処理するために SNI が使用される必要があります"
"Hs4Ma3G107","CloudFront ディストリビューションでは、転送中の暗号化が必須になっている必要があります"
"S45wrEXrLz","VPN トンネルの冗長化"
"Hs4Ma3G120","停止した EC2 インスタンスは、指定した期間が経過すると削除される必要があります"
"Hs4Ma3G121","EBS のデフォルト暗号化が有効になっている必要があります"
"Hs4Ma3G119","EBS ボリュームは、EC2 インスタンスにアタッチされている必要があります"
"4g3Nt5M1Th","AWS Direct Connect 仮想インターフェイスの冗長性"
"Hs4Ma3G232","RDS データベースクラスターでは、カスタムの管理者ユーザー名が使用される必要があります"
"Hs4Ma3G111","CloudTrail が有効になっており、少なくとも 1 つのマルチリージョンの証跡で設定されている必要があります"
"Hs4Ma3G233","RDS データベースインスタンスでは、カスタム管理者ユーザー名を使用する必要があります"
"Hs4Ma3G112","Secrets Manager のシークレットは、指定された日数以内にローテーションされる必要があります"
"Hs4Ma3G113","自動ローテーションが設定された Secrets Manager のシークレットは、正常にローテーションされる必要があります"
"Hs4Ma3G114","未使用の Secrets Manager のシークレットを削除してください"
"Hs4Ma3G115","Secrets Manager のシークレットでは、自動ローテーションが有効になっている必要があります"
"jEECYg2YVU","RDS DB パラメータグループ"
"Hs4Ma3G116","EBS スナップショットは、パブリックであってはなりません (誰でも復元できるかどうかによって判断されます)"
"Hs4Ma3G117","アタッチされた EBS ボリュームは、保管中に暗号化されている必要があります"
"dYWBaXaaMM","RDS サブネットグループ"
"Hs4Ma3G118","VPC のデフォルトのセキュリティグループは、インバウンドトラフィックおよびアウトバウンドトラフィックを許可してはなりません"
"MDBdfsQ401","Amazon MemoryDB マルチ AZ クラスター"
"0Xc6LMYG8P","EC2 オンデマンドインスタンス"
"Bh2xRR2FGH","Amazon EC2 から EBS スループット最適化"
"ECHdfsQ402","Amazon ElastiCache マルチ AZ クラスター"
"Hs4Ma3G207","EC2 サブネットは、パブリック IP アドレスを自動的に割り当ててはなりません"
"Hs4Ma3G208","EC2 インスタンスは複数の ENI を使用してはなりません"
"Hs4Ma3G209","未使用のネットワークアクセスコントロールリストは削除される必要があります"
"iH7PP0l7J9","EC2 リザーブドインスタンスのリース"
"Hs4Ma3G200","CloudFront ディストリビューションには、デフォルトのルートオブジェクトが設定されている必要があります"
"Hs4Ma3G201","CloudFront ディストリビューションでは、WAF が有効になっている必要があります"
"Hs4Ma3G202","API Gateway REST API キャッシュデータは、保管中に暗号化される必要があります"
"Hs4Ma3G203","Amazon Elasticsearch Service のドメインでは、監査ログ記録が有効になっている必要があります"
"Hs4Ma3G204","セキュリティグループは、リスクの高いポートへの無制限アクセスを許可してはなりません"
"Hs4Ma3G205","HTTPS/SSL リスナーを備えた Classic Load Balancer は、強力な設定を持つ事前定義されたセキュリティポリシーを使用する必要があります"
"51fC20e7I2","Amazon Route 53 レイテンシーリソースレコードセット"
"Hs4Ma3G206","Amazon EC2 は、Amazon EC2 サービス用に作成された VPC エンドポイントを使用するように設定する必要があります"
"hJ7NN0l7J9","SES 日次送信クォータ"
"dH7RR0l6J3","EBS 汎用 SSD (gp3) ボリュームストレージ"
"dH7RR0l6J9","EBS 汎用 SSD (gp2) ボリュームストレージ"
"zXCkfM1nI3","IAM の使用"
"8M012Ph3U5","AWS Direct Connect ロケーションの冗長性"
"Hs4Ma3G220","OpenSearch ドメインへの接続は TLS 1.2 を使用して暗号化する必要があります"
"Hs4Ma3G218","CodeBuild プロジェクト環境では、特権モードを有効化してはなりません"
"Yw2K9puPzl","IAM パスワードポリシー"
"Hs4Ma3G219","Amazon Redshift クラスターでは、デフォルトの管理者ユーザー名を使用しないでください"
"dx8afcdfMr","Route 53 トラフィックポリシーのインスタンス"
"c9D319e7sG","Amazon Route 53 MX リソースレコードセットと Sender Policy Framework"
"Qsdfp3A4L4","Microsoft Windows Server を使用する Amazon EC2 インスタンスのサポートの終了"
"Qsdfp3A4L3","Microsoft SQL Server を使用する Amazon EC2 インスタンスのサポートの終了"
"Qsdfp3A4L2","Microsoft SQL Server 向けの Amazon EC2 インスタンスの統合"
"Hs4Ma3G210","CloudFront ディストリビューションでログ記録が有効になっている必要があります"
"Hs4Ma3G211","バージョニングが有効化されている S3 バケットでは、ライフサイクルポリシーが設定されている必要があります"
"Hs4Ma3G212","S3 バケットでイベント通知が有効になっている必要があります"
"Hs4Ma3G213","S3 アクセスコントロールリスト (ACL) は、バケットへのユーザーアクセスを管理するために使用してはなりません"
"Hs4Ma3G214","ネットワーク ACL で、0.0.0.0/0 から 22 番ポートまたは 3389 番ポートへの入力トラフィック (イングレス) が許可されてはなりません"
"Hs4Ma3G215","未使用の EC2 セキュリティグループは削除する必要があります"
"Hs4Ma3G216","ECR リポジトリでは、少なくとも 1 つのライフサイクルポリシーが設定されている必要があります"
"qS7VV0l7J9","IAM ユーザー"
"Hs4Ma3G217","CodeBuild プロジェクト環境にはログ記録設定が必要です"

「関連付けられていない Elastic IP Address」の ID が Z4AUBRNSmz ということがわかりました。
refresh-trusted-advisor-checkしてみましょう。

% aws support refresh-trusted-advisor-check --check-id Z4AUBRNSmz --region us-east-1        
{
    "status": {
        "checkId": "Z4AUBRNSmz",
        "status": "success",
        "millisUntilNextRefreshable": 14967924
    }
}
% aws support describe-trusted-advisor-check-result --check-id Z4AUBRNSmz --region us-east-1
{
    "result": {
        "checkId": "Z4AUBRNSmz",
        "timestamp": "2023-02-12T10:23:52Z",
        "status": "warning",
        "resourcesSummary": {
            "resourcesProcessed": 1,
            "resourcesFlagged": 1,
            "resourcesIgnored": 0,
            "resourcesSuppressed": 0
        },
        "categorySpecificSummary": {
            "costOptimizing": {
                "estimatedMonthlySavings": 0.0,
                "estimatedPercentMonthlySavings": 0.0
            }
        },
        "flaggedResources": [
            {
                "status": "warning",
                "region": "ap-northeast-1",
                "resourceId": "wunoH9bgPeLnVF4bgryLLps4vwDA7UxCbZJpM6HnmZI",
                "isSuppressed": false,
                "metadata": [
                    "ap-northeast-1",
                    "52.68.55.136"
                ]
            }
        ]
    }
}

millisUntilNextRefreshableは次にリフレッシュ出来るようになるミリ秒を指していて、約 4 時間後のようです。
このコマンドを実行しても現時点ではメールは通知されませんでした。

項目ごとにここで必要な間隔は変わるようなのですが、これだとすぐにリフレッシュは出来ないですね。
ただし、describe-trusted-advisor-check-resultの結果としては新しい推奨項目が取得は出来ています。

ちなみに、この状態で画面上から Trusted Advisor で項目のステータス更新を行うとすぐに通知メールが送信されました。うーむ。

画面で更新するときとイベントが違う

CloudTrail を確認してみたのですが、画面でステータス更新した時は RefreshCheck が実行されていました。

調べてみたところ、これは API や AWS CLI からは呼び出すことが出来ない操作のようです。
ステータス更新に関してはマネジメントコンソールからのみ短いスパンでの更新が可能ですが、API の場合は長時間の待機が必要なようですね。

さいごに

本日は AWS Trusted Advisor を使って関連づけられていない Elastic IP アドレスが存在する場合に通知出来るか試みてみました。

結果として通知自体は可能なのですが、ベストエフォートだったりチェック頻度のコントロールが期待よりも難しそうだったのでもう少しカスタマイズしたい場合は別のチェック手法が必要そうですね。

AWS Trusted Advisor の EventBridge については設定も簡単に出来るので手軽に始めやすいというメリットはありそうなので、AWS サポートプランを利用できる方であればまずはこのあたりから始めても良さそうです。

次回は AWS Config あたりを使ってチェックする方法を試してみたいと思います。