目的
Redshift から他アカウントの S3 に AssumeRole を使ってアクセスする方法が意外とややこしかったので整理する。
想定状況
2つのアカウントを持っていて、 Account A (accountID:111111111111) には Redshift があり、 Account B (accountID:222222222222) に存在する S3 にアクセスする必要がある。
このアクセス方法はいくつかあるが、今回は AssumeRole による一時認証を使う方法を採用する。
手順の概要
- Account A で Redshift 割り当て用のロール(AccountA-Redshift-Role)を作成する
- Account B で AccountA-Redshift-Role に対して S3 アクセスを信頼する Role(accountB-S3-Assume-Role) を作成する
- Account A の Redshift 用のロールに accountB-S3-Assume-Role を引き受けるポリシーを追加する
- Account A の Redshift に AccountA-Redshift-Role を割り当て、 Account B の S3 へアクセスする
1~3 は通常のクロスアカウント設定で難しい点はないが、 4 でのアクセス方法が意外とややこしい
Redshift から他アカウントの S3 にアクセスする
IAM の設定
Account B
Account A へ権限を委譲するための accountB-S3-Assume-Role という名称の IAM ロールを一つ作成する。
これには下記2つのポリシーが含まれている
- s3 バケット s3://bucket.accountB 配下へのアクセス許可
- Account A の IAM Role への信頼
s3 へのアクセス許可ポリシー
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Sid",
"Action": [
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::bucket.accountB"
},
{
"Sid": "Sid",
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::bucket.accountB/*"
}
]
}
AccountA の IAM Role に対する信頼ポリシー
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Sid",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111111111111:role/AccountA-Redshift-Role"
},
"Action": "sts:AssumeRole"
}
]
}
Account A
account B で作成したロールを引き受けるポリシーを Redshift に割り当てる IAM ロールに追加する
AccountA の権限を引き受けるポリシー
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Sid",
"Action": [
"sts:AssumeRole"
],
"Effect": "Allow",
"Resource": "arn:aws:iam::222222222222:role/accountB-S3-Assume-Role"
}
]
}
Redshift の S3 アクセス処理
まず、Redshift の IAM ロールに AccountA-Redshift-Role を付与する。
下記2点の方法で Redshift から S3 へのクロスアカウントのアクセス処理を行う。
- Redshift による copy コマンドを使った S3 上ファイルのロード
- Redshift Spectrum を使った S3 に対する外部スキーマ作成
Redshift Copy
AssumeRole を利用したクロスアカウントの copy コマンドは下記のようになる。
iam_role
以下に copy 時に必要な IAM ロールの ARN を設定する。
この際にクロスアカウントの場合、カンマ区切りで権限引き受け元の IAM Role を指定する必要がある。
これをロールの連鎖(ロールチェーン)と呼ぶらしい。
copy 's3://bucket.accountB/'
iam_role 'arn:aws:iam::111111111111:role/AccountA-Redshift-Role,arn:aws:iam::222222222222:role/accountB-S3-Assume-Role'
;
Redshift Spectrum
Redshift Spectrum を使ったクロスアカウントの場合も同様に、ロールの連鎖で iam_role を使って外部スキーマを設定する必要がある。
create external schema test from data catalog
database 'test' region 'ap-northeast-1'
iam_role 'arn:aws:iam::111111111111:role/AccountA-Redshift-Role,arn:aws:iam::222222222222:role/accountB-S3-Assume-Role'
;
おわりに
AssumeRole で権限委譲元アカウントの IAM ロールの ARN を指定する必要があるとは思わず、手間取ってしまった。
なぜこの指定が必要なのかをまだ理解できていないのが残念だが、これで AssumeRole を利用した Redshift のクロスアカウントアクセスが可能になる。