メインコンテンツまでスキップ

AssumeRole ポリシーを使用したクロスアカウント S3 バケットへのアクセス

AWS では、クロスアカウントアクセスを設定できるため、あるアカウントのコンピューティングが別のアカウントのバケットにアクセスできます。 「 チュートリアル: インスタンスプロファイルで S3 アクセスを設定する」で説明されているように、アクセスを許可する方法の 1 つは、別のアカウントのバケットへの直接アクセスをアカウントに付与することです。 バケットへのアクセス権を付与する別の方法は、アカウントが別のアカウントの ロールを引き受け ることを許可することです。

AWS アカウント A をアカウント ID <deployment-acct-id> とAWS アカウント B をアカウント ID <bucket-owner-acct-id> とします。アカウント A は サインアップ時に Databricks: EC2 サービスおよびDatabricks Filesystemルートバケットは、このアカウントによって管理されます。アカウント B にはバケット <s3-bucket-name>があります。

この記事では、 AWS AssumeRole アクションを使用して、アカウント B のロールとして <s3-bucket-name> の S3 ファイルにアクセスするようにアカウント A を設定する手順について説明します。このアクセスを有効にするには、アカウント A とアカウント B、および Databricks 管理者設定で構成を実行します。 また、 Databricks クラスターを設定するか、バケットにアクセスするノートブックに設定を追加する必要があります。

必要条件

  • AWSIAMデプロイのAWS アカウントと バケットのDatabricks AWSアカウントにある ロールとポリシーへの管理者アクセス。S3
  • ターゲット S3 バケット。
  • S3 バケットの 暗号化 を有効にする場合は、設定で指定された KMS キー のキーユーザー としてインスタンスプロファイルを追加する必要があります。 「 KMS を使用した S3 の暗号化の設定」を参照してください。

ステップ 1: アカウント A で、ロール MyRoleA を作成し、ポリシーをアタッチします

  1. アカウント A に MyRoleA という名前のロールを作成します。インスタンスプロファイル ARN は arn:aws:iam::<deployment-acct-id>:instance-profile/MyRoleAです。

  2. アカウント A のロールがアカウント B の MyRoleB ロールを引き受けることができるというポリシーを作成し、 MyRoleAにアタッチします。 [ インラインポリシー ] をクリックし、ポリシーを貼り付けます。

    JSON
    {
    "Version": "2012-10-17",
    "Statement": [
    {
    "Sid": "Stmt1487884001000",
    "Effect": "Allow",
    "Action": ["sts:AssumeRole"],
    "Resource": ["arn:aws:iam::<bucket-owner-acct-id>:role/MyRoleB"]
    }
    ]
    }
  3. アカウント A role used to create clustering, adding the iam:PassRole action to MyRoleA:

    JSON
    {
    "Version": "2012-10-17",
    "Statement": [
    {
    "Sid": "Stmt1403287045000",
    "Effect": "Allow",
    "Action": [
    "ec2:AssociateDhcpOptions",
    "ec2:AssociateIamInstanceProfile",
    "ec2:AssociateRouteTable",
    "ec2:AttachInternetGateway",
    "ec2:AttachVolume",
    "ec2:AuthorizeSecurityGroupEgress",
    "ec2:AuthorizeSecurityGroupIngress",
    "ec2:CancelSpotInstanceRequests",
    "ec2:CreateDhcpOptions",
    "ec2:CreateInternetGateway",
    "ec2:CreateKeyPair",
    "ec2:CreateRoute",
    "ec2:CreateSecurityGroup",
    "ec2:CreateSubnet",
    "ec2:CreateTags",
    "ec2:CreateVolume",
    "ec2:CreateVpc",
    "ec2:CreateVpcPeeringConnection",
    "ec2:DeleteInternetGateway",
    "ec2:DeleteKeyPair",
    "ec2:DeleteRoute",
    "ec2:DeleteRouteTable",
    "ec2:DeleteSecurityGroup",
    "ec2:DeleteSubnet",
    "ec2:DeleteTags",
    "ec2:DeleteVolume",
    "ec2:DeleteVpc",
    "ec2:DescribeAvailabilityZones",
    "ec2:DescribeIamInstanceProfileAssociations",
    "ec2:DescribeInstanceStatus",
    "ec2:DescribeInstances",
    "ec2:DescribePrefixLists",
    "ec2:DescribeReservedInstancesOfferings",
    "ec2:DescribeRouteTables",
    "ec2:DescribeSecurityGroups",
    "ec2:DescribeSpotInstanceRequests",
    "ec2:DescribeSpotPriceHistory",
    "ec2:DescribeSubnets",
    "ec2:DescribeVolumes",
    "ec2:DescribeVpcs",
    "ec2:DetachInternetGateway",
    "ec2:DisassociateIamInstanceProfile",
    "ec2:ModifyVpcAttribute",
    "ec2:ReplaceIamInstanceProfileAssociation",
    "ec2:RequestSpotInstances",
    "ec2:RevokeSecurityGroupEgress",
    "ec2:RevokeSecurityGroupIngress",
    "ec2:RunInstances",
    "ec2:TerminateInstances"
    ],
    "Resource": ["*"]
    },
    {
    "Effect": "Allow",
    "Action": "iam:PassRole",
    "Resource": ["arn:aws:iam::<deployment-acct-id>:role/MyRoleA"]
    }
    ]
    }
