

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# Bloc-notes Jupyter sur Amazon EMR
<a name="emr-jupyter"></a>

Le [bloc-notes Jupyter](https://jupyter.org/) est une application Web open source que vous pouvez utiliser pour créer et partager des documents qui contiennent du code interactif, des équations, des visualisations, et des textes narratifs. Amazon EMR vous offre trois options pour travailler avec les blocs-notes Jupyter :

**Topics**
+ [EMR Studio](emr-studio-jupyter.md)
+ [Bloc-notes EMR](emr-jupyter-emr-managed-notebooks.md)
+ [JupyterHub](emr-jupyterhub.md)

# EMR Studio
<a name="emr-studio-jupyter"></a>

Amazon EMR Studio est un environnement de développement intégré (IDE) basé sur le Web pour les [blocs-notes Jupyter](https://jupyter.org/) entièrement gérés qui s'exécutent sur des clusters Amazon EMR. Vous pouvez configurer un studio EMR pour que votre équipe développe, visualise et débogue des applications écrites en R, Python, Scala et. PySpark 

Nous vous recommandons d'utiliser EMR Studio lorsque vous utilisez des blocs-notes Jupyter sur Amazon EMR. Pour plus d'informations, consultez [EMR Studio](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-studio.html) dans le *Guide de gestion d'Amazon EMR*.

# Bloc-notes Amazon EMR basé sur Jupyter Notebook
<a name="emr-jupyter-emr-managed-notebooks"></a>

Blocs-notes EMR est un environnement [Bloc-notes Jupyter](https://jupyter.org/) intégré à la console Amazon EMR qui vous permet de créer rapidement des blocs-notes Jupyter, de les associer à des clusters Spark, puis d'ouvrir l'éditeur Jupyter Notebook dans la console pour exécuter des requêtes et du code à distance. Un bloc-notes EMR est enregistré dans Amazon S3 indépendamment des clusters pour un stockage durable, un accès rapide et une flexibilité accrue. Vous pouvez ouvrir plusieurs blocs-notes, associer plusieurs blocs-notes à un seul cluster et réutiliser un bloc-notes sur différents clusters.

Pour plus d'informations, consultez [Blocs-notes EMR](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-managed-notebooks.html) dans le *Guide de gestion d'Amazon EMR*.

# JupyterHub
<a name="emr-jupyterhub"></a>

[Jupyter Notebook](https://jupyter.org/) est une application Web open source que vous pouvez utiliser pour créer et partager des documents contenant du code en direct, des équations, des visualisations et du texte narratif. [JupyterHub](https://jupyterhub.readthedocs.io/en/latest/)vous permet d'héberger plusieurs instances d'un serveur de bloc-notes Jupyter mono-utilisateur. Lorsque vous créez un cluster avec JupyterHub, Amazon EMR crée un conteneur Docker sur le nœud principal du cluster. JupyterHub, tous les composants requis pour Jupyter et [Sparkmagic](https://github.com/jupyter-incubator/sparkmagic/blob/master/README.md) fonctionnent dans le conteneur.

Sparkmagic est une bibliothèque de noyaux qui permet aux blocs-notes Jupyter d'interagir avec [Apache Spark](https://aws.amazon.com/big-data/what-is-spark/) exécuté sur Amazon EMR via [Apache Livy](emr-livy.md), un serveur REST pour Spark. Spark et Apache Livy sont installés automatiquement lorsque vous créez un cluster avec JupyterHub. Le noyau Python 3 par défaut pour Jupyter est disponible, ainsi que les noyaux PySpark 3 PySpark, et Spark disponibles avec Sparkmagic. Vous pouvez utiliser ces noyaux pour exécuter le code Spark et les requêtes SQL interactives ad hoc à l'aide de Python et Scala. Vous pouvez installer manuellement des noyaux supplémentaires dans le conteneur Docker. Pour de plus amples informations, veuillez consulter [Installation de noyaux et de bibliothèques supplémentaires](emr-jupyterhub-install-kernels-libs.md).

Le schéma suivant décrit les composants d' JupyterHub Amazon EMR avec les méthodes d'authentification correspondantes pour les utilisateurs d'ordinateurs portables et l'administrateur. Pour de plus amples informations, veuillez consulter [Ajout d'utilisateurs et d'administrateurs de bloc-notes Jupyter](emr-jupyterhub-user-access.md).

![\[JupyterHub architecture on EMR showing user authentication and component interactions.\]](http://docs.aws.amazon.com/fr_fr/emr/latest/ReleaseGuide/images/jupyter-arch.png)


Le tableau suivant répertorie la version JupyterHub incluse dans la dernière version de la série Amazon EMR 7.x, ainsi que les composants avec lesquels Amazon EMR est installé. JupyterHub

Pour connaître la version des composants installés JupyterHub dans cette version, consultez la [version 7.12.0 Versions des composants](emr-7120-release.md).


**JupyterHub informations de version pour emr-7.12.0**  

| Étiquette de version Amazon EMR | JupyterHub Version | Composants installés avec JupyterHub | 
| --- | --- | --- | 
| emr-7,12.0 | JupyterHub 1.5.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-hdfs-zkfc, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 

Le tableau suivant répertorie la version JupyterHub incluse dans la dernière version de la série Amazon EMR 6.x, ainsi que les composants avec lesquels Amazon EMR est installé. JupyterHub

Pour connaître la version des composants installés JupyterHub dans cette version, consultez la [version 6.15.0 Versions des composants](emr-6150-release.md).


**JupyterHub informations de version pour emr-6.15.0**  

| Étiquette de version Amazon EMR | JupyterHub Version | Composants installés avec JupyterHub | 
| --- | --- | --- | 
| emr-6.15.0 | JupyterHub 1.5.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 

Le tableau suivant répertorie la version JupyterHub incluse dans la dernière version de la série Amazon EMR 5.x, ainsi que les composants avec lesquels Amazon EMR est installé. JupyterHub

Pour la version des composants installés JupyterHub dans cette version, voir la [version 5.36.2 Versions des composants](emr-5362-release.md).


**JupyterHub informations de version pour emr-5.36.2**  

| Étiquette de version Amazon EMR | JupyterHub Version | Composants installés avec JupyterHub | 
| --- | --- | --- | 
| emr-5.36.2 | JupyterHub 1.4.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 

Le noyau Python 3 inclus dans JupyterHub Amazon EMR est 3.6.4.

Les bibliothèques installées dans le conteneur `jupyterhub` peuvent varier selon les versions Amazon EMR et les versions d'AMI Amazon EC2.

**Pour lister les bibliothèques installées à l'aide de `conda`**
+ Exécutez la commande suivante sur la ligne de commande du nœud principal :

  ```
  sudo docker exec jupyterhub bash -c "conda list"
  ```

**Pour lister les bibliothèques installées à l'aide de `pip`**
+ Exécutez la commande suivante sur la ligne de commande du nœud principal :

  ```
  sudo docker exec jupyterhub bash -c "pip freeze"
  ```

**Topics**
+ [Créez un cluster avec JupyterHub](emr-jupyterhub-launch.md)
+ [Considérations relatives à l'utilisation JupyterHub sur Amazon EMR](emr-jupyterhub-considerations.md)
+ [Configuration JupyterHub](emr-jupyterhub-configure.md)
+ [Configuration de la persistance pour les blocs-notes dans Amazon S3](emr-jupyterhub-s3.md)
+ [Connexion au nœud principal et aux serveurs de bloc-notes](emr-jupyterhub-connect.md)
+ [JupyterHub configuration et administration](emr-jupyterhub-administer.md)
+ [Ajout d'utilisateurs et d'administrateurs de bloc-notes Jupyter](emr-jupyterhub-user-access.md)
+ [Installation de noyaux et de bibliothèques supplémentaires](emr-jupyterhub-install-kernels-libs.md)
+ [JupyterHub historique des versions](JupyterHub-release-history.md)

# Créez un cluster avec JupyterHub
<a name="emr-jupyterhub-launch"></a>

Vous pouvez créer un cluster Amazon EMR à JupyterHub l'aide de AWS Management Console AWS Command Line Interface, ou de l'API Amazon EMR. Assurez-vous que le cluster n'est pas créé avec l'option d'arrêt automatique après exécution des étapes (option `--auto-terminate` dans l' AWS CLI). Assurez-vous également que les administrateurs et les utilisateurs du bloc-notes peuvent accéder à la paire de clés utilisée lors de la création du cluster. Pour plus d'informations, consultez [Utilisation d'une paire de clés pour les informations d'identification SSH](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-plan-access-ssh.html) dans le *Guide de gestion d'Amazon EMR*.

## Création d'un cluster à JupyterHub l'aide de la console
<a name="emr-jupyterhub-launch-console"></a>

Utilisez la procédure suivante pour créer un cluster JupyterHub installé à l'aide des **options avancées** de la console Amazon EMR.

**Pour créer un cluster Amazon EMR JupyterHub installé à l'aide de la console Amazon EMR**

1. Accédez à la nouvelle console Amazon EMR et sélectionnez **Changer pour l'ancienne console** depuis le menu latéral. Pour plus d'informations sur ce qu'implique le passage à l'ancienne console, consultez la rubrique [Utilisation de l'ancienne console](https://docs.aws.amazon.com/emr/latest/ManagementGuide/whats-new-in-console.html#console-opt-in).

1. Choisissez **Créer un cluster** et **Go to advanced options (Aller aux options avancées)**.

1. Sous **Software Configuration (Configuration logicielle)** :
   + Pour **Release**, sélectionnez emr-5.36.2, puis choisissez. JupyterHub
   + Si vous utilisez Spark, pour utiliser le catalogue de données AWS Glue comme métastore pour Spark SQL, sélectionnez **Utiliser pour les métadonnées de table Spark**. Pour de plus amples informations, veuillez consulter [Utiliser le catalogue AWS Glue Data Catalog avec Spark sur Amazon EMR](emr-spark-glue.md).
   + Pour **Edit software settings (Modifier les paramètres logiciels)**, choisissez **Enter configuration (Saisir une configuration)** et spécifiez des valeurs, ou choisissez **Load JSON from S3 (Charger JSON à partir de S3)** et spécifiez un fichier de configuration JSON. Pour de plus amples informations, veuillez consulter [Configuration JupyterHub](emr-jupyterhub-configure.md).

1. Sous **Add steps (optional) (Ajouter des étapes (facultatif))**, configurez les étapes à exécuter lorsque le cluster est créé, assurez-vous que **Auto-terminate cluster after the last step is completed (Arrêter automatiquement le cluster après l'exécution de la dernière étape)** n'est pas sélectionné, puis choisissez **Next (Suivant)**.

1. Choisissez les options **Hardware Configuration (Configuration matérielle)** et **Next (Suivant)**. Pour plus d'informations, consultez [Configuration du matériel et de la mise en réseau d'un cluster](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-plan-instances.html) dans le *Guide de gestion d'Amazon EMR*.

1. Choisissez les options pour **General Cluster Settings (Paramètres de cluster généraux)** et **Next (Suivant)**.

1. Choisissez **Security Options (Options de sécurité)** en spécifiant une paire de clés, puis choisissez **Create Cluster (Créer un cluster)**.

## Créez un cluster à JupyterHub l'aide du AWS CLI
<a name="emr-jupyterhub-launch-cli"></a>

Pour lancer un cluster avec JupyterHub, utilisez la `aws emr create-cluster` commande et, pour l'`--applications`option, spécifiez`Name=JupyterHub`. L'exemple suivant lance un JupyterHub cluster sur Amazon EMR avec deux instances EC2 (une instance principale et une instance principale). En outre, le débogage est activé et les journaux sont stockés dans l'emplacement Amazon S3, comme spécifié par `--log-uri`. La paire de clés spécifiée fournit l'accès aux instances Amazon EC2 dans le cluster.

**Note**  
Les caractères de continuation de ligne Linux (\$1) sont inclus pour des raisons de lisibilité. Ils peuvent être supprimés ou utilisés dans les commandes Linux. Pour Windows, supprimez-les ou remplacez-les par un caret (^).

```
aws emr create-cluster --name="MyJupyterHubCluster" --release-label emr-5.36.2 \
--applications Name=JupyterHub --log-uri s3://amzn-s3-demo-bucket/MyJupyterClusterLogs \
--use-default-roles --instance-type m5.xlarge --instance-count 2 --ec2-attributes KeyName=MyKeyPair
```

# Considérations relatives à l'utilisation JupyterHub sur Amazon EMR
<a name="emr-jupyterhub-considerations"></a>

Tenez compte des points suivants lors de l'utilisation JupyterHub sur Amazon EMR.
+ 
**Avertissement**  
Les blocs-notes utilisateur et les fichiers sont enregistrées dans le système de fichiers sur le nœud principal. Il s'agit d'un stockage éphémère qui n'est pas conservé en cas d'arrêt du cluster. Lors de l'arrêt du cluster, ces données sont perdues si elles ne sont pas sauvegardées. Nous vous recommandons de planifier des sauvegardes régulières en utilisant des tâches `cron` ou tout autre méthode adaptée à votre application.  
De plus, les changements de configuration effectués dans le conteneur peuvent ne pas être conservés lors du redémarrage de celui-ci. Nous vous recommandons de créer des scripts ou d'automatiser de quelque manière que ce soit les configurations de conteneur, de sorte que vous puissiez reproduire les personnalisations plus rapidement.
+ L'authentification Kerberos configurée à l'aide d'une configuration de sécurité Amazon EMR n'est pas prise en charge.
+ [OAuthenticator](https://github.com/jupyterhub/oauthenticator) n’est pas pris en charge.

# Configuration JupyterHub
<a name="emr-jupyterhub-configure"></a>

Vous pouvez personnaliser la configuration des JupyterHub blocs-notes d'Amazon EMR et d'utilisateurs individuels en vous connectant au nœud principal du cluster et en modifiant les fichiers de configuration. Après avoir modifié les valeurs, redémarrez le conteneur `jupyterhub`.

Modifiez les propriétés dans les fichiers suivants pour configurer JupyterHub des blocs-notes Jupyter individuels :
+ `jupyterhub_config.py` – Par défaut, ce fichier est enregistré dans le répertoire `/etc/jupyter/conf/` sur le nœud principal. Pour plus d'informations, consultez la section [Principes de base de la configuration](http://jupyterhub.readthedocs.io/en/latest/getting-started/config-basics.html) dans la JupyterHub documentation.
+ `jupyter_notebook_config.py` – Ce fichier est enregistré dans le répertoire `/etc/jupyter/` par défaut et copié dans le conteneur `jupyterhub` en tant que valeur par défaut. Pour plus d'informations, consultez [Fichier de configuration et options de ligne de commande](https://jupyter-notebook.readthedocs.io/en/5.7.4/config.html) dans la documentation sur les bloc-notes Jupyter.

Vous pouvez également utiliser la classification de configuration `jupyter-sparkmagic-conf` pour personnaliser Sparkmagic, ce qui met à jour les valeurs du fichier `config.json` pour Sparkmagic. Pour plus d'informations sur les paramètres disponibles, consultez le fichier [example\$1config.json](https://github.com/jupyter-incubator/sparkmagic/blob/master/sparkmagic/example_config.json) sur. GitHub Pour plus d'informations sur l'utilisation des classifications de configuration avec des applications dans Amazon EMR, consultez [Configuration des applications](emr-configure-apps.md).

L'exemple suivant lance un cluster en utilisant le AWS CLI, en référençant le fichier `MyJupyterConfig.json` pour les paramètres de classification de configuration de Sparkmagic.

**Note**  
Les caractères de continuation de ligne Linux (\$1) sont inclus pour des raisons de lisibilité. Ils peuvent être supprimés ou utilisés dans les commandes Linux. Pour Windows, supprimez-les ou remplacez-les par un caret (^).

```
aws emr create-cluster --use-default-roles --release-label emr-5.14.0 \
--applications Name=Jupyter --instance-type m4.xlarge --instance-count 3 \
--ec2-attributes KeyName=MyKey,SubnetId=subnet-1234a5b6 --configurations file://MyJupyterConfig.json
```

Exemples de contenu du fichier `MyJupyterConfig.json` :

```
[
    {
    "Classification":"jupyter-sparkmagic-conf",
    "Properties": {
      "kernel_python_credentials" : "{\"username\":\"diego\",\"base64_password\":\"mypass\",\"url\":\"http:\/\/localhost:8998\",\"auth\":\"None\"}"
      }
    }
]
```

**Note**  
Avec la version 5.21.0 et ultérieures d'Amazon EMR, vous permet de remplacer les configurations de cluster et de spécifier des classifications de configuration supplémentaires pour chaque groupe d'instances dans un cluster en cours d'exécution. Pour ce faire, utilisez la console Amazon EMR, le AWS Command Line Interface (AWS CLI) ou le AWS SDK. Pour plus d'informations, consultez [Fourniture d'une configuration pour un groupe d'instances dans un cluster en cours d'exécution](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-configure-apps-running-cluster.html).

# Configuration de la persistance pour les blocs-notes dans Amazon S3
<a name="emr-jupyterhub-s3"></a>

Vous pouvez configurer un JupyterHub cluster dans Amazon EMR afin que les blocs-notes enregistrés par un utilisateur soient conservés dans Amazon S3, en dehors du stockage éphémère sur les instances EC2 du cluster.

Vous spécifiez une persistence Amazon S3 à l'aide de la classification de configuration `jupyter-s3-conf` lorsque vous créez un cluster. Pour de plus amples informations, veuillez consulter [Configuration des applications](emr-configure-apps.md).

En plus de l'activation de persistance Amazon S3 à l'aide de la propriété `s3.persistence.enabled`, vous devez spécifier un compartiment dans Amazon S3 où les blocs-notes sont enregistrés à l'aide de la propriété `s3.persistence.bucket`. Les blocs-notes de chaque utilisateur sont enregistrés dans un dossier `jupyter/jupyterhub-user-name` dans le compartiment spécifié. Le compartiment doit déjà exister dans Amazon S3, et le rôle pour le profil d'instance EC2 que vous spécifiez lorsque vous créez le cluster doit disposer des autorisations pour le compartiment (par défaut, le rôle est `EMR_EC2_DefaultRole`). Pour plus d'informations, consultez [Configurer les rôles IAM pour les autorisations AWS Amazon EMR sur](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-iam-roles.html) les services.

Lorsque vous lancez un nouveau cluster à l'aide des mêmes propriétés de classification de configuration, les utilisateurs peuvent ouvrir des blocs-notes avec le contenu à partir de l'emplacement enregistré.

Notez que lorsque vous importez des fichiers sous forme de modules dans un bloc-notes lorsque Amazon S3 est activé, cela entraîne le chargement des fichiers sur Amazon S3. Lorsque vous importez des fichiers sans activer la persistance Amazon S3, ils sont chargés JupyterHub dans votre conteneur. 

L'exemple suivant active la persistance Amazon S3. Les cahiers enregistrés par les utilisateurs sont enregistrés dans le dossier `s3://MyJupyterBackups/jupyter/jupyterhub-user-name` pour chaque utilisateur, où `jupyterhub-user-name` est un nom d'utilisateur, par exemple `diego`.

```
[
    {
        "Classification": "jupyter-s3-conf",
        "Properties": {
            "s3.persistence.enabled": "true",
            "s3.persistence.bucket": "MyJupyterBackups"
        }
    }
]
```

# Connexion au nœud principal et aux serveurs de bloc-notes
<a name="emr-jupyterhub-connect"></a>

JupyterHub les administrateurs et les utilisateurs d'ordinateurs portables doivent se connecter au nœud principal du cluster à l'aide d'un tunnel SSH, puis se connecter aux interfaces Web desservies par JupyterHub le nœud principal. Pour plus d'informations sur la configuration d'un tunnel SSH et l'utilisation de ce tunnel pour les connexions Web via un proxy, consultez [Connexion au cluster](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-connect-master-node.html) dans le *Guide de gestion d'Amazon EMR*.

Par défaut, JupyterHub sur Amazon, l'EMR est disponible via le **port 9443** sur le nœud principal. Le JupyterHub proxy interne dessert également les instances de bloc-notes via le port 9443. JupyterHub et les interfaces Web de Jupyter sont accessibles à l'aide d'une URL suivant le modèle suivant :

****https : //:9443 *MasterNodeDNS*****

Vous pouvez spécifier un autre port à l'aide de la propriété `c.JupyterHub.port` dans le fichier `jupyterhub_config.py`. Pour plus d'informations, consultez la section [Notions de base de la mise en réseau](http://jupyterhub.readthedocs.io/en/latest/getting-started/networking-basics.html) dans la JupyterHub documentation.

Par défaut, JupyterHub sur Amazon EMR utilise un certificat auto-signé pour le chiffrement SSL via HTTPS. Les utilisateurs sont invités à approuver le certificat auto-signé lorsqu'ils se connectent. Vous pouvez utiliser un certificat approuvé et des clés qui vous sont propres. Remplacez le fichier de certificat par défaut, `server.crt` et le fichier de clé `server.key` dans le répertoire `/etc/jupyter/conf/` du nœud principal par un certificat et des fichiers de clé qui vous sont propres. Utilisez les propriétés `c.JupyterHub.ssl_key` et `c.JupyterHub.ssl_cert` dans le fichier `jupyterhub_config.py` pour spécifier vos matériaux SSL. Pour plus d'informations, consultez [la section Paramètres de sécurité](https://jupyterhub.readthedocs.io/en/latest/tutorial/getting-started/security-basics.html) dans la JupyterHub documentation. Après avoir mis à jour `jupyterhub_config.py`, redémarrez le conteneur.

# JupyterHub configuration et administration
<a name="emr-jupyterhub-administer"></a>

JupyterHub et les composants associés s'exécutent dans un conteneur Docker nommé `jupyterhub` qui exécute le système d'exploitation Ubuntu. Il existe plusieurs méthodes pour administrer des composants s'exécutant à l'intérieur du conteneur.

**Avertissement**  
Les personnalisations que vous effectuez dans le conteneur peuvent ne pas être conservées si le conteneur redémarre. Nous vous recommandons de créer des scripts ou d'automatiser de quelque manière que ce soit les configurations de conteneur, de sorte que vous puissiez reproduire les personnalisations plus rapidement.

## Administration à l'aide de la ligne de commande
<a name="emr-jupyterhub-administer-cli"></a>

Une fois connecté au nœud principal à l'aide de SSH, vous pouvez émettre des commandes en utilisant l'interface de ligne de commande Docker et en spécifiant le conteneur par l'intermédiaire de son nom (`jupyterhub`) ou de son ID. Par exemple, `sudo docker exec jupyterhub command` exécute des commandes reconnues par le système d'exploitation ou par une application exécutée dans le conteneur. Vous pouvez utiliser cette méthode pour ajouter des utilisateurs au système d'exploitation et installer des applications et des bibliothèques supplémentaires au sein du conteneur Docker. Par exemple, l'image de conteneur par défaut inclut Conda pour l'installation de package ; vous pouvez donc exécuter la commande suivante sur la ligne de commande du nœud principal pour installer une application, Keras, dans le conteneur :

```
sudo docker exec jupyterhub conda install keras
```

## Administration par soumission d'étapes
<a name="emr-jupyterhub-administer-steps"></a>

Les étapes constituent un moyen de soumettre le travail à un cluster. Vous pouvez soumettre des étapes lors du lancement d'un cluster ou lorsque celui-ci est en cours d'exécution. Les commandes exécutées sur la ligne de commande peuvent être soumises sous forme d'étapes à l'aide de `command-runner.jar`. Pour plus d'informations, consultez [Utilisation des étapes à l'aide de la CLI et de la console](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-work-with-steps.html) dans le *Guide de gestion d'Amazon EMR* et [Exécuter des commandes et des scripts sur un cluster Amazon EMR](emr-commandrunner.md).

Par exemple, vous pouvez utiliser la AWS CLI commande suivante sur un ordinateur local pour installer Keras de la même manière que vous l'avez fait à partir de la ligne de commande du nœud principal dans l'exemple précédent :

```
aws emr add-steps --cluster-id MyClusterID --steps Name="Command Runner",Jar="command-runner.jar",Args="/usr/bin/sudo","/usr/bin/docker","exec","jupyterhub","conda","install","keras"
```

De plus, vous pouvez créer un script avec une séquence d'étapes, le charger sur Amazon S3, puis utiliser `script-runner.jar` pour l'exécuter lors de la création du cluster ou l'ajouter en tant qu'étape. Pour de plus amples informations, veuillez consulter [Exécuter des commandes et des scripts sur un cluster Amazon EMR](emr-commandrunner.md). Pour obtenir un exemple, consultez [Exemple : script bash pour ajouter plusieurs utilisateurs](emr-jupyterhub-pam-users.md#emr-jupyterhub-script-multuser).

## Administration à l'aide de REST APIs
<a name="emr-jupyterhub-administer-rest"></a>

Jupyter et JupyterHub le proxy HTTP JupyterHub fournissent un REST APIs que vous pouvez utiliser pour envoyer des demandes. Pour envoyer des demandes à JupyterHub, vous devez transmettre un jeton d'API avec la demande. Vous pouvez utiliser la commande `curl` à partir de l'interface de ligne de commande du nœud principal pour exécuter des commandes REST. Pour plus d’informations, consultez les ressources suivantes :
+ [Utilisation JupyterHub de l'API REST](http://jupyterhub.readthedocs.io/en/latest/reference/rest.html) dans la documentation de JupyterHub, qui inclut des instructions pour générer des jetons d'API
+ API du [serveur Jupyter Notebook activée](https://github.com/jupyter/jupyter/wiki/Jupyter-Notebook-Server-API) GitHub
+ [configurable-http-proxy](https://github.com/jupyterhub/configurable-http-proxy)sur GitHub

L'exemple suivant montre comment utiliser l'API REST JupyterHub pour obtenir une liste d'utilisateurs. La commande transmet un jeton d'administration généré précédemment et utilise le port par défaut, 9443 JupyterHub, pour rediriger la sortie vers [jq afin de faciliter](https://stedolan.github.io/jq/) la visualisation :

```
curl -XGET -s -k https://$HOST:9443/hub/api/users \
-H "Authorization: token $admin_token" | jq .
```

# Ajout d'utilisateurs et d'administrateurs de bloc-notes Jupyter
<a name="emr-jupyterhub-user-access"></a>

Vous pouvez utiliser l'une des deux méthodes permettant aux utilisateurs de s'authentifier JupyterHub afin qu'ils puissent créer des blocs-notes et, éventuellement, les administrer. JupyterHub La méthode la plus simple consiste à utiliser JupyterHub le module d'authentification enfichable (PAM). En outre, JupyterHub sur Amazon, EMR prend en charge le [plug-in d'authentification LDAP JupyterHub pour](https://github.com/jupyterhub/ldapauthenticator/) obtenir les identités des utilisateurs à partir d'un serveur LDAP, tel qu'un serveur Microsoft Active Directory. Des instructions et des exemples pour l'ajout d'utilisateurs avec chaque méthode d'authentification sont fournis dans cette section.

JupyterHub sur Amazon EMR possède un utilisateur par défaut doté d'autorisations d'administrateur. Le nom d'utilisateur est `jovyan`, et le mot de passe est `jupyter`. Nous vous recommandons vivement de remplacer cet utilisateur par un autre utilisateur disposant des autorisations d'administrateur. Vous pouvez effectuer cette opération via une étape lorsque vous créez le cluster, ou en vous connectant au nœud maître lorsque le cluster est en cours d’exécution.

**Topics**
+ [Utilisation de l'authentification PAM](emr-jupyterhub-pam-users.md)
+ [Utilisation de l'authentification LDAP](emr-jupyterhub-ldap-users.md)
+ [Emprunt d'identité de l'utilisateur](emr-jupyterhub-user-impersonation.md)

# Utilisation de l'authentification PAM
<a name="emr-jupyterhub-pam-users"></a>

La création d'utilisateurs PAM JupyterHub sur Amazon EMR est un processus en deux étapes. La première étape consiste à ajouter des utilisateurs au système d'exploitation qui s'exécute dans le conteneur `jupyterhub` sur le nœud principal, et d'ajouter le répertoire de base correspondant pour chaque utilisateur. La deuxième étape consiste à ajouter ces utilisateurs du système d'exploitation en tant qu' JupyterHubutilisateurs, un processus connu sous le nom de liste blanche dans. JupyterHub Une fois qu'un JupyterHub utilisateur est ajouté, il peut se connecter à l' JupyterHub URL et fournir les informations d'identification de son système d'exploitation pour y accéder.

Lorsqu'un utilisateur se connecte, JupyterHub ouvre l'instance de serveur de bloc-notes pour cet utilisateur, qui est enregistrée dans le répertoire personnel de l'utilisateur sur le nœud principal, à savoir`/var/lib/jupyter/home/username`. Si aucune instance de serveur de bloc-notes n'existe, JupyterHub génère une instance de bloc-notes dans le répertoire personnel de l'utilisateur. Les sections suivantes montrent comment ajouter des utilisateurs individuellement au système d'exploitation et à JupyterHub, puis comment utiliser un script bash rudimentaire qui ajoute plusieurs utilisateurs.

## Ajout d'un utilisateur du système d'exploitation au conteneur
<a name="emr-jupyterhub-system-user"></a>

L'exemple suivant utilise tout d'abord la commande [useradd](https://linux.die.net/man/8/useradd) dans le conteneur pour ajouter un utilisateur unique, diego, et créer un répertoire de base pour cet utilisateur. La deuxième commande utilise [chpasswd](https://linux.die.net/man/8/chpasswd) pour établir le mot de passe associé à diego pour cet utilisateur. Les commandes sont exécutées sur la ligne de commande du nœud principal lorsque vous êtes connecté à l'aide de SSH. Vous pouvez également exécuter ces commandes à l'aide d'une étape, comme décrit précédemment dans [Administration par soumission d'étapes](emr-jupyterhub-administer.md#emr-jupyterhub-administer-steps).

```
sudo docker exec jupyterhub useradd -m -s /bin/bash -N diego
sudo docker exec jupyterhub bash -c "echo diego:diego | chpasswd"
```

## Ajouter un JupyterHub utilisateur
<a name="emr-jupyterhub-jupyterhub-user"></a>

Vous pouvez utiliser le panneau **d'administration** JupyterHub ou l'API REST pour ajouter des utilisateurs et des administrateurs, ou simplement des utilisateurs.

**Pour ajouter des utilisateurs et des administrateurs à l'aide du panneau d'administration dans JupyterHub**

1. Connectez-vous au nœud principal via SSH et connectez-vous à https : //:9443 *MasterNodeDNS* avec une identité dotée d'autorisations d'administrateur.

1. Choisissez **Control Panel (Panneau de configuration)**, **Admin**.

1. Choisissez **User (Utilisateur)**, **Add Users (Ajouter des utilisateurs)**, ou choisissez **Admin**, **Add Admins (Ajouter des administrateurs)**.

**Pour ajouter un utilisateur à l'aide de l'API REST**

1. Connectez-vous au nœud principal à l'aide de SSH et utilisez la commande suivante sur le nœud principal, ou exécutez la commande en tant qu'étape.

1. Procurez-vous un jeton administratif pour effectuer des demandes d'API et remplacez-le *AdminToken* à l'étape suivante par ce jeton.

1. Utilisez la commande suivante en *UserName* remplaçant par un utilisateur du système d'exploitation créé dans le conteneur.

   ```
   curl -XPOST -H "Authorization: token AdminToken" "https://$(hostname):9443/hub/api/users/UserName
   ```

**Note**  
Vous êtes automatiquement ajouté en tant qu'utilisateur JupyterHub non administrateur lorsque vous vous connectez à l'interface JupyterHub Web pour la première fois.

## Exemple : script bash pour ajouter plusieurs utilisateurs
<a name="emr-jupyterhub-script-multuser"></a>

L'exemple de script bash suivant associe les étapes précédentes de cette section pour créer plusieurs JupyterHub utilisateurs. Le script peut être exécuté directement sur le nœud principal, ou chargé sur Amazon S3 et exécuté en tant qu'étape.

Le script établit tout d'abord une liste des noms d'utilisateur, puis utilise la commande `jupyterhub token` pour créer un jeton d'API pour l'administrateur par défaut jovyan. Ensuite, il crée un utilisateur du système d'exploitation dans le conteneur `jupyterhub` pour chaque utilisateur, et lui affecte un mot de passe initial équivalent à son nom d'utilisateur. Enfin, il appelle l'opération de l'API REST pour créer chaque utilisateur dans JupyterHub. Il transmet le jeton généré précédemment dans le script et transfère la réponse REST à `jq` pour faciliter l'affichage.

```
# Bulk add users to container and JupyterHub with temp password of username
set -x
USERS=(shirley diego ana richard li john mary anaya)
TOKEN=$(sudo docker exec jupyterhub /opt/conda/bin/jupyterhub token jovyan | tail -1)
for i in "${USERS[@]}"; 
do 
   sudo docker exec jupyterhub useradd -m -s /bin/bash -N $i
   sudo docker exec jupyterhub bash -c "echo $i:$i | chpasswd"
   curl -XPOST --silent -k https://$(hostname):9443/hub/api/users/$i \
 -H "Authorization: token $TOKEN" | jq
done
```

Enregistrez le script dans un emplacement Amazon S3 tel que `s3://amzn-s3-demo-bucket/createjupyterusers.sh`. Vous pouvez ensuite utiliser `script-runner.jar` pour l'exécuter en tant qu'étape.

### Exemple : exécution du script lors de la création d'un cluster (AWS CLI)
<a name="emr-jupyterhub-multuser-createcluster"></a>

**Note**  
Les caractères de continuation de ligne Linux (\$1) sont inclus pour des raisons de lisibilité. Ils peuvent être supprimés ou utilisés dans les commandes Linux. Pour Windows, supprimez-les ou remplacez-les par un caret (^).

```
aws emr create-cluster --name="MyJupyterHubCluster" --release-label emr-5.36.2 \
--applications Name=JupyterHub --log-uri s3://amzn-s3-demo-bucket/MyJupyterClusterLogs \
--use-default-roles --instance-type m5.xlarge --instance-count 2 --ec2-attributes KeyName=MyKeyPair \
--steps Type=CUSTOM_JAR,Name=CustomJAR,ActionOnFailure=CONTINUE,\
Jar=s3://region.elasticmapreduce/libs/script-runner/script-runner.jar,Args=["s3://amzn-s3-demo-bucket/createjupyterusers.sh"]
```

### Exécution du script sur un cluster existant (AWS CLI)
<a name="emr-jupyterhub-multuser-runningcluster"></a>

**Note**  
Les caractères de continuation de ligne Linux (\$1) sont inclus pour des raisons de lisibilité. Ils peuvent être supprimés ou utilisés dans les commandes Linux. Pour Windows, supprimez-les ou remplacez-les par un caret (^).

```
aws emr add-steps --cluster-id j-XXXXXXXX --steps Type=CUSTOM_JAR,\
Name=CustomJAR,ActionOnFailure=CONTINUE,\
Jar=s3://region.elasticmapreduce/libs/script-runner/script-runner.jar,Args=["s3://amzn-s3-demo-bucket/createjupyterusers.sh"]
```

# Utilisation de l'authentification LDAP
<a name="emr-jupyterhub-ldap-users"></a>

LDAP (Lightweight Directory Access Protocol) est un protocole d'application pour l'interrogation et la modification d'objets correspondant à des ressources telles que des utilisateurs et des ordinateurs stockés dans un fournisseur de services de répertoire compatible avec LDAP tel qu'Active Directory, ou dans un serveur OpenLDAP. Vous pouvez utiliser le [plug-in d'authentification LDAP pour](https://github.com/jupyterhub/ldapauthenticator/) with JupyterHub sur JupyterHub Amazon EMR afin d'utiliser le protocole LDAP pour l'authentification des utilisateurs. Le plug-in gère les sessions de connexion pour les utilisateurs LDAP et fournit des informations utilisateur à Jupyter. Cela permet aux utilisateurs de se connecter à JupyterHub des blocs-notes en utilisant les informations d'identification de leur identité stockées sur un serveur compatible LDAP.

Les étapes décrites dans cette section vous guident à travers les étapes suivantes pour configurer et activer LDAP à l'aide du plug-in d'authentification LDAP pour. JupyterHub Pour effectuer ces étapes, vous devez être connecté à la ligne de commande du nœud principal. Pour de plus amples informations, veuillez consulter [Connexion au nœud principal et aux serveurs de bloc-notes](emr-jupyterhub-connect.md).

1. Créez un fichier de configuration LDAP avec les informations sur le serveur LDAP, telles que l'adresse IP de l'hôte, le port, les noms de liaison, etc.

1. Modifiez `/etc/jupyter/conf/jupyterhub_config.py` pour activer le plug-in d'authentification LDAP pour JupyterHub.

1. Créez et exécutez un script qui configure LDAP dans le conteneur `jupyterhub`.

1. Interrogez LDAP pour les utilisateurs, puis créez des répertoires personnels dans le conteneur pour chaque utilisateur. JupyterHub nécessite des répertoires personnels pour héberger les blocs-notes.

1. Exécuter un script qui redémarre JupyterHub

**Important**  
Avant de configurer LDAP, testez votre infrastructure réseau afin de vous assurer que le serveur LDAP et le nœud principal du cluster peuvent communiquer si nécessaire. Généralement, TLS utilise le port 389 sur une connexion TCP brute. Si votre connexion LDAP utilise SSL, le port TCP connu pour SSL est 636.

## Création du fichier de configuration LDAP
<a name="emr-jupyterhub-ldap-config"></a>

L'exemple ci-dessous utilise les valeurs de configuration d'espace réservé suivantes. Remplacez ces valeurs par des paramètres qui correspondent à votre implémentation.
+ Le serveur LDAP exécute la version 3 et est disponible sur le port 389. Il s'agit du port non SSL standard pour LDAP.
+ Le nom unique de base est `dc=example, dc=org`.

Utilisez un éditeur de texte pour créer le fichier [ldap.conf](http://manpages.ubuntu.com/manpages/bionic/man5/ldap.conf.5.html), avec un contenu similaire à ce qui suit. Utilisez les valeurs appropriées pour votre implémentation LDAP. *host*Remplacez-le par l'adresse IP ou le nom d'hôte résoluble de votre serveur LDAP.

```
base dc=example,dc=org
uri ldap://host
ldap_version 3
binddn cn=admin,dc=example,dc=org
bindpw admin
```

## Activer le plug-in d'authentification LDAP pour JupyterHub
<a name="emr-jupyterhub-ldap-plugin"></a>

Utilisez un éditeur de texte pour modifier le fichier `/etc/jupyter/conf/jupyterhub_config.py` et ajouter les propriétés [ldapauthenticator](https://github.com/jupyterhub/ldapauthenticator) similaires à ce qui suit. Remplacez *host* par l'adresse IP ou le nom d'hôte résoluble du serveur LDAP. L'exemple suppose que les objets utilisateur se trouvent au sein d'une unité organisationnelle (ou) nommée *people* et utilise les composants de nom unique que vous avez définis précédemment`ldap.conf`.

```
c.JupyterHub.authenticator_class = 'ldapauthenticator.LDAPAuthenticator'
c.LDAPAuthenticator.use_ssl = False
c.LDAPAuthenticator.server_address = 'host' 
c.LDAPAuthenticator.bind_dn_template = 'cn={username},ou=people,dc=example,dc=org'
```

## Configuration de LDAP dans le conteneur
<a name="emr-jupyterhub-ldap-container"></a>

Utilisez un éditeur de texte pour créer un script bash avec le contenu suivant :

```
#!/bin/bash

# Uncomment the following lines to install LDAP client libraries only if
# using Amazon EMR release version 5.14.0. Later versions install libraries by default.
# sudo docker exec jupyterhub bash -c "sudo apt-get update"
# sudo docker exec jupyterhub bash -c "sudo apt-get -y install libnss-ldap libpam-ldap ldap-utils nscd"
 
# Copy ldap.conf
sudo docker cp ldap.conf jupyterhub:/etc/ldap/
sudo docker exec jupyterhub bash -c "cat /etc/ldap/ldap.conf"
 
# configure nss switch
sudo docker exec jupyterhub bash -c "sed -i 's/\(^passwd.*\)/\1 ldap/g' /etc/nsswitch.conf"
sudo docker exec jupyterhub bash -c "sed -i 's/\(^group.*\)/\1 ldap/g' /etc/nsswitch.conf"
sudo docker exec jupyterhub bash -c "sed -i 's/\(^shadow.*\)/\1 ldap/g' /etc/nsswitch.conf"
sudo docker exec jupyterhub bash -c "cat /etc/nsswitch.conf"
 
# configure PAM to create home directories
sudo docker exec jupyterhub bash -c "echo 'session required        pam_mkhomedir.so skel=/etc/skel umask=077' >> /etc/pam.d/common-session"
sudo docker exec jupyterhub bash -c "cat /etc/pam.d/common-session"
 
# restart nscd service
sudo docker exec jupyterhub bash -c "sudo service nscd restart"
 
# Test
sudo docker exec jupyterhub bash -c "getent passwd"

# Install ldap plugin
sudo docker exec jupyterhub bash -c "pip install jupyterhub-ldapauthenticator"
```

Enregistrez le script sur le nœud principal, puis exécutez-le à partir de la ligne de commande du nœud principal. Par exemple, avec le script enregistré sous le nom `configure_ldap_client.sh`, rendez le fichier exécutable :

```
chmod +x configure_ldap_client.sh
```

Exécutez ensuite le script :

```
./configure_ldap_client.sh
```

## Ajout d'attributs à Active Directory
<a name="emr-jupyterhub-ldap-adproperties"></a>

Pour rechercher chaque utilisateur et créer l'entrée appropriée dans la base de données, le conteneur JupyterHub docker nécessite les propriétés UNIX suivantes pour l'objet utilisateur correspondant dans Active Directory. Pour plus d'informations, consultez la section *Comment continuer à modifier les attributs de la GID/UID RFC 2307 maintenant que le plug-in d'attributs Unix n'est plus disponible pour le composant logiciel enfichable MMC Utilisateurs et ordinateurs Active Directory* ? dans l'article [Clarification concernant l'état de la gestion des identités pour Unix (IDMU) et le rôle du serveur NIS dans la version préliminaire technique de Windows Server 2016 et au-delà](https://blogs.technet.microsoft.com/activedirectoryua/2016/02/09/identity-management-for-unix-idmu-is-deprecated-in-windows-server/).
+ `homeDirectory`

  Il s'agit de l'emplacement de l’annuaire de base de l'utilisateur, qui est généralement `/home/username`.
+ `gidNumber`

  Il s'agit d'une valeur supérieure à 60 000 qui n'est pas déjà utilisée par un autre utilisateur. Vérifiez le fichier `etc/passwd` pour les GID en cours d'utilisation.
+ `uidNumber`

  Il s'agit d'une valeur supérieure à 60 000 qui n'est pas déjà utilisée par un autre groupe. Vérifiez le fichier `etc/group` pour les UID en cours d'utilisation.
+ `uid`

  C'est le même que le*username*.

## Création de répertoires de base utilisateur
<a name="emr-jupyterhub-ldap-directories"></a>

JupyterHub a besoin de répertoires personnels au sein du conteneur pour authentifier les utilisateurs LDAP et stocker les données d'instance. L'exemple suivant présente deux utilisateurs, *shirley* et *diego*, dans le répertoire LDAP.

La première étape consiste à interroger le serveur LDAP pour obtenir les informations d'identifiant d'utilisateur et d'identifiant de groupe de chaque utilisateur à l'aide de [ldapsearch](http://manpages.ubuntu.com/manpages/xenial/man1/ldapsearch.1.html), comme indiqué dans l'exemple suivant, en les *host* remplaçant par l'adresse IP ou le nom d'hôte résoluble de votre serveur LDAP :

```
ldapsearch -x -H ldap://host \
 -D "cn=admin,dc=example,dc=org" \
 -w admin \
 -b "ou=people,dc=example,dc=org" \
 -s sub \
 "(objectclass=*)" uidNumber gidNumber
```

La commande `ldapsearch` renvoie une réponse au format LDIF qui ressemble à ce qui suit pour les utilisateurs *shirley* et *diego*.

```
# extended LDIF

# LDAPv3
# base <ou=people,dc=example,dc=org> with scope subtree
# filter: (objectclass=*)
# requesting: uidNumber gidNumber sn 

# people, example.org
dn: ou=people,dc=example,dc=org

# diego, people, example.org
dn: cn=diego,ou=people,dc=example,dc=org
sn: B
uidNumber: 1001
gidNumber: 100

# shirley, people, example.org
dn: cn=shirley,ou=people,dc=example,dc=org
sn: A
uidNumber: 1002
gidNumber: 100

# search result
search: 2
result: 0 Success

# numResponses: 4
# numEntries: 3
```

À l'aide des informations contenues dans la réponse, exécutez des commandes dans le conteneur de manière à créer un répertoire de base pour chaque nom commun d'utilisateur (`cn`). Utilisez la valeur de `uidNumber` et de `gidNumber` pour corriger la propriété du répertoire de base pour cet utilisateur. Les exemples de commandes suivants le font pour l'utilisateur*shirley*.

```
sudo docker container exec jupyterhub bash -c "mkdir /home/shirley"
sudo docker container exec jupyterhub bash -c "chown -R $uidNumber /home/shirley"
sudo docker container exec jupyterhub bash -c "sudo chgrp -R $gidNumber /home/shirley"
```

**Note**  
L'authentificateur LDAP pour JupyterHub ne prend pas en charge la création d'utilisateurs locaux. Pour plus d'informations, consultez la [Remarque sur la configuration de l'authentificateur LDAP pour la création d'utilisateurs locaux](https://github.com/jupyterhub/ldapauthenticator#configuration-note-on-local-user-creation).   
Pour créer manuellement un utilisateur local, utilisez la commande suivante.  

```
sudo docker exec jupyterhub bash -c "echo 'shirley:x:$uidNumber:$gidNumber::/home/shirley:/bin/bash' >> /etc/passwd"
```

## Redémarrer le JupyterHub conteneur
<a name="emr-jupyterhub-ldap-restart"></a>

Exécutez la commande suivante pour redémarrer le conteneur `jupyterhub` :

```
sudo docker stop jupyterhub
sudo docker start jupyterhub
```

# Emprunt d'identité de l'utilisateur
<a name="emr-jupyterhub-user-impersonation"></a>

Une tâche Spark exécutée dans un bloc-note Jupyter traverse plusieurs applications au cours de son exécution sur Amazon EMR. Par exemple, PySpark 3 codes exécutés par un utilisateur dans Jupyter sont reçus par Sparkmagic, qui utilise une requête HTTP POST pour le soumettre à Livy, qui crée ensuite une tâche Spark à exécuter sur le cluster à l'aide de YARN.

Par défaut, les tâches YARN soumises de cette manière s'exécutent sous l'utilisateur `livy`, quel que soit l'utilisateur ayant lancé la tâche. En configurant l'*emprunt d'identité de l'utilisateur*, l'ID utilisateur de l'utilisateur du bloc-notes peut également être l'utilisateur associé à la tâche YARN. Plutôt que les tâches soient lancées par les deux utilisateurs `shirley` et `diego` associés à l'utilisateur `livy`, les tâches initiées par chaque utilisateur sont associées respectivement à `shirley` et à `diego`. Cela vous permet de vérifier l'utilisation de Jupyter et de gérer les applications au sein de votre organisation.

Cette configuration est prise en charge uniquement lorsque des appels de Sparkmagic vers Livy ne sont pas authentifiés. Les applications qui fournissent une couche d'authentification ou de redirection entre les applications Hadoop et Livy (par exemple, Apache Knox Gateway) ne sont pas prises en charge. Les étapes de configuration de l'emprunt d'identité utilisateur décrites dans cette section supposent que Livy JupyterHub et Livy s'exécutent sur le même nœud principal. Si votre application a des clusters séparés, [Étape 3 : Créer des répertoires de base HDFS pour les utilisateurs](#Step3-UserImpersonation) doit être modifiée afin que les annuaires HDFS soient créés sur le nœud maître Livy.

**Topics**
+ [Étape 1 : Configurer Livy](#Step1-UserImpersonation)
+ [Étape 2 : Ajouter des utilisateurs](#Step2-UserImpersonation)
+ [Étape 3 : Créer des répertoires de base HDFS pour les utilisateurs](#Step3-UserImpersonation)

## Étape 1 : Configurer Livy
<a name="Step1-UserImpersonation"></a>

Vous utilisez les classifications de configuration `livy-conf` et `core-site` lorsque vous créez un cluster pour activer l'emprunt d'identité de l'utilisateur Livy, comme illustré dans l'exemple suivant. Enregistrez la classification de configuration sous la forme d'un fichier JSON, puis faites-y référence lorsque vous créez le cluster ou que vous spécifiez la classification de configuration en ligne. Pour de plus amples informations, veuillez consulter [Configuration des applications](emr-configure-apps.md).

```
[
  {
    "Classification": "livy-conf",
    "Properties": {
      "livy.impersonation.enabled": "true"
    }
  },
  {
    "Classification": "core-site",
    "Properties": {
      "hadoop.proxyuser.livy.groups": "*",
      "hadoop.proxyuser.livy.hosts": "*"
    }
  }
]
```

## Étape 2 : Ajouter des utilisateurs
<a name="Step2-UserImpersonation"></a>

Ajoutez des JupyterHub utilisateurs à l'aide de PAM ou LDAP. Pour plus d’informations, consultez [Utilisation de l'authentification PAM](emr-jupyterhub-pam-users.md) et [Utilisation de l'authentification LDAP](emr-jupyterhub-ldap-users.md).

## Étape 3 : Créer des répertoires de base HDFS pour les utilisateurs
<a name="Step3-UserImpersonation"></a>

Vous vous êtes connecté au nœud maître pour créer des utilisateurs. Toujours connecté au nœud maître, copiez le contenu ci-dessous et enregistrez-le dans un fichier script. Le script crée des répertoires de base HDFS pour chaque JupyterHub utilisateur du nœud principal. Le script suppose que vous utilisez l'ID utilisateur administrateur par défaut,*jovyan*.

```
#!/bin/bash

CURL="curl --silent -k"
HOST=$(curl -s http://169.254.169.254/latest/meta-data/local-hostname)

admin_token() {
    local user=jovyan
    local pwd=jupyter
    local token=$($CURL https://$HOST:9443/hub/api/authorizations/token \
        -d "{\"username\":\"$user\", \"password\":\"$pwd\"}" | jq ".token")
    if [[ $token != null ]]; then
        token=$(echo $token | sed 's/"//g')
    else
        echo "Unable to get Jupyter API Token."
        exit 1
    fi
    echo $token
}

# Get Jupyter Admin token
token=$(admin_token)

# Get list of Jupyter users
users=$(curl -XGET -s -k https://$HOST:9443/hub/api/users \
 -H "Authorization: token $token" | jq '.[].name' | sed 's/"//g')

# Create HDFS home dir 
for user in ${users[@]}; 
do
 echo "Create hdfs home dir for $user"
 hadoop fs -mkdir /user/$user
 hadoop fs -chmod 777 /user/$user
done
```

# Installation de noyaux et de bibliothèques supplémentaires
<a name="emr-jupyterhub-install-kernels-libs"></a>

Lorsque vous créez un cluster JupyterHub sur Amazon EMR, le noyau Python 3 par défaut pour Jupyter ainsi que les noyaux Spark PySpark et Spark pour Sparkmagic sont installés sur le conteneur Docker. Vous pouvez installer des noyaux supplémentaires. Vous pouvez également installer des bibliothèques et des packages supplémentaires, puis les importer pour le shell approprié.

## Installation d'un noyau
<a name="emr-jupyterhub-install-kernels"></a>

Les noyaux sont installés dans le conteneur Docker. La manière la plus simple de faire cela consiste à créer un script bash avec des commandes d'installation, de l'enregistrer sur le nœud principal, puis d'utiliser la commande `sudo docker exec jupyterhub script_name` pour exécuter le script dans le conteneur `jupyterhub`. L'exemple de script suivant installe le noyau, puis installe quelques bibliothèques pour ce noyau sur le nœud principal afin que vous puissiez ultérieurement importer les bibliothèques à l'aide du noyau dans Jupyter.

```
#!/bin/bash

# Install Python 2 kernel
conda create -n py27 python=2.7 anaconda
source /opt/conda/envs/py27/bin/activate
apt-get update
apt-get install -y gcc
/opt/conda/envs/py27/bin/python -m pip install --upgrade ipykernel
/opt/conda/envs/py27/bin/python -m ipykernel install

# Install libraries for Python 2
/opt/conda/envs/py27/bin/pip install paramiko nltk scipy numpy scikit-learn pandas
```

Pour installer le noyau et les bibliothèques dans le conteneur, ouvrez une connexion terminale sur le nœud principal, enregistrez le script sous `/etc/jupyter/install_kernels.sh`, et exécutez la commande suivante sur la ligne de commande du nœud principal :

```
sudo docker exec jupyterhub bash /etc/jupyter/install_kernels.sh
```

## Utilisation des bibliothèques et installation de bibliothèques supplémentaires
<a name="emr-jupyterhub-install-libs"></a>

Un ensemble essentiel de bibliothèques d'apprentissage automatique et de science des données pour Python 3 est préinstallé JupyterHub sur Amazon EMR. Vous pouvez utiliser `sudo docker exec jupyterhub bash -c "conda list" ` et `sudo docker exec jupyterhub bash -c "pip freeze"`.

Si une tâche Spark a besoin de bibliothèques sur les nœuds de travail, nous vous recommandons d'utiliser une action d'amorçage pour exécuter un script afin d'installer les bibliothèques lorsque vous créez le cluster. Les actions d'amorçage s'exécutent sur tous les nœuds du cluster pendant le processus de création du cluster, ce qui simplifie l'installation. Si vous installez des bibliothèques sur des nœuds principaux/de travail une fois que le cluster est en cours d'exécution, l'opération est plus complexe. Dans cette section, nous fournissons un exemple de programme Python qui montre comment installer ces bibliothèques.

Les exemples d'action d'amorçage et de programme Python illustrés dans cette section utilisent un script bash enregistré dans Amazon S3 pour installer les bibliothèques sur tous les nœuds.

Le script référencé dans l'exemple suivant utilise `pip` pour installer paramiko, nltk, scipy, scikit-learn et pandas pour le noyau Python 3 :

```
#!/bin/bash

sudo python3 -m pip install boto3 paramiko nltk scipy scikit-learn pandas
```

Après avoir créé le script, chargez-le dans un emplacement dans Amazon S3 par exemple, `s3://amzn-s3-demo-bucket/install-my-jupyter-libraries.sh`. Pour plus d'informations, consultez la section [Chargement d'objets](https://docs.aws.amazon.com/AmazonS3/latest/userguide/upload-objects.html) dans le *Guide de l'utilisateur Amazon Simple Storage Service* afin de pouvoir les utiliser dans votre action de démarrage ou dans votre programme Python.

**Pour spécifier une action d'amorçage qui installe des bibliothèques sur tous les nœuds lorsque vous créez un cluster à l'aide du AWS CLI**

1. Créez un script semblable à l'exemple précédent et enregistrez-le dans un emplacement dans Amazon S3. Nous utilisons l'exemple `s3://amzn-s3-demo-bucket/install-my-jupyter-libraries.sh`.

1. Créez le cluster avec JupyterHub et utilisez l'`Path`argument de l'`--bootstrap-actions`option pour spécifier l'emplacement du script, comme indiqué dans l'exemple suivant :
**Note**  
Les caractères de continuation de ligne Linux (\$1) sont inclus pour des raisons de lisibilité. Ils peuvent être supprimés ou utilisés dans les commandes Linux. Pour Windows, supprimez-les ou remplacez-les par un caret (^).

   ```
   aws emr create-cluster --name="MyJupyterHubCluster" --release-label emr-5.36.2 \
   --applications Name=JupyterHub --log-uri s3://amzn-s3-demo-bucket/MyJupyterClusterLogs \
   --use-default-roles --instance-type m5.xlarge --instance-count 2 --ec2-attributes KeyName=MyKeyPair \
   --bootstrap-actions Path=s3://amzn-s3-demo-bucket/install-my-jupyter-libraries.sh,Name=InstallJupyterLibs
   ```

**Pour spécifier une action d'amorçage qui installe des bibliothèques sur tous les nœuds lorsque vous créez un cluster à l'aide de la console**

1. Accédez à la nouvelle console Amazon EMR et sélectionnez **Changer pour l'ancienne console** depuis le menu latéral. Pour plus d'informations sur ce qu'implique le passage à l'ancienne console, consultez la rubrique [Utilisation de l'ancienne console](https://docs.aws.amazon.com/emr/latest/ManagementGuide/whats-new-in-console.html#console-opt-in).

1. Choisissez **Créer un cluster** et **Go to advanced options (Aller aux options avancées)**.

1. Spécifiez les paramètres pour **Software and Steps (Logiciel et étapes)** et **Hardware (Matériel)** selon les besoins de votre application.

1. Sur l'écran **General Cluster Settings (Paramètres généraux de cluster)**, développez **Bootstrap Actions (Actions d'amorçage)**.

1. Pour **Add bootstrap action (Ajouter une action d'amorçage)**, sélectionnez **Custom action (Action personnalisée)**, **Configure and add (Configurer et ajouter)**.

1. Pour **Name (Nom)**, saisissez un nom convivial. Pour **Emplacement du script**, entrez l'emplacement de votre script dans Amazon S3 (l'exemple que nous utilisons est *s3://amzn-s3-demo-bucket/ install-my-jupyter-libraries .sh*). Laissez les **Optional arguments (Arguments facultatifs)** vides et choisissez **Add (Ajouter)**.

1. Spécifiez les autres paramètres de votre cluster, puis choisissez **Next (Suivant)**.

1. Spécifiez les paramètres de sécurité, puis choisissez **Create cluster (Créer le cluster)**.

**Example Installation de bibliothèques sur les nœuds principaux d'un cluster en cours d'exécution**  
Après avoir installé des bibliothèques sur le nœud principal à partir de Jupyter, vous pouvez installer des bibliothèques sur les nœuds principaux en cours d'exécution de diverses manières. L'exemple suivant présente un programme Python écrit pour s'exécuter sur une machine locale. Lorsque vous exécutez le programme Python localement, il utilise le symbole `AWS-RunShellScript` de AWS Systems Manager pour exécuter l'exemple de script, présenté plus haut dans cette section, qui installe des bibliothèques sur les nœuds principaux du cluster.  

```
import argparse
import time
import boto3


def install_libraries_on_core_nodes(cluster_id, script_path, emr_client, ssm_client):
    """
    Copies and runs a shell script on the core nodes in the cluster.

    :param cluster_id: The ID of the cluster.
    :param script_path: The path to the script, typically an Amazon S3 object URL.
    :param emr_client: The Boto3 Amazon EMR client.
    :param ssm_client: The Boto3 AWS Systems Manager client.
    """
    core_nodes = emr_client.list_instances(
        ClusterId=cluster_id, InstanceGroupTypes=["CORE"]
    )["Instances"]
    core_instance_ids = [node["Ec2InstanceId"] for node in core_nodes]
    print(f"Found core instances: {core_instance_ids}.")

    commands = [
        # Copy the shell script from Amazon S3 to each node instance.
        f"aws s3 cp {script_path} /home/hadoop",
        # Run the shell script to install libraries on each node instance.
        "bash /home/hadoop/install_libraries.sh",
    ]
    for command in commands:
        print(f"Sending '{command}' to core instances...")
        command_id = ssm_client.send_command(
            InstanceIds=core_instance_ids,
            DocumentName="AWS-RunShellScript",
            Parameters={"commands": [command]},
            TimeoutSeconds=3600,
        )["Command"]["CommandId"]
        while True:
            # Verify the previous step succeeded before running the next step.
            cmd_result = ssm_client.list_commands(CommandId=command_id)["Commands"][0]
            if cmd_result["StatusDetails"] == "Success":
                print(f"Command succeeded.")
                break
            elif cmd_result["StatusDetails"] in ["Pending", "InProgress"]:
                print(f"Command status is {cmd_result['StatusDetails']}, waiting...")
                time.sleep(10)
            else:
                print(f"Command status is {cmd_result['StatusDetails']}, quitting.")
                raise RuntimeError(
                    f"Command {command} failed to run. "
                    f"Details: {cmd_result['StatusDetails']}"
                )


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("cluster_id", help="The ID of the cluster.")
    parser.add_argument("script_path", help="The path to the script in Amazon S3.")
    args = parser.parse_args()

    emr_client = boto3.client("emr")
    ssm_client = boto3.client("ssm")

    install_libraries_on_core_nodes(
        args.cluster_id, args.script_path, emr_client, ssm_client
    )


if __name__ == "__main__":
    main()
```

# JupyterHub historique des versions
<a name="JupyterHub-release-history"></a>

Le tableau suivant répertorie la version JupyterHub incluse dans chaque version d'Amazon EMR, ainsi que les composants installés avec l'application. Pour connaître les versions des composants de chaque version, consultez la section Version des composants de votre version dans [Versions Amazon EMR 7.x](emr-release-7x.md), [Versions Amazon EMR 6.x](emr-release-6x.md) ou [Versions Amazon EMR 5.x](emr-release-5x.md).


**JupyterHub informations sur la version**  

| Étiquette de version Amazon EMR | JupyterHub Version | Composants installés avec JupyterHub | 
| --- | --- | --- | 
| emr-7,12.0 | 1.5.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-hdfs-zkfc, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-7.11.0 | 1.5.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-hdfs-zkfc, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-7.10.0 | 1.5.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-7.9.0 | 1.5.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-7,8.0 | 1.5.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-7,7.0 | 1.5.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-7.6.0 | 1.5.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-7.5.0 | 1.5.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-7.4.0 | 1.5.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-7.3.0 | 1.5.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-7.2.0 | 1.5.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.36.2 | 1.4.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-7.1.0 | 1.5.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-7.0.0 | 1.5.0 | emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.15.0 | 1.5.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.14.0 | 1.5.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.13.0 | 1.5.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.12.0 | 1.4.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.11.1 | 1.4.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.11.0 | 1.4.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.10.1 | 1.5.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.10.0 | 1.5.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.9.1 | 1.4.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.9.0 | 1.4.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.8.1 | 1.4.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.8.0 | 1.4.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.7.0 | 1.4.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.36.1 | 1.4.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.36.0 | 1.4.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.6.0 | 1.4.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, hudi, hudi-spark, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.35.0 | 1.4.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.5.0 | 1.4.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.4.0 | 1.4.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.3.1 | 1.2.2 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.3.0 | 1.2.2 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.2.1 | 1.1.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.2.0 | 1.1.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.1.1 | 1.1.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.1.0 | 1.1.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.0.1 | 1.0.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-6.0.0 | 1.0.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.34.0 | 1.4.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.33.1 | 1.2.2 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.33.0 | 1.2.2 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.32.1 | 1.1.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.32.0 | 1.1.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.31.1 | 1.1.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.31.0 | 1.1.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.30.2 | 1.1.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.30.1 | 1.1.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.30.0 | 1.1.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| mr-5.29.0 | 1.0.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.28.1 | 1.0.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.28.0 | 1.0.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.27.1 | 1.0.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.27.0 | 1.0.0 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.26.0 | 0.9.6 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.25.0 | 0.9.6 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.24.1 | 0.9.6 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.24.0 | 0.9.6 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.23.1 | 0.9.4 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.23.0 | 0.9.4 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.22.0 | 0.9.4 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.21.2 | 0.9.4 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.21.1 | 0.9.4 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.21.0 | 0.9.4 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.20.1 | 0.9.4 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.20.0 | 0.9.4 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.19.1 | 0.9.4 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.19.0 | 0.9.4 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.18.1 | 0.8.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.18.0 | 0.8.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.17.2 | 0.8.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.17.1 | 0.8.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.17.0 | 0.8.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.16.1 | 0.8.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.16.0 | 0.8.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.15.1 | 0.8.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.15.0 | 0.8.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.14.2 | 0.8.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.14.1 | 0.8.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 
| emr-5.14.0 | 0.8.1 | aws-sagemaker-spark-sdk, emrfs, emr-goodies, emr-ddb, hadoop-client, hadoop-hdfs-datanode, hadoop-hdfs-library, hadoop-hdfs-namenode, hadoop-kms-server, hadoop-yarn-nodemanager, hadoop-yarn-resourcemanager, hadoop-yarn-timeline-server, r, spark-client, spark-history-server, spark-on-yarn, spark-yarn-slave, livy-server, jupyterhub | 