はじめに
WebUIのCost ExplorerでもAWSコストをグラフ表示できますが、PrometheusのExporterとGrafanaで視覚化した際のメモです
PrometheusのExporterはPythonで書かれた aws-cost-exporter を使用します
https://github.com/electrolux-oss/aws-cost-exporter
AWS Cost Exporterとは
- boto3経由でAWS Cost Exporter APIでコスト情報を取得する(他のExporterではCloudWatchメトリックより取得しているものもある)
- AsuumeRoleを行うことでマルチアカウントに対応している
- AWS Organizationsにも対応しているのでメンバーアカウントのコストを管理アカウントから取得できる
- 日次と月次のコストをサポート
設定
弊社ではAWS Organizationsで管理されているため、AWS Organizations用に設定しています
IAMポリシーの追加
Exporterを実行するEC2インスタンスのIAMロールに以下のポリシーを追加します
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "ce:GetCostAndUsage",
"Effect": "Allow",
"Resource": "*"
}
]
}
必要なパッケージのインストール
boto3とprometheus_clientが必要なためこれらをインストールします
sudo pip install -r requirements.txt
export_config.yaml の編集
YAMLファイル内にある $XXXXXX は環境変数で設定できます(後述)
同じEC2インスタンスで実行しているPrometheusとポート番号が同じなのでポート番号を変更します
exporter_port: $EXPORTER_PORT|9090 # the port that exposes cost metrics
GetCostAndUsage APIを実行する間隔を指定します
AWS Cost ExporterはPrometheusからのリクエストでメトリックの取得を行うのではなく、ここの設定された間隔でポーリングを行い、Prometheusからのリクエストではその値を返すという動きをします
デフォルトでは8時間です
(AWS側が1日1回しか更新されないのでもっと長くてもいいかもしれないです)
polling_interval_seconds: $POLLING_INTERVAL_SECONDS|28800 # by default it is 8 hours because for daily cost, AWS only updates the data once per day
ここはEC2のInstance Profileにポリシーを追加したのでこのままにします
aws_access_key: $AWS_ACCESS_KEY|"" # for prod deployment, DO NOT put the actual value here or default is null ("") to use iam-role/irsa
aws_access_secret: $AWS_ACCESS_SECRET|"" # for prod deployment, DO NOT put the actual value here or default is set null ("") to use iam-role/irsa
aws_assumed_role_name: $AWS_ASSUMED_ROLE|"" # Optional. When empty, will use the instance profile. Otherwise, specify a role name to assume
AWS OrganizationsのメンバーアカウントのアカウントIDとエイリアス名のマッピングを設定します
alias: # optional - this will allow you to add label alias to with mapped values (both original and aliased labels will be exported)
label_name: AccountAlias
map:
"123456789012": "myaccount"
"234567890123": "publisher1"
"321645789123": "publisher2"
GetCostAndUsage APIで指定するMetricオプションを指定します
それぞれの説明は以下のドキュメントに記載されています
https://docs.aws.amazon.com/ja_jp/cost-management/latest/userguide/ce-advanced.html
が、すでに他の方がまとめておられるのこちらのQiitaの記事のほうがわかりやすいです
https://qiita.com/tamura_CD/items/4a9a412faf379b334986
メンバーアカウントごとのコストを確認したいので UnblendedCost にします
# Allowed values for metric type are AmortizedCost, BlendedCost, NetAmortizedCost, NetUnblendedCost, NormalizedUsageAmount, UnblendedCost, and UsageQuantity
metric_type: UnblendedCost
Tagでのフィルタは使用しないので以下は削除します
# the following `tag_filters` part is optional and can be removed if there is no filter by tags
tag_filters:
- tag_key: "my_org:team"
tag_values:
- dev-team-1
- dev-team-2
- tag_key: EnvironmentName
tag_values:
- dev
AWS Organizationsの管理アカウントのアカウントIDを指定します
target_aws_accounts:
# here defines a list of target AWS accounts
# it should be guaranteed that all the AWS accounts have the same set of keys (in this example they are Publisher, ProjectName, and EnvironmentName)
# note that Publisher is mandatory here and its value has to be the 12-digit account ID
- Publisher: 999999999999
起動
サービスに追加
以下のファイルを作成してsystemdに追加します
exporter_config.yaml内の環境変数はここで設定します
(以下の内容ではポート番号を 9091、ポーリング期間を12時間にしています)
[Unit]
Description=aws-cost-exporter
[Service]
User=nobody
Environment=EXPORTER_PORT=9091
Environment=POLLING_INTERVAL_SECONDS=43200
ExecStart=python3 /usr/local/aws-cost-exporter/main.py \
-c /usr/local/aws-cost-exporter/exporter_config.yaml
Restart=always
[Install]
WantedBy=multi-user.target
サービスを起動
aws-cost-exporterを起動します
sudo systemctl daemon-reload
sudo systemctl enable aws-const-exporter.service
sudo systemctl start aws-cost-exporter.service
PrometheusとGrafanaの設定
PrometheusにJobを追加
ポーリング期間は12時間ですが、とりあえずintervalは1時間にしています
- job_name: 'aws-cost-exporter'
scrape_interval: 1h
static_configs:
- targets: ['localhost:9091']
Grafanaのダッシュボード追加
gitレポジトリにあるjsonファイルをGrafanaでImportします
https://github.com/electrolux-oss/aws-cost-exporter/blob/main/doc/aws-cost-overview-dashboard-example.json
Import後、ダッシュボードをカスタマイズします
追加でAlertmanagerでAWSコストが一定を超えた際や、何らかのサービスで急激に増えた際にアラートにするということをしてもいいかもしれません