Help us understand the problem. What is going on with this article?

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日目の記事です。
お楽しみに!

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away