Glue JobでRedshift Serverlessに接続する


# はじめに
Glue Job(Sparkタイプ)を使って、Redshift Serverlessのデータを参照したりインサートしたりするために、
GlueデータカタログのConnectionを使って、Redshift Serverlessと接続する方法を整理しています。

以下のAWS記事を参考にしています。
[ユーザーガイド: Redshift 接続](https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-connect-redshift-home.html#aws-glue-programming-etl-redshift-using)
[Repost: 接続トラブルシューティング](https://repost.aws/ja/knowledge-center/glue-test-connection-failed)




# この記事でわかること
 - [接続に必要なAWSリソース一覧](#リソース一覧)
 - [AWSマネージメントコンソールの設定内容](#設定手順)
:::note warn
本記事では接続までで、GlueJobを実行する部分は[次回記事](https://qiita.com/tamabe/items/b7d0ccf206dab9d90c19)にて掲載します
:::




# 構成図
Glue JobとRedshift Serverless間の接続についての構成を、図にしてみます。
![Glue JobでRedshift Serverlessに接続する.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618752/73533a6a-c19b-9f7d-706c-cb330fb042d2.png)




# リソース一覧
IAM関係リソース
 - Glue Job用のIAMロール、ポリシー
 - Redshift Serverless用のIAMロール、ポリシー

Glue Jobのロールには、S3アクセス関連のポリシーを付与（Redshift関連は不要）し、
Redshift用のロールには、S3の読み取りと書き込みを許可するポリシーが必要[^10]です。

---

ネットワーク関係リソース
 - Glue用VPCプライベートサブネット
 - Redshift Serverless用VPCプライベートサブネット × 3
 - Connection用のセキュリティグループ

Glue JobがVPC内で動くときのサブネットを指定します。
Redshift Serverlessのワークグループは、サブネットを3つ以上紐づけが必要です[^6]。
今回のセキュリティグループは、GlueとRedshift双方に設定するものを作成します[^9]。

---

Glue関連リソース
 - Glue Job
 - GlueデータカタログConnection

Glue Jobに、作成したGlue Job用のロールを紐づけます。
Glue Connectionには、サブネットやセキュリティグループ、Redshiftの認証情報なども設定していきます。

---

Redshift Serverless関連リソース
 - Redshift Serverlessワークグループ、名前空間

ワークグループに、サブネット、セキュリティグループを設定します。
名前空間には、ロールを紐づけます。

---
（その他Glue Job実行時に必要なリソース）
 - S3バケット
 - S3用VPCエンドポイント

SparkタイプGlue JobでConnectionを使ってRedshiftに接続する場合、
データの移動はS3を経由して行われる[^1][^8]ため、Glue Jobを実行する際にはS3が必要となります。

またそのときVPC内のConnectionがVPC外のS3と接続するために、エンドポイントが必要です。
（ゲートウェイ型のエンドポイントを利用しています）





# 設定手順
AWSマネージドコンソールの設定画面をもとに整理しています。
※プライベートサブネット, S3バケット, S3用ゲートウェイエンドポイントは、作成済みとして進めます。
1. [セキュリティグループの設定](#セキュリティグループの設定)
1. [IAMの設定](#iamの設定)
1. [Redshift Serverlessの設定](#redshiftserverlessの設定)
1. [Glueの設定](#glueの設定)
1. [接続確認してみる](#接続確認してみる)
1. [Glue Jobを実行してみる(次回記事)](#gluejobを実行してみる次回記事)

### セキュリティグループの設定
VPC画面サイドバーのセキュリティグループから、セキュリティグループを作成します。
インバウンドルールに自己参照ルールを設定します。
(自己参照ルールとは[^3])
>[Type (タイプ)] All TCP、[Protocol (プロトコル)] は TCP、[Port Range (ポート範囲)] にはすべてのポートが含まれ、[Source (ソース)] は [Group ID (グループ ID)] と同じセキュリティグループ名であるというルール

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618752/93ec04a0-2add-2de3-6e9c-621338290bee.png)



アウトバウンドルールは、自己参照ルールと、S3エンドポイントへのアクセスを許可するルールを設定します[^9]。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618752/dcdd2083-81a6-c4f7-2ea7-5471b2f81e6d.png)





### IAMの設定
IAM画面サイドバーのロールから、IAMロールを作成します。まずはRedshiftServerless用のロールを作成します。
まず、Redshift Serverlessがこのロールを使用できるように信頼ポリシーを定義しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618752/b4b7a8ab-9f91-a652-4068-c921be134fcc.png)


続けて、ロールにアタッチするポリシーの設定をします。
S3の読込み、書込みアクションを許可します。
```json:RedshiftServerlessのポリシー
{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Effect": "Allow",
			"Action": [
				"s3:ListBucket",
				"s3:GetObject",
				"s3:PutObject",
				"s3:DeleteObject",
				"s3:AbortMultipartUpload",
				"s3:ListMultipartUploadParts",
				"s3:ListBucketMultipartUploads"
			],
			"Resource": [
				"arn:aws:s3:::<利用するS3バケット名>/*",
				"arn:aws:s3:::<利用するS3バケット名>"
			]
		}
	]
}
```

次に、GlueJob用のロールを作成します。
まず、Glue Jobがこのロールを使用できるように信頼ポリシーを定義しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618752/8fe81fbd-1a20-e4d1-fcc8-6be93edf2220.png)


続けて、ロールにアタッチするポリシーを設定します。
GlueJobの実行関連アクション許可、S3の読込み、書込みアクション許可、ネットワーク関連アクション許可を設定します。
（CloudWatch関連アクション許可は任意ですが、今後ログ確認するために設定しています）
```json:GlueJobのポリシー
{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Effect": "Allow",
			"Action": [
				"glue:GetConnection",
				"glue:StartJobRun",
				"glue:GetJobRun",
				"glue:GetJobRuns",
				"glue:BatchStopJobRun"
			],
			"Resource": [
				"arn:aws:glue:*:*:*"
			]
		},
		{
			"Effect": "Allow",
			"Action": [
				"s3:GetObject",
				"s3:PutObject",
				"s3:ListBucket"
			],
			"Resource": [
				"arn:aws:s3:::<利用するS3バケット名>/*",
				"arn:aws:s3:::<利用するS3バケット名>"
			]
		},
		{
			"Effect": "Allow",
			"Action": [
				"ec2:DescribeVpcAttribute",
				"ec2:DescribeVpcs",
				"ec2:DescribeSubnets",
				"ec2:DescribeSecurityGroups",
				"ec2:DescribeNetworkInterfaces",
				"ec2:DescribeVpcEndpoints",
				"ec2:DescribeRouteTables",
				"ec2:CreateTags",
				"ec2:CreateNetworkInterface",
				"ec2:DeleteNetworkInterface"
			],
			"Resource": [
				"*"
			]
		},
		{
			"Effect": "Allow",
			"Action": [
				"logs:CreateLogGroup",
				"logs:CreateLogStream",
				"logs:PutLogEvents"
			],
			"Resource": "arn:aws:logs:*:*:log-group:*"
		},
		{
			"Effect": "Allow",
			"Action": [
				"cloudwatch:PutMetricData",
				"cloudwatch:GetMetricData",
				"cloudwatch:GetMetricStatistics",
				"cloudwatch:ListMetrics"
			],
			"Resource": "*"
		}
	]
}
```

### RedshiftServerlessの設定
Redshift画面からサーバレスダッシュボード画面に移動し、ワークグループを作成します。
プライベートサブネット3つと、先ほど作成したセキュリティグループを設定します。
（今回必要な設定以外は、基本デフォルト設定のままにしています）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618752/ad36551f-9ddd-2484-6958-a3299d67074c.png)


続けて、名前空間を設定します。
（管理者ユーザー名とパスワードは任意で問題ないですが、後でGlue Connection設定で使います）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618752/1705e391-b752-dd47-8ad3-16eac366f847.png)




### Glueの設定
Glue画面サイドバーのData Connectionsに移動し、Redshift用Connectionを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618752/9f6f015f-0313-8660-1210-4381ad635cd4.png)


作成したRedshiftServerlessのワークグループとデータベース名（デフォルトのdev）を指定します。
Redshift認証情報は今回、RedshiftServerless名前空間作成時に設定した管理者ユーザーとパスワードを直書きして設定しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618752/f3b9fdac-853b-ef79-a39f-13963f2cd37d.png)

作成後、Connectionの設定を確認すると、ネットワーク情報（JDBC URL, サブネット, セキュリティグループ）が自動で設定されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618752/a6149621-2204-7449-a168-c7695e56bfdf.png)

次に、Glue Jobを作成します。Glue画面サイドバーのETL jobsから新規作成を行います。
Job detailsタブにて、作成したGlueJob用ロールを設定します。タイプは「Spark」を指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618752/82c9ca4c-0d15-ced4-e3f8-50f5cbe44df4.png)

Connections設定には、先ほど作成したConnectionを指定します。
（その他、今回必要な設定以外は、基本デフォルト設定のままにしています）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618752/81b81146-6e67-b294-67a0-65306f1f97ba.png)