注記

アカウントが Databricks プラットフォームの E2 バージョンを使用している場合は、 ec2:CreateKeyPairec2:DeleteKeyPairを省略できます。

ステップ 2: アカウント B で、ロール MyRoleB を作成し、ポリシーをアタッチします

  1. MyRoleBという名前のロールを作成します。ロール ARN は arn:aws:iam::<bucket-owner-acct-id>:role/MyRoleBです。

  2. ロール MyRoleB の信頼関係を編集して、アカウント A のロール MyRoleAがアカウント B のロールを引き受けることを許可します。 IAMロール >を MyRoleB > [信頼関係を編集] > [信頼関係を編集 ] を選択し、次のように入力します。

    JSON
    {
    "Version": "2012-10-17",
    "Statement": [
    {
    "Effect": "Allow",
    "Principal": {
    "AWS": ["arn:aws:iam::<deployment-acct-id>:role/MyRoleA"]
    },
    "Action": "sts:AssumeRole"
    }
    ]
    }
  3. バケット <s3-bucket-name>のバケットポリシーを作成します。 [ S3 > <s3-bucket-name> > Permissions > Bucket ポリシー ] を選択します。 ロール (プリンシパル) MyRoleB バケットポリシーに含めます。

    JSON
    {
    "Version": "2012-10-17",
    "Statement": [
    {
    "Effect": "Allow",
    "Principal": {
    "AWS": ["arn:aws:iam::<bucket-owner-acct-id>:role/MyRoleB"]
    },
    "Action": ["s3:GetBucketLocation", "s3:ListBucket"],
    "Resource": "arn:aws:s3:::<s3-bucket-name>"
    },
    {
    "Effect": "Allow",
    "Principal": {
    "AWS": ["arn:aws:iam::<bucket-owner-acct-id>:role/MyRoleB"]
    },
    "Action": ["s3:PutObject", "s3:PutObjectAcl", "s3:GetObject", "s3:DeleteObject"],
    "Resource": "arn:aws:s3:::<s3-bucket-name>/*"
    }
    ]
    }
ヒント

Principal errorを求められた場合は、 信頼関係 ポリシーのみを変更したことを確認してください。

手順 3: Databricks ワークスペースに MyRoleA を追加する

Databricks管理設定で、インスタンスプロファイルMyRoleAをDatabricksに追加します。 MyRoleA インスタンスプロファイル ARN arn:aws:iam::<deployment-acct-id>:instance-profile/MyRoleAステップ 1 から実行します。

ステップ 4: クラスターを構成する MyRoleA

  1. クラスターを選択または作成します。

  2. [詳細設定 ] セクションを開きます。

  3. 「インスタンス」 タブで、インスタンスプロファイルMyRoleAを選択します。

  4. [ Spark ] タブで、ロールの認証情報プロバイダを引き受ける と [ロール ARN] MyRoleBを設定します。

注記

Databricks Runtime 7.3 LTS 以降では、 オープンソースの Hadoop オプションを使用した S3A ファイルシステムの構成がサポートされています。 グローバルプロパティとバケットごとのプロパティを設定できます。

すべてのバケットに対してグローバルに設定するには:

Bash
fs.s3a.aws.credentials.provider org.apache.hadoop.fs.s3a.auth.AssumedRoleCredentialProvider
fs.s3a.assumed.role.arn arn:aws:iam::<bucket-owner-account-id>:role/MyRoleB

特定のバケットに設定するには:

Bash
fs.s3a.bucket.<s3-bucket-name>.aws.credentials.provider org.apache.hadoop.fs.s3a.auth.AssumedRoleCredentialProvider
fs.s3a.bucket.<s3-bucket-name>.assumed.role.arn arn:aws:iam::<bucket-owner-account-id>:role/MyRoleB
  1. クラスターを開始します。

  2. ノートブックをクラスターにアタッチします。

  3. 次のコマンドを実行して、 <s3-bucket-name> にアクセスできることを確認します。

    Python
    dbutils.fs.ls("s3a://<s3-bucket-name>/")

ステップ 5: AssumeRole を使用してクロスアカウントバケットをマウントする

