[アップデート] AWS Trusted Advisorを扱う新しいAPIがリリースされました

2023.11.18

しばたです。

本日よりAWS Trusted Advisorを扱う新しいAPIが使える様になりました。  

AWSからのアナウンスはこちらになります。

どういうこと?

従来Trusted Advisorを扱うAPIはAWS Support API (SAPI)の一部として提供され、

  • DescribeTrustedAdvisorCheckRefreshStatuses
  • DescribeTrustedAdvisorCheckResult
  • DescribeTrustedAdvisorChecks
  • DescribeTrustedAdvisorCheckSummaries
  • RefreshTrustedAdvisorCheck

の5アクション存在しており、AWS CLIから扱う場合はaws supportコマンドを使う必要がありました。

今回新たにTrusted Advisorを専用に扱うAWS Trusted Advisor APIが登場し、

  • GetOrganizationRecommendation
  • GetRecommendation
  • ListChecks
  • ListOrganizationRecommendationAccounts
  • ListOrganizationRecommendationResources
  • ListOrganizationRecommendations
  • ListRecommendationResources
  • ListRecommendations
  • UpdateOrganizationRecommendationLifecycle
  • UpdateRecommendationLifecycle

の10アクション利用可能になりました。

利用可能リージョン

新しいAPIは本日時点ではオハイオ、バージニア北部、オレゴン、ソウル、シドニー、アイルランドリージョンで利用可能とのことです。

従来のSAPIではTrusted Advisor関連のアクションはバージニア北部のみ利用可能でした。
今後もっと利用可能なリージョンが増えてくれると嬉しいですね。

ちなみにTrusted Advisor自体はグローバルサービスなので、どのリージョンでAPIを使っても結果は同じになります。

利用可能なサポートプラン

新しいAPIはSAPIと同様にBusiness、Enterprise On-Ramp、Enterpriseいずれかのサポートプランに加入している必要があるとのことです。
ビジネス上の都合かと思いますが、せっかくSAPIから独立したのでこの制限は無くなって欲しいなというのが率直な気持ちです。

対応していないサポートプランの環境からAPIを呼び出すとアクセス拒否エラーとなります。

An error occurred (AccessDeniedException) when calling the ListChecks operation: Access denied due to support level

(AWS CLIでのアクセスエラー例)

AWS CLIでの利用方法

AWS CLIでは新たにaws trustedadvisorコマンドが増え、本日時点ではVer.1.30.3から利用可能です。
AWS CLI v2対応はまだですがGitHubの状況を見る分にVer.2.13.38から対応されるはずです。

試してみた

それでは早速試してみます。

今回は私の検証用AWSアカウントのバージニア北部のCloudShell上にAWS CLI Ver.1.30.3をインストールして試していきます。

$ printenv AWS_DEFAULT_REGION
us-east-1
$ aws --version 
aws-cli/1.30.3 Python/3.7.16 Linux/6.1.59-84.139.amzn2023.x86_64 exec-env/CloudShell botocore/1.32.3

AWS CLI v1のインストールはこの手順で行っています。

ちなみに新アクションのうちOrganizationがついているものはAWS Organizations環境用なので割愛します。

aws trustedadvisor list-checks

aws trustedadvisor list-checksコマンドは各種チェックの一覧を取得します。

aws support describe-trusted-advisor-checks相当のコマンドですが、引数に--piller--aws-serviceなどの検索条件が増え、また、レスポンスもより詳細な情報を取得可能になっています。

--pillarはチェックの柱(カテゴリー)で以下の値のいずれかを指定します。

  • cost_optimizing : コスト最適化
  • performance : パフォーマンス
  • security : セキュリティ
  • service_limits : サービスの制限
  • fault_tolerance : 耐障害性
  • operational_excellence : 運用上の優秀性

たとえば「コスト最適化」で「EC2」に関連するチェックを日本語でリストアップする場合は以下の様にします。

aws trustedadvisor list-checks --pillar cost_optimizing --aws-service ec2 --language ja

実行結果はこんな感じです

