Posted at
LivesenseDay 15

AWSの請求情報をembulkを使用してTreasure Dataに転送し、Re:dashで可視化

More than 1 year has passed since last update.

皆様こんにちは。

お酒を飲むと100倍しゃべる @takemotto です。

リブセンスでインフラエンジニアをやってます。

『Livesense Advent Calendar 2016』の15日目の記事を担当することになりました。

よろしくお願いします。

尚、リブセンスでは他に2本のAdvent Calendarもやっております。こちらもよろしくお願いします。


背景

弊社では年々、オンプレからAWSを移行するするサービスが増えてきています。

そこで全社的にAWS費用圧縮の啓蒙活動行うことでをコスト意識高めよう → AWSのコストを可視化してみようということになりました。

今回はその辺を記事にまとめました。

AWSにはもともと コストエクスプローラ- という機能があり、費用をサービス別、日別に分析することが可能です。

ですが、今回は社内にあるAWSの複数アカウントのコストを集約して可視化したかったのでRe:dashを採用することにしました。


概要

AWSの請求情報(csv)をs3バケットに出力できます。

詳しくは、請求レポートで使用量を確認する を参照してください。

ローカルPCからEmbuklコマンドを実行して、s3バケットの請求情報をTreasure Data(以下、TD)に転送します。

その後、TDにインポートした請求情報をデータソースとして、Re:dashで可視化(グラフ化)します。

AWS Design (2).png


前提条件


  • TDのアカウントがあること


    • APIがあること(TDのMy profileから確認可能です)



  • AWSのアカウント(以下の権限を含む)があること


    • AmazonS3ReadOnlyAccess

    • Billing



  • IAMで上記アカウントのアクセスキーを発行がされていること


    • アクセスキー、シークレットキーがあること



  • tdコマンドがインストールされていること

$ gem install td


実行環境


  • Mac OS X 10.12.1

  • td 0.15.2

  • embulk 0.8.15

  • embulk-input-s3 (0.2.8)

  • embulk-output-td (0.3.12)

  • embulk-decoder-commons-compress (0.4.0)

  • embulk-filter-column (0.5.4)

  • embulk-filter-typecast (0.1.5)

  • Re:dash 0.12.0+b2449


AWSのセットアップ


s3バケットの作成

AWSの請求情報出力先のs3バケットを作成してください。

今回は「aws-billing-report」としました。

s3バケットのアクセス許可は適切に。


請求情報設定

AWSマネジメントコンソールから「請求ダッシュボード」→「レポート」→「レポートの作成」でレポートの設定を行ってください。

設定する内容は以下の通りです。


  • レポート名:任意

  • 時間単位:時間別

  • S3バケット:先程作成したs3バケットを指定

設定が完了すると、当該s3バケットに請求情報(csv)が出力されます。

がしかし出力されるまでに1日かかる場合があるので、気長に待ちましょう。


AWS credencialsの設定

ローカルのMacにAWS credencialsの設定を行います。

事前作成したユーザで取得したAccess kyeとSecret Access kyeを設定してください。

$ aws configure

AWS Access Key ID [None]: [AWSのアクセスキー]
AWS Secret Access Key [None]: [AWSのシークレットキー]
Default region name [None]: ap-northeast-1
Default output format [None]: json


Treasure Dataのセットアップ


アカウント設定

ローカルのMacに設定します。

Treasure Dataのアカウントを設定します

$ td account -f

Enter your Treasure Data credentials. For Google SSO user, please see https://docs.treasuredata.com/articles/command-line#google-sso-users
Email: [TDアカウント]
Password (typing will be hidden):[TDパスワード]
Authenticated successfully.
Use 'td db:create <db_name>' to create a database.
$


データベース作成

TD上にデータベースを作成します。

今回、TD側のデータベース名は「aws_billing」としました。

td db:create aws_billing


Embulkのセットアップ


インストール

ローカルのMacにインストールします。

いろんなプラグインを駆使します。

$ curl --create-dirs -o ~/.embulk/bin/embulk -L "http://dl.embulk.org/embulk-latest.jar" -k

$ chmod +x ~/.embulk/bin/embulk
$ echo 'export PATH="$HOME/.embulk/bin:$PATH"' >> ~/.bashrc
$ source ~/.bashrc
$ embulk gem install embulk-output-td
$ embulk gem install embulk-input-s3
$ embulk gem install embulk-decoder-commons-compress
$ embulk gem install embulk-filter-column
$ embulk gem install embulk-filter-typecast


