clock2020.12.17 08:18
SERVICE
home

クラウドデータ基盤をTerraformを使ってIaC化 & 量産する

AUTHOR :   ギックス

この記事は GiXo アドベントカレンダー の 17 日目の記事です。
昨日は、Firestore のデータを TypeScript と Security Rules で安全に扱う話 でした。

Technology Div. の奥田です。前職ではC++を使ってCADを開発しており、GiXoには去年2019年9月に入社しました。クラウド開発歴は1年ほどです。今回は、そんなクラウド初心者の僕がとあるプロジェクトで開発・検証しているデータ基盤についてご紹介したいと思います。

本記事は以下の技術要素を含みます。

  • GCP
  • Github Actions
  • Terraform

データ基盤の概要

絶えず生成される生データをBigQueryに取り込むデータ基盤を作成します。このプロジェクトには以下の制約があります。

  1. CSVを定期的に取り込む必要がある。
  2. BigQueryに取り込む際、重複を排除する必要がある。
  3. 処理が失敗した際にリトライする必要がある。
  4. 同様のシステムを量産する必要がある。

これらの制約を満たすために、下図のようなシステムを構築しました。

これからこのデータ基盤の詳細について解説します。

データ基盤の詳細

図中2のCloud Functionsで実行するPythonコードです。BigQueryから外部テーブルで参照しているパスにCSVを移動してから、蓄積テーブルにCSVを取り込むクエリを流しています。

図中7のCloud Functionsで実行するPythonコードです。図中2から発行するBigQueryのJobが失敗したときにLogs Router経由で実行されます。Job IDにFunction名を含めて実行しているので、そのFunctionをリトライします。

CSVをBigQueryにインポートする方法としては、BigQuery Data Transfer Serviceを利用する方法も考えられますが、実際に利用してみたところエラーハンドリングの困難さから採用しませんでした。

ここで解説していない、その他リソースに関しては後のTerraformテンプレートにて解説します。

Terraformテンプレート

このプロジェクトでは図と同様のシステムを量産する必要があったのでTerraformを用いてテンプレート化しました。テンプレート内で利用する変数を.tfvarsファイルにまとめることで、量産が容易になります。

以下に、Terrafomから利用するファイルを示します。

terraform.tfvars : terraformテンプレートで利用する変数をここにまとめます。

.tfbackend : リソースの状態を保存するための.tfstateファイルを、CDを実現するためにGCSに出力するよう設定します。その設定をファイルに定義します。

provider.tf

deploy.tf

デプロイは以下のコマンドで行います。

図中4,5,6,7のリソースは複数のシステムで共有するので別の.tfファイルで管理しています。.tfvarsや.tfbackend、provider.tfはほとんど共通のものを利用しているのでdeploy.tfのみ紹介します。

deploy.tf

GCSバケットやBigQueryのテーブルなどのリソースもTerraformで管理することができますが、terraform destroy等のコマンドで誤って削除してしまうリスクが高いのでTerraformでは管理していません。

ちょっとした黒魔術

詳細は割愛しますが、実際には変数を.tfvarsファイルのみに集約するために、.tfvarsファイルから.tfbackendファイルや、環境変数定義用のシェル生成を行っています。.tfvarsファイルはシンプルなので、シェルスクリプトで簡単にパースできます。

Github Actions

CDを実現するために、Github Actionsを利用しています。

./github/workflows/ 内にyamlファイルを置いておくと、ファイルに記述したコードをGithub上で実行させることができます。このシステムでは、deployブランチにプッシュされたときに、terraformを使ってリソースのデプロイが自動的に行われるように設定しています。また、事前にsecretsにサービスアカウントキーを登録することで、安全にサービスアカウントが利用できます。

./github/workflows/deploy.yml

Cloud Functionsのコード変更をTerraformで検知して更新することができないので、Github Actionsからdestroyして更新していますが、コードのハッシュ値を利用して変更を検知および更新することができるようです。

https://github.com/hashicorp/terraform-provider-google/issues/1938

まとめ

今回は、僕が開発しているデータ基盤の話を技術面にフォーカスして書いてみました。実際のコードはもっと複雑で量が多いのですが、シンプルにするためにかなり削ったり改変したりしました。大変でした・・・ですので、ニッチな内容が多いかと思いますが、どこかの誰かに少しでも参考にしていただければ幸いです。

明日は「SHAP Values で 機械学習を「解釈」する」を公開予定です。


Yuki Okuda
Technology Div. 所属
GiXoでエンジニアをやっています。

SERVICE