DatabricksでAssumeRoleポリシーを用いてクロスアカウントS3バケットをマウントする

:::note
**2023/1/19追記** より詳細な記事を書きました。
:::

https://qiita.com/taka_yayoi/items/e7e86c02c8dcb567c717


DatabricksがデプロイされているAWSアカウントと、データが格納されているS3のAWSアカウントが異なるケースというのはあり得る話です。

クロスアカウントバケットポリシーでアクセスを許可することも可能ですが、最近AWS GuardDutyのアラートポリシーが追加され、アラートを回避するにはAssumeRoleを用いたマウントポイントの作成をお勧めしています。

**AWS GuardDutyのアラート及び対応策に関して**

https://qiita.com/taka_yayoi/items/93cbd29a3b8cb6886757

**AssumeRoleポリシーを用いたクロスアカウントアクセスに関して**

https://qiita.com/taka_yayoi/items/c971c7c5411df054b621

本書では、実際にAssumeRoleを用いてどのようにクロスアカウントのマウントポイントを作成するのかを説明します。

# 全体像

![Screen Shot 2022-02-03 at 13.10.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/d11907a8-1935-2a92-3b3f-ef3ede2d99cb.png)

- **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)`の作成

1. IAMに移動し、ロールを作成します。
1. **信頼されたエンティティの種類を選択**では**AWSサービス**、**ユースケースの選択**では**EC2**を選択します。
1. ポリシーは後で追加するので、一旦ロール名をつけて**IAMロール(1)**を作成します。

# S3のAWSアカウント`AWSアカウントB`での設定：S3にアクセスするロール`IAMロール(2)`の作成

データを格納しているS3のAWSアカウントでAWSコンソールにログインします。

1. IAMに移動し、ロールを作成します。
1. **信頼されたエンティティの種類を選択**では**AWSサービス**、**ユースケースの選択**では**EC2**を選択します。
1. **ポリシーの作成**でJSONを開き、以下を貼り付けます。

    ```json:JSON
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:PutObject",
                "s3:GetObject",
                "s3:DeleteObject",
                "s3:PutObjectAcl"
            ],
            "Resource": [
                "arn:aws:s3:::<S3バケット名>",
                "arn:aws:s3:::<S3バケット名>/*"
            ]
        }
    ]
}
    ```

1. **IAMロール(2)**を作成します。
1. **IAMロール(2)**の**信頼関係**を開き、**IAMロール(1)**への信頼関係を設定します。

    ```json:JSON
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::<AWSアカウントA>:role/<IAMロール(1)>"
      },
      "Action": "sts:AssumeRole",
      "Condition": {}
    }
  ]
}
    ```

以下のようになっていることを確認します。

![Screen Shot 2022-02-03 at 13.35.33.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/336fd1bc-6c6d-b653-f355-28786b416a18.jpeg)

# Databricks環境のAWSアカウント`AWSアカウントA`での設定：S3にアクセスするロール`IAMロール(1)`の設定

**IAMロール(1)**の**アクセス権**を開き、以下のポリシーを追加します。これで、**IAMロール(1)**が**IAMロール(2)**のロールを担うことができるようになります。

```json:JSON
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1487884001000",
            "Effect": "Allow",
            "Action": [
                "sts:AssumeRole"
            ],
            "Resource": [
                "arn:aws:iam::<AWSアカウントB>:role/<IAMロール(2)>"
            ]
        }
    ]
}
```

**IAMロール(1)**のインスタンスプロファイルARNをコピーしておきます。
![Screen Shot 2022-02-03 at 13.26.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/1c49a3e5-c86a-fc80-b30d-6da0a6f6a100.png)


# `IAMロール(1)`を用いてインスタンスプロファイルを作成する

1. Databricksの**Admin Console**にアクセスします。
1. **Instance Profile**タブを開きます。
1. **Add Instance Profile**をクリックします。ダイアログが表示されます。
1. 上でコピーしたインスタンスプロファイルARNを貼り付けます。
![](https://docs.databricks.com/_images/add-instanceprofile-arn.png)
1. **Add**をクリックします。

# マウントポイントを作成する

上で作成したインスタンスプロファイルをアタッチしてクラスターを作成・起動します。
![Screen Shot 2022-02-03 at 13.30.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/51d9e5f3-42d9-75ce-f096-5350c31b3c41.png)

以下のコマンドを実行してマウントポイントを作成します。

```py:Python
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"
)
)
```

アクセスできることを確認します。

```py:Python
dbutils.fs.ls("/mnt/<マウントポイント>")
```

![Screen Shot 2022-02-03 at 13.33.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/4a40c84f-ecd3-3faa-678d-9f4df62eb52d.png)

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)