Aller au contenu principal

Accédez aux compartiments S3 inter-comptes avec une stratégie AssumeRole

Dans AWS, vous pouvez configurer l'accès inter-comptes, afin que le calcul dans un compte puisse accéder à un compartiment dans un autre compte. Une façon d'accorder l'accès, décrite dans Tutoriel : Configurer l'accès S3 avec un profil d'instance, consiste à accorder à un compte un accès direct à un compartiment dans un autre compte. Une autre façon d'accorder l'accès à un compartiment est de permettre à un compte d' assumer un rôle dans un autre compte.

Considérez le compte AWS A avec l'ID de compte <deployment-acct-id> et le compte AWS B avec l'ID de compte <bucket-owner-acct-id>. Le compte A est utilisé lors de l'inscription à Databricks: les services EC2 et le compartiment racine du système de fichiers Databricks sont gérés par ce compte. Le compte B dispose d'un compartiment <s3-bucket-name>.

Cet article décrit les étapes pour configurer le compte A afin d’utiliser l’action AWS AssumeRole pour accéder aux fichiers S3 dans <s3-bucket-name> en tant que rôle dans le compte B. Pour activer cet accès, vous devez effectuer une configuration dans le compte A et le compte B, ainsi que dans les paramètres d’administration de Databricks. Vous devez également configurer un cluster Databricks ou ajouter une configuration à un notebook qui accède au compartiment.

Exigences

  • Accès administrateur AWS aux rôles et politiques IAM dans le compte AWS du déploiement Databricks et le compte AWS du compartiment S3.
  • Compartiment S3 cible.
  • Si vous avez l'intention d'activer le chiffrement pour le bucket S3, vous devez ajouter le profil d'instance en tant qu'utilisateur clé pour la clé KMS fournie dans la configuration. Consultez Configurer le chiffrement pour S3 avec KMS.

Étape 1 : Dans le compte A, créez le rôle MyRoleA et attachez les stratégies.

  1. Créez un rôle nommé MyRoleA dans le compte A. L'ARN du profil d'instance est arn:aws:iam::<deployment-acct-id>:instance-profile/MyRoleA.

  2. Créez une politique qui indique qu’un rôle dans le compte A peut assumer MyRoleB dans le compte B. Associez-la à MyRoleA. Cliquez sur Politique en ligne et collez la politique :

    JSON
    {
    "Version": "2012-10-17",
    "Statement": [
    {
    "Sid": "Stmt1487884001000",
    "Effect": "Allow",
    "Action": ["sts:AssumeRole"],
    "Resource": ["arn:aws:iam::<bucket-owner-acct-id>:role/MyRoleB"]
    }
    ]
    }
  3. Mettre à jour la politique du rôle Compte A utilisé pour créer des clusters, en ajoutant l'action iam:PassRole à 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"]
    }
    ]
    }
remarque

Si votre compte est sur la version E2 de la plateforme Databricks, vous pouvez omettre ec2:CreateKeyPair et ec2:DeleteKeyPair.

Étape 2 : dans le compte B, créez le rôle MyRoleB et attachez les politiques

  1. Créer un rôle nommé « MyRoleB ». L'ARN de rôle est arn:aws:iam::<bucket-owner-acct-id>:role/MyRoleB.

  2. Modifiez la relation de confiance du rôle MyRoleB pour permettre à un rôle MyRoleA dans le compte A d'assumer un rôle dans le compte B. Sélectionnez IAM > Rôles > MyRoleB > Relations de confiance > Modifier la relation de confiance et saisissez :

    JSON
    {
    "Version": "2012-10-17",
    "Statement": [
    {
    "Effect": "Allow",
    "Principal": {
    "AWS": ["arn:aws:iam::<deployment-acct-id>:role/MyRoleA"]
    },
    "Action": "sts:AssumeRole"
    }
    ]
    }
  3. Créez une stratégie de compartiment pour le compartiment <s3-bucket-name>. Sélectionnez S3 > <s3-bucket-name> > Autorisations > Stratégie de compartiment . Incluez le rôle (Principal) MyRoleB dans la stratégie de compartiment :

    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>/*"
    }
    ]
    }
astuce

Si vous êtes invité avec un Principal error, assurez-vous que vous avez modifié uniquement la politique de relation de confiance .

Étape 3 : Ajouter MyRoleA au Workspace Databricks

Dans les paramètresd'administration Databricks, ajoutez le profil d'instance MyRoleA à Databricks en utilisant l'ARN du MyRoleA profil d'instance arn:aws:iam::<deployment-acct-id>:instance-profile/MyRoleA de l'étape 1.

Étape 4 : Configurer le cluster avec MyRoleA

  1. Sélectionnez ou créez un cluster.

  2. Ouvrez la section Avancée .

  3. Sur le **tab** Instances, sélectionnez le profil MyRoleA d'instance.

  4. Sous l’**Spark** tab, définissez le fournisseur d’informations d’identification de rôle à endosser et l’ARN de rôle MyRoleB:

remarque

Databricks Runtime 7.3 LTS et les versions ultérieures prennent en charge la configuration du système de fichiers S3A en utilisant les options Hadoop open source. Vous pouvez configurer les propriétés globales et les propriétés par compartiment.

Pour le définir globalement pour tous les compartiments :

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

Pour le définir pour un compartiment spécifique :

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. Start le cluster.

  2. Associez un Notebook au cluster.

  3. Vérifiez que vous pouvez accéder à <s3-bucket-name> en exécutant la commande suivante :

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

Étape 5 : monter le compartiment inter-comptes avec AssumeRole

Vous pouvez monter votre compartiment inter-comptes pour utiliser des chemins de fichiers relatifs afin d'accéder aux données distantes. Consultez Monter un compartiment à l'aide de profils d'instance avec la politique AssumeRole.

Configuration automatisée à l'aide de Terraform

Vous pouvez utiliser le fournisseur Databricks Terraform pour configurer automatiquement les rôles AWS IAM et leur attachement de cluster.

Comme le montre cet exemple de configuration, définissez d'abord deux variables :

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"
}

Créez un compartiment en utilisant 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"
})
}

Créez un rôle IAM pour l'accès aux données en utilisant aws_iam_role:

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
}

Créez une politique de compartiment avec une définition databricks_aws_bucket_policy qui donne un accès complet à ce compartiment. Appliquez une politique de compartiment S3 intégrée au compartiment nouvellement créé avec 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
}

Créer une stratégie inter-comptes, qui permet à Databricks de transmettre une liste de rôles de données à l'aide d'une stratégie aws_iam:

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
}

Autorisez Databricks à effectuer des actions au sein de votre compte en configurant une relation de confiance à l'aide d'un aws_iam_role_policy_attachment. Accordez à Databricks un accès complet aux ressources Virtual Private Cloud (VPC) et attachez une politique inter-comptes au rôle inter-comptes :

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
}

Enregistrer le rôle inter-comptes dans la configuration du Workspace E2:

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
}

Une fois le workspace créé, enregistrez votre rôle de données avec aws_iam_instance_profile en tant que 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
}

Pour la dernière étape, créez un point de montage /mnt/experiments et un cluster avec un profil d'instance spécifié :

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
}
}