先に結論
- GlueジョブでVPCエンドポイントを介してS3接続をおこなうにはJDBCタイプの接続設定が必要
やりたいこと
AWS GlueのETLジョブではVPCエンドポイントを使用して、インターネットを経由せず
S3へのアクセスを行うことができます。
以下のドキュメントに記載されている通りです。
Amazon VPC Endpoints for Amazon S3
https://docs.aws.amazon.com/glue/latest/dg/vpc-endpoints-s3.html
Glueが指定したプライベートサブネット上でENIを作成し、そのENIに割り当てられたプライベートIPで
VPCエンドポイントを経由してS3にアクセスします。
やりたいことはこれだけなのですが、ジョブ自体にはS3のアクセスやVPCサブネットを指定する方法がなく
設定に戸惑ったため、手順を残しておきます。
ここでは以下の内容には触れません。
- VPCやVPCエンドポイントの作成、設定
- Glueジョブの作成
接続設定の追加
Glueのコンソールメニューから、データカタログのデータベース→接続と進み、接続の追加を選択します。
接続のプロパティの設定で任意の接続名を入力し、接続タイプで JDBC を選択します。
現状、データソースとしてS3にプライベートアクセスを行いたいだけの場合であっても
このような接続設定を介す必要があります。
これがわかりにくかった。入力したら次に進みます。
今回はデータベースへの接続は行わないのですが、JDBC URL/ユーザ名/パスワードが必須
になっているのでここではダミーの情報を入力しました。
もちろんオンプレミスデータベースの接続情報を入力し、DirectConnectを介して
接続するなどの用途にも実際には使用することが可能です。
更にその下の設定でVPC/Subnet/セキュリティグループを指定することができます。
ここで指定するプライベートサブネットにS3のVPCエンドポイントが存在し、
適切なルート情報が設定されていれば、GlueジョブはS3へプライベート接続を行います。
設定するセキュリティグループには全てのTCPポートに対する自己参照のインバウンドルール
が含まれている必要があります。自己参照ルールというのは以下のように
送信元に自身のセキュリティグループが設定されているルールのことを指します。
最後に設定の確認を行い、接続の追加を完了します。
ちなみに接続のテストは指定したJDBC URLに対し接続確認を行います。
エンドポイントを経由したS3アクセスを確認するものではありません。
ダミーのJDBC情報を入力している場合は、当然のことながらテストは失敗します。
ジョブ設定の編集
対象のジョブ設定で、すべての接続に先ほど追加した接続設定が追加されています。
選択をクリックすると要求される接続に設定が追加されますので、この状態でジョブ設定を保存します。
動作確認
バケットポリシーで対象VPCエンドポイント経由のみを許可したバケットをデータソース/結果出力先として
ジョブを実行し、正常終了することを確認しました。
またCloudWatch Logsに保存されているジョブのログを参照し、VPCのプライベートIPが使用されていること
を確認することもできます。
注意点など
S3バケットのリージョン
S3のVPCエンドポイントを使用する際の基本的な注意点ではありますが、
VPCエンドポイントが存在するリージョンとS3バケットが存在しているリージョンは
同一である必要があります。
サブネットの利用可能なIP数を考慮する
前述の通りプライベート接続を使用したジョブを実行するとGlueにENIが割り当てられます。
特にサブネットを細かく分割している場合に、サブネットで利用可能なIPv4の残数に注意してください。
Resource unavailable(メッセージがわかりにくい…)でジョブがFailedする場合は
IPが枯渇している可能性が高いです。
Troubleshooting Errors in AWS Glue - Error: Resource Unavailable
https://docs.aws.amazon.com/glue/latest/dg/glue-troubleshooting-errors.html#error-resource-unavailable
For any connections and development endpoints that you use, check that your cluster has not run out of elastic network interfaces.
ジョブ起動までの時間
些細な点ですが、プライベート接続を使用したジョブを起動すると通常よりも処理開始まで
時間がかかるようになりました。ENIの割当等で余計に時間を使っているのだと思われます。
Python shell
最近追加されたPython shellで試してみましたが、ジョブに接続設定を追加しても
現状はVPCエンドポイント経由の接続とはならないようです。
以下のような超簡易ジョブを実行してみたところ、指定したVPCのIPアドレスにならなかったので。
import os
os.system("env")
os.system("ip -f inet addr")
結果は以下のような感じ。
HOSTNAME=ip-172-31-41-88
USE_PROXY=true
PYTHON_PIP_VERSION=9.0.1
HOME=/
AWS_DEFAULT_REGION=ap-northeast-1 PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/amazon/bin:/opt/amazon/usr/bin
LANG=C.UTF-8
PYTHON_VERSION=2.7.14
GLUE_INSTALLATION=/glue/lib/installation
PWD=/tmp PYTHONPATH=:/glue/lib/installation
ERROR_FILE_NAME_LOCATION=/reporting/error.txt
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever
8: eth0@if9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
inet 169.254.76.2/32 scope global eth0 valid_lft forever preferred_lft forever
Introducing Python Shell Jobs in AWS Glue
https://aws.amazon.com/jp/about-aws/whats-new/2019/01/introducing-python-shell-jobs-in-aws-glue/
以上です。
参考になれば幸いです。