### 接続確認してみる
Data Connectionsの画面に戻って、作成したConnectionを選択し、接続確認を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618752/addfc461-92ae-2ced-10f4-7938142f6b1b.png)


GlueJobロールを指定して、接続確認します。
（Connectionに設定されているJDBC URLに対して、テスト接続が行われます）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618752/c7ecb295-9968-47fe-9627-df249378fdd1.png)

少し待つと、接続に成功した画面が確認できました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618752/0424e74f-ae80-a474-f5e4-4a97afeebb9d.png)


### GlueJobを実行してみる(次回記事)
Glue Jobで使うスクリプトの内容や一時保管用S3の場所を設定する方法など、次回の記事で詳細整理します。




# 最後に
GlueとRedshift Serverlessを接続するための具体的な手順を整理しました。
今回はRedshift認証情報をConnection設定に直書きしていますが、
Secrets Managerを使ったりなど、よりセキュアな接続方法にカスタマイズ可能なので、また整理したいと思います。

次回記事では、作成した接続を使って実際にGlue Jobを実行し、
Redshift Serverlessのテーブルにデータインサートを行う方法を整理しています。

https://qiita.com/tamabe/items/b7d0ccf206dab9d90c19


# 参考URL
この記事で参考にしたURLです。
[^1]:AWS記事：Redshift connections
https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-connect-redshift-home.html#aws-glue-programming-etl-redshift-using

