LambdaでTrusted Advisorの節約可能な月額料金を取得する（Node.js）


## 🔶 はじめに
[LambdaでSlackにAWSの利用料金を投稿する（Node.js）](https://qiita.com/tamura_CD/items/33cceb2eac7f1f2fe221)で、AWS料金をSlackに投稿するついでに、節約可能な月額料金も提示した方が親切かと思い、おまけで調べました。

### 🔷 Trusted Advisor
AWSの利用中のサービスをチェックして、推奨の設定を提案してくれるサービス。
https://console.aws.amazon.com/trustedadvisor/home

その中に、「コスト最適化」という項目があり、こちらで提示してくれる「月額料金節約の可能性」の金額を、今回は取得します。

<img width="672" alt="スクリーンショット 2019-03-29 17.02.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/38099/04c8de25-7650-d2ba-e338-9a22c675f577.png">


## 🔶 Lambda関数の実装

### 🔷 ポリシー設定
Lambda関数で節約可能な月額料金を取得するには、AWS SDKのSupportクラスの`describeTrustedAdvisorCheckSummaries`と`describeTrustedAdvisorChecks`を使います。
そのためには、Supportへのフルアクセス権限を持つ**AWSSupportAccessポリシー**をアタッチします。（以下のJSONで設定してもOK）

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "support:*"
            ],
            "Resource": "*"
        }
    ]
}
```
権限は最小にしたいところですが、現時点（2019/03/29）では、**Supportは細かい権限設定はできないようです。**

> AWS Support does not let you allow or deny access to individual actions; therefore your policy must use the "Action": "support:*" to use the AWS Support Center or to use the AWS Support API.

参考：[Actions, Resources, and Condition Keys for AWS Support](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/list_awssupport.html)


### 🔷 実装

* 処理を簡単に言うと、`describeTrustedAdvisorChecks`で一旦、コスト関係のアドバイスを全件取得して、その中に含まれるアドバイス情報のIDのみを拾って配列を作ります。
 * 参考：[DescribeTrustedAdvisorChecks](https://docs.aws.amazon.com/awssupport/latest/APIReference/API_DescribeTrustedAdvisorChecks.html) 
* 次に、`describeTrustedAdvisorChecks`に生成したアドバイスのIDの配列を渡すと、アドバイス毎に節約金額を含む情報を返してくれるので、金額を合計する。
 * 参考：[DescribeTrustedAdvisorCheckSummaries](https://docs.aws.amazon.com/awssupport/latest/APIReference/API_DescribeTrustedAdvisorCheckSummaries.html)
* 注意点として、最初に`new AWS.Support({region:'us-east-1'});`と定義しているように、**Supportクラスはリージョンを明示的に指定しないとエラーになります。**

```js
const AWS = require('aws-sdk');
const support = new AWS.Support({region:'us-east-1'});

exports.handler = async (event) => {
    return await getAdvice();
};

/**
 * Support APIからコスト削減のアドバイス取得処理
 * 
 * @return AWSから取得したコスト削減のアドバイス
 */
function getAdvice() {
  console.log(`■□■□ getAdvice : Support APIからコスト削減のアドバイス取得処理 ■□■□`);
  return new Promise(
    (resolve, reject) => {
      let idArr=[];
      let savingAmount = 0;
      /* アドバイス毎のIDの取得 */
      support.describeTrustedAdvisorChecks({ language: "ja"}, (err, adviceData) => {
        if (err) {
          console.error(err, err.stack);
          reject("");
        }
        
        console.log(JSON.stringify(adviceData));
        for(let i=0; i<adviceData.checks.length; i++) {
          idArr.push(adviceData.checks[i].id);
        }
        
        /* アドバイスのID毎に提示されている、概算月間節約額の取得 */
        support.describeTrustedAdvisorCheckSummaries({ checkIds: idArr}, (err, savingsData) => {
          if (err) {
            console.error(err, err.stack);
            reject("");
          }
          
          console.log(JSON.stringify(savingsData));
          for(let j=0; j<savingsData.summaries.length; j++) {
            if(savingsData.summaries[j].hasFlaggedResources) {
              savingAmount = savingAmount + savingsData.summaries[j].categorySpecificSummary.costOptimizing.estimatedMonthlySavings;
            }
          }
          resolve(`概算月間節約額の合計${Math.round(savingAmount*100)/100}$`);
        });
      });
    }
  );
}
```

## 🔶 テスト

ここまで上手く設定できていたら、Lambda関数を実行すると、以下のように出力されます。
<img width="656" alt="スクリーンショット 2019-03-29 16.56.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/38099/c0682c5b-6247-6c8a-111b-2b3d5b695c11.png">

## 🔶 まとめ

このように、ID取る → 金額とる → 合計する と、ちょっと面倒というだけで、難易度は簡単なので、試してみてください。

## 🔶 参考
 * [DescribeTrustedAdvisorChecks](https://docs.aws.amazon.com/awssupport/latest/APIReference/API_DescribeTrustedAdvisorChecks.html) 
 * [DescribeTrustedAdvisorCheckSummaries](https://docs.aws.amazon.com/awssupport/latest/APIReference/API_DescribeTrustedAdvisorCheckSummaries.html)
 * [Actions, Resources, and Condition Keys for AWS Support](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/list_awssupport.html)