# 最初の2件だけピックアップ
$ aws trustedadvisor list-checks --pillar cost_optimizing --aws-service ec2 --language ja --query "checkSummaries[0:2]"
[
    {
        "arn": "arn:aws:trustedadvisor:::check/1e93e4c0b5",
        "awsServices": [
            "EC2"
        ],
        "description": "今後 30 日の間に有効期限が切れる予定になっている、または過去 30 日の間に有効期限が切れた Amazon EC2 リザーブドインスタンス をチェックします。リザーブドインスタンスは自動的に更新されません。予約の対象であった EC2 インスタンスは中断されることなく継続して使用することができますが、オンデマンド料金が課金されます。新しいリザーブドインスタンスのパラメータには有効期限が切れたインスタンスと同じものを設定でき、異なるパラメ ータのリザーブドインスタンスを購入することも可能です。<br/>\r\nAWS が提示する毎月の推定削減額は、同じインスタンスのオンデマンド料金とリザーブドインスタンス料金の差額です。<br/><br/>\r\n<b>アラート基準</b><br/>\r\nYellow: リザーブドインスタンスのリース有効期限が 30 日未満で切れます。<br/>\r\nYellow: リザーブドインスタンスのリース有効期限が過去 30 日の間に切れています。<br/><br/>\r\n<b>推奨されるアクション</b><br/>\r\n有効期限が近付いてい るリザーブドインスタンスを置き換えるための新しいリザーブドインスタンスの購入を検討します。詳細については、「<a href=\"https://aws.amazon.com/ec2/purchasing-options/reserved-instances/buyer/\" target=\"_blank\">リザーブドインスタンスの購入方法</a>」および「<a href=\"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ri-market-concepts-buying.html\" target=\"_blank\">リザーブドインスタンスの購入</a>」を参照してください。<br/><br/> \r\n<b>追加のリソース</b><br/>\r\n<a href=\"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/concepts-on-demand-reserved-instances.html\" target=\"_blank\">リザーブドインスタンス</a><br/>\r\n<a href=\"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html\" target=\"_blank\">イン スタンスタイプ</a>",
        "id": "1e93e4c0b5",
        "metadata": {
            "properties.availabilityZone": "ゾーン",
            "properties.currentMonthlyCost": "現在の月額コスト",
            "properties.currentRICount": "インスタンス数",
            "properties.expirationDate": "有効期限",
            "properties.instanceType": "インスタンスタイプ",
            "properties.monthlySavings": "毎月の推定削減額",
            "properties.operatingSystem": "プラットフォーム",
            "properties.reason": "理由",
            "properties.reservedInstanceId": "リザーブドインスタンス ID",
            "status": "ステータス"
        },
        "name": "Amazon EC2 リザーブドインスタンスのリース有効期限切れ",
        "pillars": [
            "cost_optimizing"
        ],
        "source": "ta_check"
    },
    {
        "arn": "arn:aws:trustedadvisor:::check/COr6dfpM03",
        "awsServices": [
            "EC2"
        ],
        "description": "ルックバック期間中の任意の時点で実行されていた Amazon Elastic Block Storage (Amazon EBS) ボリュームをチェックします。このチェックにより、ワークロードについて過剰にプロビジョニングされた EBS ボリュームがある場合はアラートが出されます。ボリュームが過剰にプロビジョニングされると、未使用のリソースに対して料金が発生します。シナリオによっては設計上、最適化が低くなる場合もありますが、EBS ボリュームの設定を変更することで コストを削減できる場合がよくあります。毎月の推定削減額は、EBS ボリュームの現在の使用率を使用して計算されます。ボリュームが 1 か月間存在していない場合は、実際の削減額は変動します。<br/>\n<br/>\n<b>ソース</b><br/>\nAWS Compute Optimizer<br/>\n<br/>\n<b>アラート基準</b><br/>\n黄色: ルックバック期間中に過剰にプロビジョニングされた EBS ボリューム。ボリュームが過剰にプロビジョニングされているかどうかを判断するには、デフォルトの CloudWatch メトリクス (IOPS とスループットを含む) のすべてが考慮されます。過剰にプロビジョニングされた EBS ボリュームを特定するために使用されるアルゴリズムは AWS のベストプラクティスに従います。新しいパターンが特定されると、アルゴリズムは更新されます。<br/>\n<br/>\n<b>推奨されるアクション</b><br/>\n使用率の 低いボリュームのダウンサイジングを検討してください。<br/>\n<br/>\n<b>その他のリソース</b><br/>\nこの推奨事項の詳細については、「<a href=\"https://docs.aws.amazon.com/console/awssupport/trusted-advisor/compute-optimizer\" target=\"blank\">Trusted Advisor のドキュメント</a>」を参照してください。\n",
        "id": "COr6dfpM03",
        "metadata": {
            "properties.curVolBaselineIOPS": "ボリュームベースライン IOPS",
            "properties.curVolBaselineThroughput": "ボリュームベースラインスループット",
            "properties.curVolBurstIOPS": "ボリュームバースト IOPS",
            "properties.curVolBurstThroughput": "ボリュームバーストスループット",
            "properties.curVolSize": "ボリュームサイズ (GB)",
            "properties.curVolType": "ボリュームタイプ",
            "properties.estMonSavingsCurrency": "毎月の推定削減額通貨",
            "properties.estMonSavingsValue": "毎月の推定削減額",
            "properties.lookbackPeriodInDays": "ルックバック期間 (日数)",
            "properties.recVolBaselineIOPS": "推奨ボリュームベースライン IOPS",
            "properties.recVolBaselineThroughput": "推奨ボリュームベースラインスループット",
            "properties.recVolBurstIOPS": "推奨ボリュームバースト IOPS",
            "properties.recVolBurstThroughput": "推奨ボリュームバーストスループット",
            "properties.recVolSize": "推奨ボリュームサイズ (GB)",
            "properties.recVolType": "推奨ボリュームタイプ",
            "properties.savingsOpportunityPercentage": "削減の機会 (%)",
            "properties.updateTimeUtc": "最終更新時刻",
            "properties.volId": "ボリューム ID",
            "region": "リージョン/AZ",
            "status": "ステータス"
        },
        "name": "Amazon EBS の過剰にプロビジョニングされたボリューム",
        "pillars": [
            "cost_optimizing"
        ],
        "source": "compute_optimizer"
    }
]