クロスアカウントバケットをマウントして、リモートデータへのアクセスに相対ファイルパスを使用することができます。 「AssumeRoleポリシーでのインスタンスプロファイルを使用したバケットのマウント」を参照してください。

Terraform を使用した自動構成

Databricks Terraform プロバイダーを使用して、AWS IAMロールとそのクラスター アタッチメントを自動的に構成できます。

この構成例に示すように、最初に 2 つの変数を定義します。

variable "prefix" {
default = "changeme"
}

variable "databricks_account_id" {
description = "Account ID. You can get your account ID in the bottom left corner of the account console. See https://accounts.cloud.databricks.com"
}

aws_s3_bucketを使用してバケットを作成します。

resource "aws_s3_bucket" "ds" {
bucket = "${var.prefix}-ds"
acl = "private"
versioning {
enabled = false
}
force_destroy = true
tags = merge(var.tags, {
Name = "${var.prefix}-ds"
})
}

aws_iam_roleを使用して、データアクセス用のIAMロールを作成します。

data "aws_iam_policy_document" "assume_role_for_ec2" {
statement {
effect = "Allow"
actions = ["sts:AssumeRole"]
principals {
identifiers = ["ec2.amazonaws.com"]
type = "Service"
}
}
}

resource "aws_iam_role" "data_role" {
name = "${var.prefix}-first-ec2s3"
description = "(${var.prefix}) EC2 Assume Role role for S3 access"
assume_role_policy = data.aws_iam_policy_document.assume_role_for_ec2.json
tags = var.tags
}

このバケットへのフルアクセスを付与する databricks_aws_bucket_policy 定義を使用してバケットポリシーを作成します。 インライン S3 バケットポリシーを、新しく作成したバケットに 次のaws_s3_bucket_policyで適用します。

data "databricks_aws_bucket_policy" "ds" {
provider = databricks.mws
full_access_role = aws_iam_role.data_role.arn
bucket = aws_s3_bucket.ds.bucket
}

resource "aws_s3_bucket_policy" "ds" {
bucket = aws_s3_bucket.ds.id
policy = data.databricks_aws_bucket_policy.ds.json
}

cross-アカウント ポリシーを作成すると、Databricksポリシーを使用してデータの役割のリストを渡すことができます。

data "databricks_aws_crossaccount_policy" "this" {
pass_roles = [aws_iam_role.data_role.arn]
}

resource "aws_iam_policy" "cross_account_policy" {
name = "${var.prefix}-crossaccount-iam-policy"
policy = data.databricks_aws_crossaccount_policy.this.json
}

Databricks がアカウント内でアクションを実行できるようにするには、 aws_iam_role_policy_attachmentを使用して信頼関係を設定します。 Databricks に VPC リソースへのフルアクセスを付与し、クロスアカウント ポリシーをクロスアカウント ロールにアタッチします。

data "databricks_aws_assume_role_policy" "this" {
external_id = var.databricks_account_id
}

resource "aws_iam_role" "cross_account" {
name = "${var.prefix}-crossaccount-iam-role"
assume_role_policy = data.databricks_aws_assume_role_policy.this.json
description = "Grants Databricks full access to VPC resources"
}

resource "aws_iam_role_policy_attachment" "cross_account" {
policy_arn = aws_iam_policy.cross_account_policy.arn
role = aws_iam_role.cross_account.name
}

E2 ワークスペースのセットアップで登録する cross-アカウント ロール:

resource "databricks_mws_credentials" "this" {
provider = databricks.mws
account_id = var.databricks_account_id
credentials_name = "${var.prefix}-creds"
role_arn = aws_iam_role.cross_account.arn
}

ワークスペースが作成されたら、aws_iam_instance_profileを次のように登録するデータロールdatabricks_instance_profile

resource "aws_iam_instance_profile" "this" {
name = "${var.prefix}-first-profile"
role = aws_iam_role.data_role.name
}

resource "databricks_instance_profile" "ds" {
instance_profile_arn = aws_iam_instance_profile.this.arn
}

最後の手順では、指定したインスタンスプロファイルを使用して /mnt/experiments マウントポイントとクラスターを作成します。

resource "databricks_aws_s3_mount" "this" {
instance_profile = databricks_instance_profile.ds.id
s3_bucket_name = aws_s3_bucket.this.bucket
mount_name = "experiments"
}

data "databricks_node_type" "smallest" {
local_disk = true
}

data "databricks_spark_version" "latest_lts" {
long_term_support = true
}

resource "databricks_cluster" "shared_autoscaling" {
cluster_name = "Shared Autoscaling"
spark_version = data.databricks_spark_version.latest_lts.id
node_type_id = data.databricks_node_type.smallest.id
autotermination_minutes = 20

autoscale {
min_workers = 1
max_workers = 50
}

aws_attributes {
instance_profile_arn = databricks_instance_profile.ds.id
}
}