Cost Explorerを使ってEC2⇔CloudFrontの転送量をaws cliで出力する

Cost ExplorerからCloudFrontの転送量を取得します。

この方法はEC2⇔CloudFrontやS3→CloudFrontの転送量を出します

CloudFront→ユーザーが欲しい方はこちら=> Cost Explorerを使ってCloudFront→ユーザーの転送量をaws cliで出力する

下記は公式ドキュメントになります。
読みこんで、ほしい情報を得るのに苦労しました。

各項目に何を入力していいかわからないときはCost Explorerのコンソールを英語にするとなんとなくわかります。

https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ce/index.html

こちらのget-cost-and-usageを行っていきます

profile作成

aws credentialsで認証情報を登録するときにprofileを作成しておくと便利です

$ aws configure --profile test-hacknote
AWS Access Key ID [None]: XXXXXXXXXXXXX
AWS Secret Access Key [None]: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Default region name [None]: ap-northeast-1
Default output format [None]: json

ce実行

料金確認

まずは手始めにアカウントの料金を出します
10月の1ヶ月分を出したいときは10/1~11/1までを指定します(月末が何日まであるか気にしなくていいので便利ですね)

上から順番に

  • 期間を指定
  • 月ごと
  • 非ブレンドコスト

を指定しています

メトリクスに何をいれるといいかは、AWS Cost Explorerに渡す、Metricsの値の意味がとてもわかりやすいです。感謝

aws ce --profile test-hacknote get-cost-and-usage \
             --time-period Start=2020-10-01,End=2020-11-01 \
             --granularity MONTHLY  \
             --metrics UnblendedCost

結果

{
    "ResultsByTime": [
        {
            "TimePeriod": {
                "Start": "2020-10-01",
                "End": "2020-11-01"
            },
            "Total": {
                "UnblendedCost": {
                    "Amount": "XXXXXXXXXX",
                    "Unit": "USD"
                }
            },
            "Groups": [],
            "Estimated": false
        }
    ]
}

CloudFrontの転送量を取得

CloudFrontの転送量を取得するには、Cost Explorerのコンソールでいう右側のフィルターという部分で指定する必要があります。
これをcliで実行するにはjsonファイルを記述しなければなりません。
これが慣れないとなかなか大変です。一つの条件だけを記述したいときは、良いんですが、複数条件になると難しいです。仕組みがわかればサクサクかけますね

まずはfilter.jsonを作成していきます(名前は特に指定はありません。cliで指定するときに変えればokです)

"Dimensions": {
    "Key":"USAGE_TYPE_GROUP",
    "Values": ["EC2: Data Transfer - CloudFront (Out)",
               "EC2: EC2 Data Transfer - CloudFront (In)",
               "S3: Data Transfer - CloudFront (Out)"]
}

フィルターの使用タイプグループというカテゴリからCloudFrontと検索して該当するものを記述しました

これでCloudFrontの転送量を取れるはずです

上記ファイルを作成後に下記を実行します

$ aws ce --profile test-hacknote get-cost-and-usage \
                          --time-period Start=2020-10-01,End=2020-11-01 \
                          --granularity MONTHLY  \
                          --metrics UsageQuantity \
                          --filter file://filter.json

結果

{
    "ResultsByTime": [
        {
            "TimePeriod": {
                "Start": "2020-10-01",
                "End": "2020-11-01"
            },
            "Total": {
                "UsageQuantity": {
                    "Amount": "XXX.XXXXXXX",
                    "Unit": "GB"
                }
            },
            "Groups": [],
            "Estimated": false
        }
    ]
}

Cost Explorerのコンソールを見比べるとあっているかわかります

複数条件

次にフィルターの条件を複数にするときです。

今回は一つのアカウントに複数アカウントが紐付いているということを想定します。   主に企業などでは使われているのではないでしょうか
AWS Organizationsですね

filter.jsonは下記のように書きます

