AWSにはデータの検出、準備、統合をする所謂ETL処理をサーバーレスで行う為のサービスとして「AWS Glue」を提供している。Pythonなどのスクリプトも実行できるため、データの加工処理の為に起動していたEC2やECSコンテナが不要になる。今回はPythonスクリプトを AWS Glue
のGlueジョブとして登録し、実行する事にした。
簡単な作成と実行の手順
まずは簡単なジョブを作成し実行する。実行するスクリプトは、標準出力へ「 Ok
」と出力するだけの簡単なスクリプトを使う。
print("Ok")
ETLジョブを作成する
まずETLジョブを作成する。
- AWS GlueでPythonスクリプトを実行する際に使用する、実行ロール(IAM Role)を作成する。
- AWS ConsoleのGlueStudioでジョブの登録を開始する。
https://ap-northeast-1.console.aws.amazon.com/gluestudio/home?region=ap-northeast-1#/jobs
今回は「
Python Shell script editor
」を選択する。 - ローカルのファイルをアップロードする。
Optionsで「
Upload and edit an existing script
」を選択し、ファイルをアップロードする。 - 登録する。 「Create」ボタンをクリックし、登録する。
作成したETLジョブを設定する
作成したETLジョブを実行可能な状態になるように設定する。
- 「Job details」タブを表示する。
- 「Name」に付けたい名前を入力する。
- 「IAM Role」のプルダウンから、使用できるIAM Roleを選択する。
- 「Python version」のプルダウンから、使いたいバージョンを選択する。
- 「Job timeout (minutes)」を1にする。 タイムアウトは最長48時間待つ事ができる。今回の場合、直ぐに終了するため待つ事はないが、ずっと待たれても困るのでタイムアウトを1分に設定した。
- 「Advanced properties」の「Script Filename」に付けたいファイル名を入力する。
- 「Save」ボタンをクリックし保存する。
作成したETLジョブを実行し結果を確認する
- 「Run」ボタンをクリックする。
- 「Runs」タブを表示すると実行状態を確認できる。 Cloudwatch logsのログストリームを作成し追記する権限があれば、ログストリームが作られるため、Cloudwatch logsで出力を確認できる。
Pythonの実行環境
Pythonの実行環境はバージョンを幾つか選択できる。ノーマルな状態なものを使用しても、そこそこパッケージが予めインストールされている。例えばboto3やPyMySQLのようなライブラリは既に入っている。どのパッケージが入っているかは、公式のドキュメントから確認できる1。
パーミッションとアシュームロール
AWS GlueのETLジョブとしてPythonシェルを使用する場合、実行ロールには最低でもS3への権限と、アシュームロールの設定が必要となる。
S3へのパーミッション
スクリプトがS3にアップロードされる事を考えると、当然S3への権限が必要となる。それについて公式のドキュメントにも記述されている2。
リソースはもっと絞った方が良いかもしれない。またSSE-KMSを使う場合は、その権限も必要となる。それも公式のドキュメントに記載がある。
アシュームロール
ジョブの実行には、以下の権限が必要となる。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "glue.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
Cloudwatch Logsへのパーミッション
一応これまでの状態の権限を付けてあげれば、ジョブ自体は実行できる。ただし、標準出力や標準エラー出力はCloudwatch Logsとして出力されるため、Cloudwatch Logsへの権限がないとスクリプトの出力を確認できない。
スクリプトにパラメータを渡す
この実行方法の場合、実行環境に対して環境変数を設定する手段がない。もちろんスクリプト内で設定はできるが、それでは意味がない。変わりに起動オプションを指定できる。そこで起動オプションにパラメータを設定する事になる。
この起動オプションの仕組みが結構やっかいで、最初から設定されている起動パラメータもあり、そこに更に指定したいパラメータを追加していく。そのため、AWS Glueが必要としている物と、スクリプトが必要としている物が混在する。起動オプションだからsys.argvからアクセス可能ではあるけれど、シンプルにargparseで解析する場合、AWS Glueが必要としているオプションも解析する事になってしまう。これは面倒だ。
AWS Glueではそれを回避する為に awsglue
というパッケージを提供していて、これを用いてオプションを解析できるようにしている。
例えば "–FOO_PARAM 3" と指定されるように、新しくオプションを追加した場合、 awsglue.utils.getResolvedOptions
を使って解析し、最後の行が評価されると "3" という値となる。
from awsglue.utils import getResolvedOptions
aws_glue_args = getResolvedOptions(
sys.argv, [
"FOO_PARAM",
])
aws_glue_args["FOO_PARAM"] # => "3"
VPC内での実行
VPC内に設置されているRDS等と接続する場合、Connectionsで接続設定を事前に作成しておく必要がある。これを作成した後、GlueジョブにConnectionsを関連付ける事で、VPC内にあるコンポーネントとのネットワーク接続ができるようになる3。