aws trustedadvisor list-recommendations

aws trustedadvisor list-recommendationsコマンドは現在存在するレコメンデーションの一覧を取得します。
各種引数で抽出対象を絞ることが可能です。

ただ、チェックの状態を選ぶ--statusについてはCLIで指定可能な値がok,warning,errorなもののAPIが返す内容がok,warn,errorのため警告となっているものは期待した抽出をできませんでした...
こちらはあとでフィードバックしておこうと思います。

たとえば「コスト最適化」で「EC2」に関連するレコメンデーションをリストアップする場合は以下の様にします。

aws trustedadvisor list-recommendations --pillar cost_optimizing --aws-service ec2

実行例はこんな感じ。

# 環境に応じて結果は変わる
$ aws trustedadvisor list-recommendations --pillar cost_optimizing --aws-service ec2
{
    "recommendationSummaries": [
        {
            "arn": "arn:aws:trustedadvisor::xxxxxxxxxxxx:recommendation/57c36989-35bb-464f-9915-20ee1dae99a3",
            "awsServices": [
                "ec2"
            ],
            "checkArn": "arn:aws:trustedadvisor:::check/Qsdfp3A4L2",
            "id": "57c36989-35bb-464f-9915-20ee1dae99a3",
            "lastUpdatedAt": "2023-11-18T02:17:58.285Z",
            "name": "Amazon EC2 instances consolidation for Microsoft SQL Server",
            "pillarSpecificAggregates": {
                "costOptimizing": {
                    "estimatedMonthlySavings": 0.0,
                    "estimatedPercentMonthlySavings": 0.0
                }
            },
            "pillars": [
                "cost_optimizing"
            ],
            "resourcesAggregates": {
                "errorCount": 0,
                "okCount": 0,
                "warningCount": 0
            },
            "source": "ta_check",
            "status": "ok",
            "type": "standard"
        },
#       ・・・中略・・・
        {
            "arn": "arn:aws:trustedadvisor::xxxxxxxxxxxx:recommendation/722e700e-6f53-422a-a72d-53a3635cefb8",
            "awsServices": [
                "ec2"
            ],
            "checkArn": "arn:aws:trustedadvisor:::check/DAvU99Dc4C",
            "id": "722e700e-6f53-422a-a72d-53a3635cefb8",
            "lastUpdatedAt": "2023-11-18T03:12:27.902Z",
            "name": "Underutilized Amazon EBS Volumes",
            "pillarSpecificAggregates": {
                "costOptimizing": {
                    "estimatedMonthlySavings": 55.29599999999999,
                    "estimatedPercentMonthlySavings": 1.0
                }
            },
            "pillars": [
                "cost_optimizing"
            ],
            "resourcesAggregates": {
                "errorCount": 0,
                "okCount": 0,
                "warningCount": 3
            },
            "source": "ta_check",
            "status": "warn",
            "type": "standard"
        }
    ]
}