embulk guessの実行

まずs3バケット上にある請求情報(csv)をembulk guessコマンドで読み込み、

データファイルのレイアウトを推測します。

なお、請求情報のファイルがzipファイルであるため、decodersの設定を入れてます。

このdecodersを入れることで、解凍してからファイルを読み込みます。


seed.yml

in:

type: s3
bucket: aws-billing-report
path_prefix: [AWSの12桁ユーザID]-aws-billing-detailed-line-items-2016
access_key_id: [アクセスキー]
secret_access_key: [シークレットキー]
decoders:
- {type: commons-compress}

$ embulk guess seed.yml -o config.yml

~省略~
in:
type: s3
bucket: aws-billing-report
path_prefix: [AWS account number(12桁)]-aws-billing-detailed-line-items-2016
access_key_id: [アクセスキー]
secret_access_key: [シークレットキー]
decoders:
- {type: commons-compress}
parser:
charset: UTF-8
newline: CRLF
type: csv
delimiter: ','
quote: '"'
escape: '"'
trim_if_not_quoted: false
skip_header_lines: 1
allow_extra_columns: false
allow_optional_columns: false
columns:
- {name: InvoiceID, type: long}
- {name: PayerAccountId, type: long}
- {name: LinkedAccountId, type: long}
- {name: RecordType, type: string}
- {name: ProductName, type: string}
- {name: RateId, type: long}
- {name: SubscriptionId, type: long}
- {name: PricingPlanId, type: long}
- {name: UsageType, type: string}
- {name: Operation, type: string}
- {name: AvailabilityZone, type: string}
- {name: ReservedInstance, type: boolean}
- {name: ItemDescription, type: string}
- {name: UsageStartDate, type: timestamp, format: '%Y-%m-%d %H:%M:%S'}
- {name: UsageEndDate, type: timestamp, format: '%Y-%m-%d %H:%M:%S'}
- {name: UsageQuantity, type: string}
- {name: BlendedRate, type: string}
- {name: BlendedCost, type: string}
- {name: UnBlendedRate, type: string}
- {name: UnBlendedCost, type: string}
Created 'config.yml' file.
$

geuss成功しました。

がこのまま使うとこの後のembulk runでコケるのと、

filterをいろいろかけたいので最終的にconfig.ymlを以下のようにしました。


config.yml

in:

type: s3
bucket: aws-billing-report
path_prefix: [AWS account number(12桁)]-aws-billing-detailed-line-items-20
access_key_id: [AWS アクセスキー]
secret_access_key: [AWS シークレットキー]
decoders:
- {type: commons-compress}
parser:
charset: UTF-8
newline: CRLF
type: csv
delimiter: ','
quote: '"'
escape: '"'
trim_if_not_quoted: false
skip_header_lines: 1
allow_extra_columns: false
allow_optional_columns: false
columns:
- {name: invoiceid, type: string}
- {name: payeraccountid, type: string}
- {name: linkedaccountid, type: string}
- {name: recordtype, type: string}
- {name: productname, type: string}
- {name: rateid, type: string}
- {name: subscriptionid, type: string}
- {name: pricingplanid, type: string}
- {name: usagetype, type: string}
- {name: operation, type: string}
- {name: availabilityzone, type: string}
- {name: reservedinstance, type: string}
- {name: itemdescription, type: string}
- {name: usagestartdate, type: timestamp, format: '%Y-%m-%d %H:%M:%S'}
- {name: usageenddate, type: timestamp, format: '%Y-%m-%d %H:%M:%S'}
- {name: usagequantity, type: string}
- {name: blendedrate, type: double}
- {name: blendedcost, type: double}
- {name: unblendedrate, type: double}
- {name: unblendedcost, type: double}
filters:
- type: column
columns:
- {name: 'productname'}
- {name: 'unblendedcost'}
- {name: 'usagestartdate'}
- type: typecast
columns:
- {name: 'usagestartdate', type: long}
out:
type: td
apikey: [TD APIキー]
database: aws_billing
table: biiling
time_column: usagestartdate
mode: replace


ポイント


  • TDはカラム名に大文字を使用できないため、小文字に変換します。

  • カラムの型をいい感じに変換します。(string、doubleのみにした)

  • TDのAPIキーは、td apikey:show で確認できます。

  • 必要なカラムだけTDにインポートしたいため、「filters」の「type: column」でカラムを絞っています。

  • TDでは以下のデータタイプのみ使用できます。