[^9]:AWS記事：Redshift connections - Set up Amazon VPC
https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-connect-redshift-home.html#aws-glue-programming-etl-redshift-config-vpc

[^10]:AWS記事：Redshift connections - Configuring IAM roles
https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-connect-redshift-home.html#aws-glue-programming-etl-redshift-config-iam

[^2]:AWS Repost：接続トラブルシューティング
https://repost.aws/ja/knowledge-center/glue-test-connection-failed

[^3]:AWS記事：AWS Glue のための開発用ネットワークの設定
https://docs.aws.amazon.com/ja_jp/glue/latest/dg/start-development-endpoint.html

[^4]:AWS記事：JDBC接続
https://docs.aws.amazon.com/ja_jp/glue/latest/dg/aws-glue-programming-etl-connect-jdbc-home.html

[^5]:AWS記事：GlueContext クラス
https://docs.aws.amazon.com/ja_jp/glue/latest/dg/aws-glue-api-crawler-pyspark-extensions-glue-context.html
https://docs.aws.amazon.com/ja_jp/glue/latest/dg/aws-glue-api-crawler-pyspark-extensions-dynamic-frame-writer.html

[^6]:Amazon Redshift サーバーレスを使用する場合の考慮事項
https://docs.aws.amazon.com/ja_jp/redshift/latest/mgmt/serverless-usage-considerations.html

[^7]:Amazon Redshift クラスターまたは Amazon Redshift Serverless ワークグループのセキュリティグループ通信設定の構成
https://docs.aws.amazon.com/ja_jp/redshift/latest/mgmt/rs-security-group-public-private.html

[^8]:Apache Spark の Amazon Redshift 統合
https://docs.aws.amazon.com/redshift/latest/mgmt/spark-redshift-connector.html#spark-redshift-connector-considerations