GAデータをs3にエクスポート(前編)
GAのデータをAWSのリソース中で利用する場面があったのですが、AWSからGCPの記事はあってもGCPからAWSへの記事があまりなかったので、まとめて見ようと思います。
GAのデータは毎日更新されるので自動でcsvにしてs3にエクスポートされるバッチを構築していきます。
目次
- 全体像(構成図)
- GAからBigQuery
- VMマシンの設定
- AWSの認証
- BigQueryからGCSへのエクスポート方法
- GCSからS3にエクスポート方法
- 定期実行の処理
- 定期実行番外編
全体像
GAにはいくつかエクスポート機能がありますが、今回はBigQueryにGAデータをエクスポートし、Cloud Storegeを経由してs3にエクスポートします。
あらかじめGCP上にプロジェクトを用意しておいてください。
GAからBigQuery
GAの設定しBigQueryとリンクすると24h以内にデータがエクスポートされます。 今回は詳しい設定は省きます。 GAのドキュメント
VMインスタンスの設定
エクスポートを定期的に実行するためのバッチをGCEのVMインスタンス上におきます。
VMインスタンスの設定をしていきます。
がそのまえに、インスタンスが利用するサービスアカウントを用意します。
IAMと管理のサービスアカウントから作成します。
最低限以下の権限があれば問題ないです。
bigquery.datasets.get
bigquery.jobs.create
bigquery.tables.create
bigquery.tables.delete
bigquery.tables.export
bigquery.tables.get
bigquery.tables.getData
bigquery.tables.list
bigquery.tables.updateData
logging.logEntries.create
storage.buckets.get
storage.buckets.list
storage.objects.create
storage.objects.delete
storage.objects.get
storage.objects.list
今回はBigQueryの管理者とStoregeの管理者をつけて作成します(後で必ず絞りましょう。)
次はVMインスタンスの設定に入ります。
基本的に数分しか実行しない&実行時しかインスタンスを起動させないのでどのスペックでも問題ないと思います。強いて言うなら、低スペックインスタンスだと最初の環境構築でパッケージをインストールするのに時間がかかるのが気になるくらいです。
リージョンは揃えておきましょう。
- E2/e2-micro
- 10GBバランス永続ディスク
- Debian GNU/Linux 11 (bullseye)
で作成します。
サービスアカウントは先ほど作成したものを忘れずにつけます。
AWSの認証
外部からAWSのリソースにアクセスするにはAWSの認証をしなければなりません。今回は、AWS STSでGCPのサービスアカウントを使ってS3にアクセスしていきます。
GCPでサービスアカウントの作成 → done
AWSでロールの作成
GCPインスタンスにサービスアカウントを紐づけ
GCPインスタンス上のS3にアクセスするコードを修正
という流れで認証していきます。
こちらの記事を参考にさせていただきました。
記事ではGoでメインの処理内で認証情報を取得していますが、今回は、認証情報を取得するスクリプトを.aws/credentialsで読み込ませ認証させます。
#!/usr/bin/python3
import requests
import boto3
import json
import sys
def get_metadata(path: str, parameter: str):
# Use .format() instead of f-type to support python version before 3.7
metadata_url = 'http://metadata.google.internal/computeMetadata/v1/{}/{}'.format(path, parameter)
headers = {'Metadata-Flavor': 'Google'}
# execute http metadata request
try:
meta_request = requests.get(metadata_url, headers=headers)
except requests.exceptions.RequestException as e:
raise SystemExit(e)
if meta_request.ok:
return meta_request.text
else:
raise SystemExit('Compute Engine meta data error')
if __name__ == '__main__':
# Get aws arn from command line argument
try:
aws_role_arn = sys.argv[1]
except IndexError:
print('Please specify AWS arn role:\n{} arn:aws:iam::account-id:role/role-name'.format(sys.argv[0]))
exit(0)
# Get variables from the metadata server
instance_name = get_metadata('instance', 'hostname')
project_id = get_metadata('project', 'project-id')
project_and_instance_name = '{}.{}'.format(project_id, instance_name)[:64]
token = get_metadata('instance', 'service-accounts/default/identity?format=standard&audience=gcp')
# Assume role using gcp service account token
sts = boto3.client('sts', aws_access_key_id='', aws_secret_access_key='')
res = sts.assume_role_with_web_identity(
RoleArn=aws_role_arn,
WebIdentityToken=token,
RoleSessionName=project_and_instance_name)
aws_temporary_credentials = {
'Version': 1,
'AccessKeyId': res['Credentials']['AccessKeyId'],
'SecretAccessKey': res['Credentials']['SecretAccessKey'],
'SessionToken': res['Credentials']['SessionToken'],
'Expiration': res['Credentials']['Expiration'].isoformat()
}
print(json.dumps(aws_temporary_credentials))
こちらをインスタンスの.aws/credentialsに配置していきます。(実行権限を忘れずにつけましょう!)
[default]
credential_process = /home/user/janus.py {AWSロールのARN}
パスは適宜読み替えてください。
BigQueryからCloud Storege
Storegeにエクスポートするタイミングでcsvに変換します。
BigQueryからstoregeにエクスポートする方法はいくつかあるみたいです。
- コンソールからエクスポート
- SQLコマンドのEXPORT DATA
- BigQueryクライアント
プログラムからエクスポートするので2か3になりますが、今回は2のEXPORT DATAコマンドを利用します。
from google.cloud import bigquery
client = bigquery.Client(project={project_id})
export_query = f"""
EXPORT DATA OPTIONS(
uri='gs://{GCSバケットurl}/{ファイル名}-*.csv',
format='CSV',
overwrite=true,
header=true,
field_delimiter=','
) AS
SELECT * FROM `{project_id}.{data_set_id}.{table_name}`;
"""
client.query(query_export).result()
SQLの中でオプションの設定ができます。 1GB以上のエクスポートの場合、自動的に分割しエクスポートされます。その場合、ファイル名の中にワイルドカードを含めなければならないとドキュメントにはありました。ただ、そこまで大きくないテーブルだったので、ワイルドカードなしのファイル名で指定したところ、エラーでエクスポートできませんでした。そのため、ファイル名にワイルドカードを含めています。
このスクリプトを実行すると指定したGCSバケットにcsvとしてエクスポートされます。
後半に続く…