RedshiftでVPCルーティングを利用し、VPCエンドポイント経由でデータをロードする
コンニチハ、千葉です。
RedshiftのルーティングをVPCルーティングにて制御できるようになってました。以前は、RedshiftのルーティングはVPCルートテーブルでは制御できませんでした。
例えば、Redshiftをプライベートサブネットに配置、インターネットに接続できない環境でも、S3とインターネット経由にて通信できました。また、VPCエンドポイントを設定しても反映されずに、インターネット経由での通信となっていました。
今回のアップデートは、「Enhanced VPC Routing」という設定項目が追加され、こちらを有効にすることでVPCにて設定しているルートテーブルに従った通信を行うようになります。このパラメータは、新規作成時にも、既存のクラスタに対しても設定できます。
注意事項
注意いただきたいのですが、Enhanced VPC Routingを有効にする前にルートテーブルが意図した設定になっているかご確認ください。有効にしたタイミングで、通信ができなくなる可能性があります。ルートテーブル、VPCエンドポイント、ACL、VPCエンドポイントポリシー、インターネットゲートウェイ、S3バケットポリシーなど設定をご確認ください。
また、Enhanced VPC Routingを有効にしたタイミングにて一時的(数分)にReshiftへアクセスできない時間が発生しましたので、こちらも合わせてご注意ください。
嬉しいこと
まず、S3へはVPCエンドポイント経由にてプライベート接続が可能になります。
もう一つ、S3バケットポリシーでソースIPにてRedshiftのパブリックIPを指定している環境がありました。この環境に対して、Redshiftノード追加を行うとパブリックIPが全て書き変わってしまうので、毎度毎度、複数のバケットに対してポリシー変更を行う必要がありました。こちらを有効にすることで、バケットポリシーはIPベースではなくVPC単位でアクセス許可することができるようになりました。毎度毎度の変更が不要になりました!
やったね!
検証してみた方法
既存のRedshiftに対して、VPCルーティングが反映されるかを確認してみました。
ステップ1
- Redshift
- プライベートサブネットに配置
- S3
- Reshiftからのアクセスを許可したS3バケットポリシーを設定
まずは、この環境でロードできることを確認します。
ステップ2
- VPC
- プライベートサブネットに対してVPCエンドポイントを設定します。
- Redshift
- Enhanced VPC Routingを有効可
通信が、VPCエンドポイント経由になるので、IPアドレスで許可しているS3へアクセスできなくなることを想定。ロードが失敗するはず。
ステップ3
- S3
- バケットポリシーをVPCでアクセス許可
VPCエンドポイント経由にてアクセスし、ロードが成功する
やってみた
ステップ1
Redshiftをプライベートサブネットに配置します。
S3バケットポリシーには以下を設定(RedshiftのパブリックIPアドレスのみ通信するように許可)
※RedshiftのIPに加え、自分の端末のソースIPも追加しましょう。でないと、操作できないバケットが誕生します。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "Allow-from-specific-IP", "Effect": "Deny", "Principal": "*", "Action": "s3:*", "Resource": [ "arn:aws:s3:::redshift-test99", "arn:aws:s3:::redshift-test99/*" ], "Condition": { "NotIpAddress": { "aws:SourceIp": [ "xx.xx.xx.xx/32", "xx.xx.xx.xx/32" ] } } ] }
S3からデータをロードしてみます。
chiba=# copy part from 's3://redshift-test99/load/part-csv.tbl' CREDENTIALS 'aws_iam_role=arn:aws:iam::xxxxxxxxxxxx:role/redshift' REGION 'ap-northeast-1' csv null as '\000'; INFO: Load into table 'part' completed, 49999 record(s) loaded successfully. COPY
ロードできました!
ステップ2
VPCエンドポイントを有効にします。
Redshiftの設定Enhanced VPC Routingを有効にします。
設定変更中は、Redshiftに一時的にアクセスできなくなるのでご注意ください!
設定が完了したので、VPCエンドポイント経由になり、S3にアクセスできず、ロードエラーになるはずです。
chiba=# copy part from 's3://redshift-test99/load/part-csv.tbl' chiba-# CREDENTIALS 'aws_iam_role=arn:aws:iam::xxxxxxxxxxxx:role/redshift' chiba-# REGION 'ap-northeast-1' chiba-# csv chiba-# null as '\000'; ERROR: S3ServiceException:Access Denied,Status 403,Error AccessDenied,Rid 48A670758CE902FF,ExtRid GBu5y3l2X66UO2CayKe6d8fVQhQ8h1nAxPFeHMsNYA6xVXwzNMm1kXCmj9aJHNizE9Z0g5C2XzY=,CanRetry 1 DETAIL: ----------------------------------------------- error: S3ServiceException:Access Denied,Status 403,Error AccessDenied,Rid 48A670758CE902FF,ExtRid GBu5y3l2X66UO2CayKe6d8fVQhQ8h1nAxPFeHMsNYA6xVXwzNMm1kXCmj9aJHNizE9Z0g5C2XzY=,CanRetry 1 code: 8001 context: Listing bucket=redshift-test99 prefix=load/part-csv.tbl query: 1599 location: s3_utility.cpp:532 process: padbmaster [pid=7837] -----------------------------------------------
エラーになりました!
ステップ3
S3バケットポリシーを変更し、VPCにて許可してみます。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "Allow-from-specific-IP", "Effect": "Deny", "Principal": "*", "Action": "s3:*", "Resource": [ "arn:aws:s3:::redshift-test99", "arn:aws:s3:::redshift-test99/*" ], "Condition": { "NotIpAddress": { "aws:SourceIp": [ "xx.xx.xx.xx/32" ] }, "StringNotEquals": { "aws:sourceVpc": "vpc-xxxxxxxx" } } } ] }
これで、ロードできるようになっているはずです。
chiba=# copy part from 's3://redshift-test99/load/part-csv.tbl' CREDENTIALS 'aws_iam_role=arn:aws:iam::xxxxxxxxxxxx:role/redshift' REGION 'ap-northeast-1' csv null as '\000'; INFO: Load into table 'part' completed, 49999 record(s) loaded successfully. COPY
ロードできました!
まとめ
RedshiftがVPCルーティングに対応したため、EC2のようにACL、インターネットゲートウェイ、VPCに対応できます。また、S3バケットポリシーでのアクセス制御がとても楽になりました。
本番環境に設定を入れようっと。
参考
https://docs.aws.amazon.com/ja_jp/redshift/latest/mgmt/enhanced-vpc-routing.html