最後のデータは「利用頻度の低い Amazon EBS ボリューム」で警告("status": "warn")のレコメンデーションです。

aws trustedadvisor get-recommendation

aws trustedadvisor get-recommendationコマンドは単一のレコメンデーションを取得します。
--recommendation-identifierに対象となるレコメンデーションを指定します。

取得できる情報はlist-recommendationsとだいたい同じですが、こちらの場合は英語のdescriptionが付いてきます。

# 実行例
$ aws trustedadvisor get-recommendation --recommendation-identifier arn:aws:trustedadvisor::xxxxxxxxxxxx:recommendation/722e700e-6f53-422a-a72d-53a3635cefb8
{
    "recommendation": {
        "arn": "arn:aws:trustedadvisor::xxxxxxxxxxxx:recommendation/722e700e-6f53-422a-a72d-53a3635cefb8",
        "awsServices": [
            "ec2"
        ],
        "checkArn": "arn:aws:trustedadvisor:::check/DAvU99Dc4C",
        "description": "Checks Amazon Elastic Block Store (Amazon EBS) volume configurations and warns when volumes appear to be underused. Charges begin when a volume is created. If a volume remains unattached or has very low write activity (excluding boot volumes) for a period of time, the volume is probably not being used.<br>\n<br>\n<h4 class='headerBodyStyle'>Alert Criteria</h4><br>\nYellow: A volume is unattached or had less than 1 IOPS per day for the past 7 days.<br>\n<br>\n<h4 class='headerBodyStyle'>Recommended Action</h4><br>\nConsider creating a snapshot and deleting the volume to reduce costs. For more information, see <a href=\"http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-creating-snapshot.html\" target=\"_blank\">Creating an Amazon EBS Snapshot</a> and <a href=\"http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-deleting-volume.html\" target=\"_blank\">Deleting an Amazon EBS Volume</a>.<br>\n<br>\n<h4 class='headerBodyStyle'>Additional Resources</h4><br>\n<a href=\"http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AmazonEBS.html\" target=\"_blank\">Amazon Elastic Block Store (Amazon EBS)</a><br>\n<a href=\"http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-volume-status.html\" target=\"_blank\">Monitoring the Status of Your Volumes</a>",
        "id": "722e700e-6f53-422a-a72d-53a3635cefb8",
        "lastUpdatedAt": "2023-11-18T03:44:48.074Z",
        "name": "Underutilized Amazon EBS Volumes",
        "pillarSpecificAggregates": {
            "costOptimizing": {
                "estimatedMonthlySavings": 55.29599999999999,
                "estimatedPercentMonthlySavings": 1.0
            }
        },
        "pillars": [
            "cost_optimizing"
        ],
        "resourcesAggregates": {
            "errorCount": 0,
            "okCount": 0,
            "warningCount": 3
        },
        "source": "ta_check",
        "status": "warn",
        "type": "standard"
    }
}

aws trustedadvisor list-recommendation-resources

aws trustedadvisor list-recommendation-resourcesコマンドは各レコメンデーションと紐づくリソースを抽出します。
--recommendation-identifierに対象となるレコメンデーションを指定します。

先ほどの「利用頻度の低い Amazon EBS ボリューム」に紐づくリソースを取得しようとしたのですが...エラーになってしまいました。

# レコメンデーションに紐づくリソース(EBSボリューム)を取得しようとするもエラーとなった
$ aws trustedadvisor list-recommendation-resources --recommendation-identifier arn:aws:trustedadvisor::xxxxxxxxxxxx:recommendation/722e700e-6f53-422a-a72d-53a3635cefb8 