Treasure Data supports the following data types:

int
long
double
float
string
array<T>

 timestamp型は使用できないので、「filters」の「type: typecast」でlong型に変換してます。

 この設定がないとstring型でインポートされます。


embulk runの実行

まずembulk runの前にembulk previewを実行して動作確認します。

$ embulk preview config.yml |more

2016-12-10 22:21:07.826 +0900: Embulk v0.8.15
2016-12-10 22:21:19.416 +0900 [INFO] (0001:preview): Loaded plugin embulk-input-s3 (0.2.8)
2016-12-10 22:21:19.501 +0900 [INFO] (0001:preview): Loaded plugin embulk-filter-column (0.6.0)
2016-12-10 22:21:19.532 +0900 [INFO] (0001:preview): Loaded plugin embulk-filter-typecast (0.1.5)
2016-12-10 22:21:21.033 +0900 [INFO] (0001:preview): Loaded plugin embulk-decoder-commons-compress (0.4.0)
+-------------------------------+----------------------+---------------------+
| productname:string | unblendedcost:double | usagestartdate:long |
+-------------------------------+----------------------+---------------------+
| AWS CloudTrail | 0.0 | 1,470,009,600 |
| AWS CloudTrail | 0.0 | 1,470,013,200 |

いけそうです。

ではembulk runで実際にTDにインポートしてみます。

$ embulk run config.yml

~長いので省略〜

成功しました。

TDにテーブルが作成されていればOKです。

ここまでくればRe:dashで可視化させるだけです。


Re:dashのセットアップ


Re:dashインストール

ローカルMacにRe:dashを入れましょう。

こちらを参考にしてください。すいません。

参考:「Re:dash」を「Docker for Mac」で動かしてみた

インストールが終わったらアクセスしてみましょう。admin/adminでログインできます。

スクリーンショット 2016-12-12 15.22.48.png


Re:dash Data Source追加

Data SourceにTDを追加します。このボタンをクリック。

スクリーンショット 2016-12-12 15.25.00.png

次に「New Data Source」をクリック。以下のように設定しました。

ApikeyはTDのapiキーを設定してください。

スクリーンショット 2016-12-12 15.38.11.png


Re:dash クエリを作成

クリエを作成します。

スクリーンショット 2016-12-12 15.44.01.png

クエリはこんな感じです。クエリが成功したら、名前をつけて「save」ボタンで保存しましょう。

クエリ名は「aws billing」としました。

SELECT productname,

TD_TIME_FORMAT(usagestartdate, 'yyyy-MM-dd', 'JST') AS DATE,
SUM(unblendedcost) AS cost
FROM biiling
GROUP BY productname,
TD_TIME_FORMAT(usagestartdate, 'yyyy-MM-dd', 'JST')


Re:dash グラフ化

「NEW VISUALIZATION」でグラフを作成して、「save」します。

スクリーンショット 2016-12-12 18.08.47.png

 

グラフは以下ように設定しました。

スクリーンショット 2016-12-12 17.07.52.png

 


Re:dash ダッシュボード作成

「New Dashboard」をクリックして、ダッシュボードを作成します。名前は「aws billing」としました。

スクリーンショット 2016-12-12 17.11.20.png

 

ダッシュボードにWidgetを追加します。

スクリーンショット 2016-12-12 17.14.51.png

 

さきほど作成したクエリ「aws billing」を指定して、「Add to Dashboard」をクリックします。

スクリーンショット 2016-12-12 17.15.58.png

 

 

完成です。

スクリーンショット 2016-12-12 17.17.37.png


まとめ


  • 複数AWSアカウントで実施する場合、アクセスキー、シークレットキーを指定する部分がネックなると思います。この対策としてLiquidというテンプレートを使用することで、設定ファイル(今回ではconfig.yml)に環境変数が使用できます。この辺をうまく活用すれば、AWSアカウント毎のアクセスキー、シークレットキーを設定できると思います。他にいい方法があったら教えてください。

  • これは言っては元も子もないですが、自分のAWSアカウントだけでコスト分析したいのであればAWSの機能を使った方がよさそうですw

  • 最後までお付き合いいただき、ありがとうございました。


最後に

明日は @boscoworks さんのアドベントカレンダー16日目の記事です。

お楽しみに!