とことんDevOps | 日本仮想化技術のDevOps技術情報メディア

DevOpsに関連する技術情報を幅広く提供していきます。

日本仮想化技術がお届けする「とことんDevOps」では、DevOpsに関する技術情報や、日々のDevOps業務の中での検証結果、TipsなどDevOpsのお役立ち情報をお届けします。
主なテーマ: DevOps、CI/CD、コンテナ開発、IaCなど

開催予定の勉強会

読者登録と各種SNSのフォローもよろしくお願いいたします。

AWS CLIでコストを取得

AWSのコスト気になりますよね、個人で運用している環境だと尚更。ただ、毎日AWSのコンソールにログインしてコストエクスプローラーを眺めるのもそれはそれで結構な負担になるので、AWS CLIでコストを取得して、確認しやすくしてみます。

aws ce

コマンドからコストエクスプローラーをツンツンするにはaws ceを使うとよさそうです。ceってCostExplorerか…なるほど…。今回使うコマンドはget-cost-and-usageget-cost-forecastです。

get-cost-and-usage

docs.aws.amazon.com

指定期間内のコストと使用状況のメトリクスを取得します。

以下の3つのオプションが必須です。

--time-period <value>
--granularity <value>
--metrics <value>

--time-periodオプションはコストを取得する期間を指定します。オプション引数はStart=YYYY-mm-dd,End=YYYY-mm-ddで、Startに指定した日付から、Endに指定した日付の1日前までを集計します。Endが少しわかりづらいのですが、Start=2023-07-01,End=2023-08-01と指定したら7月1日から7月31日までが期間となります。

--granularityオプションはどの粒度で取得するかを指定します。オプション引数はDAILY MONTHLY HOURLYの3つで、DAILYを指定すると指定期間内の1日のコストが指定した日付分取得できます。MONTHLYを指定すると指定期間内の1ヶ月のコストが、HOURLYを指定すると毎時のコストが取得できます。

--metricsオプションはどのメトリクスを取得するかを指定します。オプション引数はAmortizedCost BlendedCost NetAmortizedCost NetUnblendedCost NormalizedUsageAmount UnblendedCost UsageQuantityの7つです。どの引数を選ぶべきかは以下のポストが参考になります。ページごと日本語翻訳しても意味は通じると思います。

aws.amazon.com

So, which cost dataset should you use?

If you are a customer who has purchased Savings Plans or Reservations, then amortized costs are most likely the right dataset for analyzing your cost trends. Otherwise, > looking at unblended costs should suit you just fine.

Savings PlansReservationsを使ってる場合は償却高スト(AmortizedCost)を、それ以外の場合は非混合コスト(UnblendedCost)を使えばよさそうです。

以下のコマンドを実行してみます。

aws ce get-cost-and-usage \
    --time-period "Start=$(date +%Y-%m-01),End=$(date -d '1 month' +%Y-%m-01)" \
    --granularity MONTHLY \
    --metrics UnblendedCost

このようなJSONが返ってきます。

{
    "ResultsByTime": [
        {
            "TimePeriod": {
                "Start": "2023-07-01",
                "End": "2023-08-01"
            },
            "Total": {
                "UnblendedCost": {
                    "Amount": "1.2345678901",
                    "Unit": "USD"
                }
            },
            "Groups": [],
            "Estimated": true
        }
    ],
    "DimensionValueAttributes": []
}

7/1 ~ 7/31の期間で、全てのサービスの合計が1.2345678901 USDかかっていることがわかりました。

どのサービスでいくらかかっているかを取得したい場合は--group-byを使います。

aws ce get-cost-and-usage \
    --time-period "Start=$(date +%Y-%m-01),End=$(date -d '1 month' +%Y-%m-01)" \
    --granularity MONTHLY \
    --metrics UnblendedCost \
    --group-by Type=DIMENSION,Key=SERVICE

サービスごとのコストを取得できました。

{
    "GroupDefinitions": [
        {
            "Type": "DIMENSION",
            "Key": "SERVICE"
        }
    ],
    "ResultsByTime": [
        {
            "TimePeriod": {
                "Start": "2023-07-01",
                "End": "2023-08-01"
            },
            "Total": {},
            "Groups": [
                {
                    "Keys": [
                        "AWS Amplify"
                    ],
                    "Metrics": {
                        "UnblendedCost": {
                            "Amount": "0.1234567890",
                            "Unit": "USD"
                        }
                    }
                },
                {
                    "Keys": [
                        "AWS Key Management Service"
                    ],
                    "Metrics": {
                        "UnblendedCost": {
                            "Amount": "0",
                            "Unit": "USD"
                        }
                    }
                },
...

以下のコマンドで見やすく整形できます。

aws ce get-cost-and-usage \
    --time-period "Start=$(date +%Y-%m-01),End=$(date -d '1 month' +%Y-%m-01)" \
    --granularity MONTHLY \
    --metrics UnblendedCost \
    --group-by Type=DIMENSION,Key=SERVICE \
    --query 'ResultsByTime[].Groups[].{"Service": Keys[0], "Cost": join(`" "`, [Metrics.UnblendedCost.Amount, Metrics.UnblendedCost.Unit])}' \
    --output table

get-cost-forecast

docs.aws.amazon.com

指定期間内の予想コストを取得します。

以下の3つのオプションが必須です。

--time-period <value>
--granularity <value>
--metric <value>

--time-periodオプションはコストを取得する期間を指定します。オプション引数のフォーマットはget-cost-and-usageと同じですが、Startに指定する日付はこのコマンドを実行する日(つまりdate +%Y-%m-%d)にあります。Endは同じです。

--granularityオプションはどの粒度で取得するかを指定します。オプション引数のフォーマットはget-cost-and-usageと同じです

--metricsオプションはどのメトリクスを取得するかを指定します。オプション引数はAMORTIZED_COST BLENDED_COST NET_AMORTIZED_COST NET_UNBLENDED_COST UNBLENDED_COSTの5つです。get-cost-and-usageはパスカルケースでこちらはスネークケース……頼むから統一してくれ……。

コマンドの実行方法もget-cost-and-usageとだいたい同じです。

aws ce get-cost-forecast \
    --time-period "Start=$(date +%Y-%m-%d),End=$(date -d '1 month' +%Y-%m-01)" \
    --granularity MONTHLY --metric UNBLENDED_COST

以下のようなJSONが返ってきます。

{
    "Total": {
        "Amount": "1.23456789012345",
        "Unit": "USD"
    },
    "ForecastResultsByTime": [
        {
            "TimePeriod": {
                "Start": "2023-07-01",
                "End": "2023-08-01"
            },
            "MeanValue": "1.23456789012345"
        }
    ]
}

Total.Amountをみると今月の予想金額がわかります。

get-cost-forecastには--group-byはありませんでした。料金だけ取るなら以下

aws ce get-cost-forecast \
    --time-period "Start=$(date +%Y-%m-%d),End=$(date -d '1 month' +%Y-%m-01)" \
    --granularity MONTHLY --metric UNBLENDED_COST \
    --query 'Total.Amount' --output text

まとめ

CLIから料金をみられるようになりました。コンソールにログイン不要なので定期実行しておくか、簡単にとれるようにシェルスクリプトなんかにしておくと、毎日チェックできてよさそうです。サービスごとに料金を確認できるので、知らないところで課金されていても気づけます。AWSは従量課金のサービスなので簡単に料金を確認できると無駄な課金を防ぐこともできそうですね。