An error occurred (InternalServerException) when calling the ListRecommendationResources operation (reached max retries: 4): Internal server exception. Please retry.

原因は不明ですが、CLIの戻り値には各リソースのステータスも保持されており、このチェックに紐づくリソース(EBSボリューム)にはステータス欄が無いのが関係してそうな気がします。(ステータスを持たないリソースは抽出不可?)

代わりにステータスのあるリソースを抽出してみたところ期待した動作をしました。

# 別のレコメンデーション (AWS Well-Architected コスト最適化のための高リスク問題) を抽出
$ aws trustedadvisor list-recommendations --pillar cost_optimizing --status error \
    --query "recommendationSummaries[0].{arn: arn, name: name}"
{
    "arn": "arn:aws:trustedadvisor::xxxxxxxxxxxx:recommendation/0c98c6d1-6c4e-4e5a-8769-cba93eedc678",
    "name": "AWS Well-Architected high risk issues for cost optimization"
}

# このレコメンデーションと紐づくリソースを検索
$ aws trustedadvisor list-recommendation-resources --recommendation-identifier arn:aws:trustedadvisor::xxxxxxxxxxxx:recommendation/0c98c6d1-6c4e-4e5a-8769-cba93eedc678 
{
    "recommendationResourceSummaries": [
        {
            "arn": "arn:aws:trustedadvisor::xxxxxxxxxxxx:recommendation-resource/0c98c6d1-6c4e-4e5a-8769-cba93eedc678/8f7e07f25ff82c60d2698396b73698ef841b3d27367177447df4c689075d8863",
            "id": "8f7e07f25ff82c60d2698396b73698ef841b3d27367177447df4c689075d8863",
            "lastUpdatedAt": "2023-11-17T05:00:00Z",
            "metadata": {
                "identifiedHRI": "9",
                "questionsAnswered": "9",
                "region": "ap-northeast-1",
                "resolvedHRI": "0",
                "reviewerName": "shibata",
                "status": "error",
                "totalQuestions": "9",
                "updateTimeUtc": "2023-11-17T05:39:05.00Z",
                "workloadARN": "arn:aws:wellarchitected:ap-northeast-1:xxxxxxxxxxxx:workload/cef0a79798f382938d6a02c6b3491178",
                "workloadLastModifiedDate": "2020-06-04",
                "workloadName": "お試しワークロード",
                "workloadStartDate": "2020-06-04",
                "workloadType": "Production"
            },
            "recommendationArn": "arn:aws:trustedadvisor::xxxxxxxxxxxx:recommendation/0c98c6d1-6c4e-4e5a-8769-cba93eedc678",
            "regionCode": "ap-northeast-1",
            "status": "error"
        }
    ]
}

aws trustedadvisor update-recommendation-lifecycle

aws trustedadvisor update-recommendation-lifecycleコマンドは特定レコメンデーションのライフサイクルを更新します。

これはAWS Trusted Advisor Priority向けの機能で私の環境では試すことができませんでした。

使い方としては--recommendation-identifierに対象となるレコメンデーションを、--lifecycle-stageに更新するライフサイクルステージを設定します。

# こんな感じの引数指定をする
aws trustedadvisor update-recommendation-lifecycle \
    --recommendation-identifier arn:aws:trustedadvisor::xxxxxxxxxxxx:recommendation/0c98c6d1-6c4e-4e5a-8769-cba93eedc678 \
    --lifecycle-stage resolved

AWS Trusted Advisor Priorityではない通常のレコメンデーション(type = standard)に対してコマンドを実行すると種別違いのエラーとなります。

An error occurred (ValidationException) when calling the UpdateRecommendationLifecycle operation: Operation does not accept Standard Recommendations.

最後に

ざっとこんな感じです。

Updateの付くアクションがあったので「これはレコメンデーションの更新を自動化できるのでは?」と期待したのですが、残念ながらAWS Trusted Advisor Priority専用機能でした。
それでも従来のSAPIより柔軟にレコメンデーションを検索可能でAWS Oraganizationsにも対応しているので情報収集する分には非常に便利に使えそうです。

機会があればぜひご活用ください。