{
    "And":[
    {
        "Dimensions": {
            "Key": "LINKED_ACCOUNT",
            "Values": ["111111111111"]
        }
    },
    {
        "Dimensions": {
            "Key":"USAGE_TYPE_GROUP",
            "Values": ["EC2: Data Transfer - CloudFront (Out)",
                       "EC2: EC2 Data Transfer - CloudFront (In)",
                       "S3: Data Transfer - CloudFront (Out)"]
        }
    }
    ]
}

複数条件を書くやり方がわからなくて苦労しました。

AND,OR,NOTが使えるので、かなり複雑なフィルターでも出せるようです
詳しくはこちら

これで実行すると指定したAWSアカウントIDのものだけが出力されます。
コマンドは先程と同じです

$ aws ce --profile test-hacknote get-cost-and-usage \
                          --time-period Start=2020-10-01,End=2020-11-01 \
                          --granularity MONTHLY  \
                          --metrics UsageQuantity \
                          --filter file://filter.json

結果

{
    "ResultsByTime": [
        {
            "TimePeriod": {
                "Start": "2020-10-01",
                "End": "2020-11-01"
            },
            "Total": {
                "UsageQuantity": {
                    "Amount": "XX.XXXXXXXX",
                    "Unit": "GB"
                }
            },
            "Groups": [],
            "Estimated": false
        }
    ]
}

紐付いているすべてのアカウントで転送量を出力する

紐付いているすべてのアカウントで出力するときはgroup-byLINKED_ACCOUNTを指定します。
jsonの中身からLINKED_ACCOUNTを外します

aws ce --profile test-hacknote get-cost-and-usage \
                    --time-period Start=2020-10-01,End=2020-11-01 \
                    --granularity MONTHLY  \
                    --metrics UsageQuantity \
                    --group-by Type=DIMENSION,Key=LINKED_ACCOUNT \
                    --filter file://datatransfer.json
$ cat datatransfer.json
    {
        "Dimensions": {
            "Key":"USAGE_TYPE_GROUP",
            "Values": ["EC2: Data Transfer - CloudFront (Out)",
                       "EC2: EC2 Data Transfer - CloudFront (In)",
                       "S3: Data Transfer - CloudFront (Out)"]
        }
    }

結果

{
    "GroupDefinitions": [
        {
            "Type": "DIMENSION",
            "Key": "LINKED_ACCOUNT"
        }
    ],
    "ResultsByTime": [
        {
            "TimePeriod": {
                "Start": "2020-10-01",
                "End": "2020-11-01"
            },
            "Total": {},
            "Groups": [
                {
                    "Keys": [
                        "111111111111"
                    ],
                    "Metrics": {
                        "UsageQuantity": {
                            "Amount": "XXXXXXXX",
                            "Unit": "GB"
                        }
                    }
                },
                {
                    "Keys": [
                        "222222222222"
                    ],
                    "Metrics": {
                        "UsageQuantity": {
                            "Amount": "XXXXXXXXXX",
                            "Unit": "GB"
                        }
                    }
                },
                {
                    "Keys": [
                        "333333333333"
                    ],
                    "Metrics": {
                        "UsageQuantity": {
                            "Amount": "XXXXXXXXXXX",
                            "Unit": "GB"
                        }
                    }
                },
                {
                    "Keys": [
                        "444444444444"
                    ],
                    "Metrics": {
                        "UsageQuantity": {
                            "Amount": "XXXXXXXXXXX",
                            "Unit": "GB"
                        }
                    }
                },
                {
                    "Keys": [
                        "555555555555"
                    ],
                    "Metrics": {
                        "UsageQuantity": {
                            "Amount": "XXXXXXXXXXXX",
                            "Unit": "GB"
                        }
                    }
                },
            "Estimated": false
        }
    ]
}

アカウントIDをアカウントの名前にする方法はわからなかったので、改良は必要そうです