Google Cloud Platformの支払い情報をBigQueryにエクスポートしてSlackに飛ばすまで

#概要


スクリプトを使って，支払い情報の取得設定や通知できるようにするためにはどうすれば良いかを説明します。
Google Cloud Platform(以下GCP)の支払い情報をBigQueryにエクスポートして，GCFで集計してSlackに通知するスクリプトを作りました．
下のような通知が日時でSlackに届きます．かっこの中身は前日の金額との差（昨日より増えてるか減ってるか）です．
オプション設定によりプロジェクトの内訳も表示できるようになります。（一番下を参照）

|<img width="741" alt="slack通知(縮小版）.png" src="https://qiita-image-store.s3.amazonaws.com/0/76724/1d15ab28-3aed-00d5-ad22-d2e6134e8606.png">|
|:-:|

デプロイコマンドも同封しているので、slack api tokenとBigQueryのエクスポート設定をすれば任意のチャネルに通知を飛ばせるようにできます。
[スクリプトはこちら（Github）](https://github.com/firstVersion/send-invoice-gcp2slack)

##使用するもの
・BigQuery
・Google Scheduler
・Google Cloud Functions ( Node.js v6 )
・Slack API

##全体像
GCP側からBigQueryにデータをエクスポートしてもらいます。（設定は後述）
そのデータをとってきてSlackに流します。

<img width="1494" alt="Qiita用Billing全体図.png" src="https://qiita-image-store.s3.amazonaws.com/0/76724/66e1f6f7-95f2-4e83-9df9-e60552074ff7.png">





#GCP支払い情報取得設定
支払い情報はWebAPIなどがあってそこからリアルタイムで取得できるものだと思っておりましたが，取り方は[BigQueryにエクスポート](https://cloud.google.com/billing/docs/how-to/export-data-bigquery?hl=ja)するか[ファイル(JSON or CSV)をGoogle Cloud Storageにエクスポート](https://cloud.google.com/billing/docs/how-to/export-data-file?hl=ja)するかしかありませんでした．

##違いは？
出力されるデータ形式や出力されるタイミングが違うので，そこらへんの特徴を以下にまとめました．
###ファイルにエクスポート
- 出力タイミングは1日に一回，夜に出力されることが多かった．時間は指定できない．不規則．
- 一回の出力でファイルが一つ生成される。（毎日ひとつファイルが増える）
- 形式はCSVかJSONを選べる
- 一つのファイルの出力範囲は3日前から前日まで利用した分くらいの請求情報が出力される．（例:17日export分には14日から16日の請求情報）
- 利用しているサービスが少ないうちはこちらでも良さそう．しかし，量が多くなったり，数日にわたって請求情報を分析したい場合には不向き

###BigQueryにエクスポート
- 出力タイミングは稼働しているサービスにより不規則に出力され続ける．
- 請求情報はテーブルに蓄積される．最新ので5-6時間前に利用した請求情報が取得できる．
- その日に使った分の請求情報が翌日の夜に出力されたりと不規則 →　その日に使った分の料金を正確に出すのは難しそう．．

##設定（BigQueryの設定の場合）
- 今回は今月分の合計請求額を計算するのに適したBigQueryを利用することにしました。以下にその設定を示します。
- GCPのコンソールでサイドメニューを開いてお支払いを押す

|<img width="190" alt="exp01.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/76724/f29ff45f-a8b4-96c8-27e0-7af8a4f3659e.png">|
|:-:|

- 課金データのエクスポートを押す

|<img width="168" alt="exp02.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/76724/51a9b9ce-1fd5-2161-eac0-d7dac11df6ef.png">|
|:-:|

- 事前にエクスポートを有効に、エクスポート先を指定します。

|<img width="432" alt="exp03.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/76724/16d921e5-bf15-7059-1b67-b6aeadb32317.png">|
|:-:|

- この時にBigQueryのDBを、ファイルエクスポートの場合はGoogle Cloud Storageにbucketを生成しておく必要があります。


#BigQueryとSlackAPIを利用するための準備
今回用意したスクリプトはBigQueryとSlackAPIを用いるので、環境変数としてSlack API Token, 通知するチャネル名、BigQueryにSQLのリクエストするときに取得先テーブル名が必要になります。
それぞれの準備の仕方について説明します。
##BigQueryの名前確認
テーブル名はプロジェクト名.データベース名.テーブル名で指定するとリクエストを飛ばすことができるようです。
（BigQueryでSQLが飛ばせればそれでよいです。）
プロジェクト名、データベース名、テーブル名をそれぞれ確認してください。
確認は、BigQueryのページでリソースを確認することができます。

|<img width="160" alt="bigquery.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/76724/63f41253-56cb-d5bf-787e-5a0692fbb59c.png">|
|:-:|


##Google Cloud Functionsにデプロイ
デプロイする際に環境変数を設定します．設定が必要なのは以下
- Slackの API token
- 通知するチャネル名
- BigQueryのリクエスト先
- プロジェクトの内訳を表示するかどうか（１にするとプロジェクトの内訳も表示するようになります。）
SlackのAPIキー取得などは[こちら](https://qiita.com/ykhirao/items/3b19ee6a1458cfb4ba21)などが大変わかりやすかったです．
ただしスコープは```Send messages as sample``` ではなく， ```send messages as [bot name]（chat:write:bot）``` です．
取得したらば，deploy.shにそれぞれ記入してください．
[記入した例]
以下のようなコマンドでデプロイできます．（リポジトリにdeploy.shが同封されておりますので，ご利用ください）

```sh
gcloud beta functions deploy notifySlack \
--set-env-vars=\
"SLACK_API_TOKEN"="your-api-token",\
"SLACK_CHANNEL_NAME"="your-channel-name",\
"TABLE_NAME"="your-project-name.your-db-name.your-table-name" \
"FULL_BURST"="0 or 1" \
--project=your-project-name \
--trigger-http
```
※GCPのコンソールから関数を作って直接コードを書くこともできます．


##環境変数などの確認
デプロイすると関数が追加されていることがコンソールから確認できます．

|<img width="562" alt="gcf01.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/76724/6f4ed5b3-a565-8b59-7fc7-f33e9851851a.png">|
|:-:|

関数名をクリックして編集ボタンを押します。

|<img width="572" alt="gcf02.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/76724/36e84062-1687-1f10-ca25-b63cfebdb66a.png">|
|:-:|

下のほうにスクロールしてその他を押します。

|<img width="167" alt="gcf03.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/76724/72a2b3c5-e07a-0793-0c19-cf02d57ff1f1.png">|
|:-:|

環境変数もちゃんとセットされていますね．

|<img width="172" alt="gcf04.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/76724/6b20b1cb-f9bc-e86d-edb6-199e5020bb89.png">|
|:-:|

テストで実行してちゃんと通知が来るかどうか確認して見ましょう．


#Google Schedulerの設定
- 定期実行する設定です．左のサイドバーのツール群にあるCloud Schedulerを開いてください

|<img width="208" alt="cloud_scheduler.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/76724/38a10dc3-21d2-72b7-0ae9-62382de9eafa.png">|
|:-:|

- cronの設定がよくわからない方は[これなんか](http://scrap.php.xdomain.jp/create_tool/cron_setting_tool/)を使って設定すると良いですね．
勝手に実行されるようになるはずです．ジョブを作成を押します

|<img width="336" alt="create job.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/76724/2351cd10-2a32-42e8-a729-80f4c549beb5.png">|
|:-:|

- 今回は毎日夜の0時15分に実行することにしました．URLはGoogle Cloud Functionsのトリガータブに記載されています。

|<img width="320" alt="scheduler_setting_ex.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/76724/0db0d640-b5bd-04c2-b411-6d2618cd08d0.png">|
|:-:|

#確認
ちゃんと実行されていました．（内訳も表示した場合）

|<img width="241" alt="slackに通知が届いている様子.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/76724/3fe78514-4a97-2e15-0cf3-3e72595affce.png">|
|:-:|

#まとめ

Cloud Functionsを使って請求情報をSlackに出力することができるようになりました。
この記事を作るにあたってファイルに出力させるパターンでもスクリプトの作成を試みましたが、集計をJS側でやらなければならず、いろいろてこずったので、BigQueryにExportしたほうがはるかに楽です。SQL書くだけでJSはメッセージ整形すればよくなるのでおすすめです！
　また、Exportする際には、GKEのインスタンスがGCEと一緒になっていたりするので、さらに詳細な内訳を知りたい場合には、事前にラベルを付けるなどして分析していくとより細かなことがわかるようになるはずです。