Glue の「接続」を作ってジョブにアタッチすると、VPC エンドポイント経由で S3 にアクセスできる。VPC エンドポイントポリシーでアクセス可能な S3 バケットを絞りたい場合は、業務で使うバケットに加えて Glue ジョブが使うスクリプトディレクトリ(デフォルト: aws-glue-scripts-{AWS Account ID}-{region})、一時ディレクトリ(デフォルト: aws-glue-temporary-{AWS Account ID}-{region}) も許可する必要がある。
事象
- エラーログ
fatal error: An error occurred (403) when calling the HeadObject operation: Forbidden Error downloading script ★: fatal error: An error occurred (403) when calling the HeadObject operation: Forbidden
- ログ
--conf spark.hadoop.yarn.resourcemanager.connect.max-wait.ms=60000 --conf spark.hadoop.fs.defaultFS=hdfs://172.17.2.84:8020 --conf spark.hadoop.yarn.resourcemanager.address=172.17.2.84:8032 --conf spark.dynamicAllocation.enabled=true --conf spark.shuffle.service.enabled=true --conf spark.dynamicAllocation.minExecutors=1 --conf spark.dynamicAllocation.maxExecutors=2 --conf spark.executor.memory=5g --conf spark.executor.cores=4 --conf spark.driver.memory=5g --JOB_ID j_d92fbdf94cb508d0ec9912ae6cf5d9aab616d829cc92da206f1a7f7849f3790e --JOB_RUN_ID jr_1d116a91943a03339a39f5e88a8ff16ac3a74a841f684f7547ab7999dcc44eb8 --job-bookmark-option job-bookmark-disable --scriptLocation s3://aws-glue-scripts-123456789012-ap-northeast-1/admin/PrivateTest ★ --job-language python --TempDir s3://aws-glue-temporary-123456789012-ap-northeast-1/admin ★ --JOB_NAME PrivateTest Detected region ap-northeast-1 Detected glue endpoint https://glue.ap-northeast-1.amazonaws.com YARN_RM_DNS=172.17.2.84 JOB_NAME = PrivateTest PYSPARK_VERSION 3 python3 Specifying ap-northeast-1 while copying script. S3 copy with region specified failed. Falling back to not specifying region.
前提
- 設定していた VPC エンドポイントポリシー
{ "Version": "2008-10-17", "Statement": [ { "Effect": "Allow", "Principal": "*", "Action": "*", "Resource": [ "arn:aws:s3:::datalake-landing", "arn:aws:s3:::datalake-landing/*", "arn:aws:s3:::datalake-main", "arn:aws:s3:::datalake-main/*" ] } ] }
- 実行した Glue ジョブのコード(PySpark)
import sys from awsglue.transforms import * from awsglue.utils import getResolvedOptions from pyspark.context import SparkContext from awsglue.context import GlueContext from awsglue.job import Job sc = SparkContext() glueContext = GlueContext(sc) spark = glueContext.spark_session job = Job(glueContext) job.init('test job') df = spark.read.csv("s3://datalake-landing/test.csv") df.coalesce(1).write.mode('overwrite').csv("s3://datalake-main/")
解決策
{ "Version": "2008-10-17", "Statement": [ { "Effect": "Allow", "Principal": "*", "Action": "*", "Resource": [ "arn:aws:s3:::glue-private-test", "arn:aws:s3:::glue-private-test/*", "arn:aws:s3:::log-raw-az", "arn:aws:s3:::log-raw-az/*" ] }, { "Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": [ "arn:aws:s3:::aws-glue-scripts-123456789012-ap-northeast-1", "arn:aws:s3:::aws-glue-scripts-123456789012-ap-northeast-1/*" ] }, { "Effect": "Allow", "Principal": "*", "Action": [ "s3:PutObject", "s3:GetObject", "s3:DeleteObject" ], "Resource": [ "arn:aws:s3:::aws-glue-temporary-123456789012-ap-northeast-1", "arn:aws:s3:::aws-glue-temporary-123456789012-ap-northeast-1/*" ] } ] }
- 上記は東京リージョンでデフォルトのケース。--scriptLocation や --TempDir を明示的に指定する場合はそのバケットの ARN を指定する。
参考
- --scriptLocation - ETL スクリプトが s3://path/to/my/script.py のような形式で配置されている Amazon Simple Storage Service (Amazon S3) の場所。これは、JobCommand オブジェクトで設定されているスクリプトの場所を上書きします。
- --TempDir - ジョブの一時ディレクトリとして使用できるバケットへの Amazon S3 パスを指定します。
たとえば、一時ディレクトリを設定するには、以下の引数を渡します。
'--TempDir': 's3-path-to-directory'https://docs.aws.amazon.com/ja_jp/glue/latest/dg/aws-glue-programming-etl-glue-arguments.html
現状、データソースとしてS3にプライベートアクセスを行いたいだけの場合であってもこのような接続設定を介す必要があります。
AWS GlueのジョブでVPCエンドポイントを利用したS3接続を行う - Qiita
これがわかりにくかった。入力したら次に進みます。今回はデータベースへの接続は行わないのですが、JDBC URL/ユーザ名/パスワードが必須
になっているのでここではダミーの情報を入力しました。
VPC endpoints for Amazon S3 can alleviate these challenges. A VPC endpoint for Amazon S3 enables AWS Glue to use private IP addresses to access Amazon S3 with no exposure to the public internet. AWS Glue does not require public IP addresses, and you don't need an internet gateway, a NAT device, or a virtual private gateway in your VPC. You use endpoint policies to control access to Amazon S3. Traffic between your VPC and the AWS service does not leave the Amazon network.
(中略)
https://docs.aws.amazon.com/glue/latest/dg/vpc-endpoints-s3.html