2023/1/19追記 より詳細な記事を書きました。
DatabricksがデプロイされているAWSアカウントと、データが格納されているS3のAWSアカウントが異なるケースというのはあり得る話です。
クロスアカウントバケットポリシーでアクセスを許可することも可能ですが、最近AWS GuardDutyのアラートポリシーが追加され、アラートを回避するにはAssumeRoleを用いたマウントポイントの作成をお勧めしています。
AWS GuardDutyのアラート及び対応策に関して
AssumeRoleポリシーを用いたクロスアカウントアクセスに関して
本書では、実際にAssumeRoleを用いてどのようにクロスアカウントのマウントポイントを作成するのかを説明します。
全体像
- AWSアカウントA: Databricks環境をデプロイしているAWSアカウント
- AWSアカウントB: S3が存在しているAWSアカウント
- IAMロール(1): AWSアカウントAで作成するIAMロール。Databricksにアタッチするインスタンスプロファイルとなります。
- IAMロール(2): AWSアカウントBで作成するIAMロール。S3にアクセスする権限を付与します。
Databricks環境のAWSアカウントAWSアカウントA
での設定:S3にアクセスするロールIAMロール(1)
の作成
- IAMに移動し、ロールを作成します。
- 信頼されたエンティティの種類を選択ではAWSサービス、ユースケースの選択ではEC2を選択します。
- ポリシーは後で追加するので、一旦ロール名をつけて**IAMロール(1)**を作成します。
S3のAWSアカウントAWSアカウントB
での設定:S3にアクセスするロールIAMロール(2)
の作成
データを格納しているS3のAWSアカウントでAWSコンソールにログインします。
-
IAMに移動し、ロールを作成します。
-
信頼されたエンティティの種類を選択ではAWSサービス、ユースケースの選択ではEC2を選択します。
-
ポリシーの作成でJSONを開き、以下を貼り付けます。
JSON
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject",
"s3:PutObjectAcl"
],
"Resource": [
"arn:aws:s3:::",
"arn:aws:s3:::/*"
]
}
]
}
```
-
**IAMロール(2)**を作成します。
-
IAMロール(2)の信頼関係を開き、**IAMロール(1)**への信頼関係を設定します。
JSON
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam:::role/"
},
"Action": "sts:AssumeRole",
"Condition": {}
}
]
}
```
以下のようになっていることを確認します。
Databricks環境のAWSアカウントAWSアカウントA
での設定:S3にアクセスするロールIAMロール(1)
の設定
IAMロール(1)のアクセス権を開き、以下のポリシーを追加します。これで、**IAMロール(1)がIAMロール(2)**のロールを担うことができるようになります。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1487884001000",
"Effect": "Allow",
"Action": [
"sts:AssumeRole"
],
"Resource": [
"arn:aws:iam::<AWSアカウントB>:role/<IAMロール(2)>"
]
}
]
}
**IAMロール(1)**のインスタンスプロファイルARNをコピーしておきます。
IAMロール(1)
を用いてインスタンスプロファイルを作成する
- DatabricksのAdmin Consoleにアクセスします。
- Instance Profileタブを開きます。
- Add Instance Profileをクリックします。ダイアログが表示されます。
- 上でコピーしたインスタンスプロファイルARNを貼り付けます。
- Addをクリックします。
マウントポイントを作成する
上で作成したインスタンスプロファイルをアタッチしてクラスターを作成・起動します。
以下のコマンドを実行してマウントポイントを作成します。
dbutils.fs.mount("s3a://<S3バケット名>", "/mnt/<マウントポイント名>",
extraConfigs = Map(
"fs.s3a.credentialsType" -> "AssumeRole",
"fs.s3a.stsAssumeRole.arn" -> "arn:aws:iam::<AWSアカウントB>:role/<IAMロール(2)>",
"fs.s3a.acl.default" -> "BucketOwnerFullControl"
)
)
アクセスできることを確認します。
dbutils.fs.ls("/mnt/<マウントポイント>")