Séparer les répertoires des applications avec des points d’accès

AWSBeginner
Pratiquer maintenant

Introduction

Deux applications ont besoin d’un stockage partagé tout en travaillant chacune dans son répertoire. Configurez des points d’accès EFS pour sélectionner une racine et une identité POSIX par montage, puis observez les fichiers et propriétaires réels.

Terminez d’abord Partager des fichiers entre serveurs d’applications avec EFS. Cette VM indépendante fournit de nouveaux hôtes et un sous-réseau, sans reprendre le système précédent. Utilisez Terminal pour AWS CLI et SSH, et AWS View pour les réponses des applications. Aucun compte AWS personnel n’est requis.

Lien avec les certifications

Certification Tâche de l’examen Pratique
Cloud Practitioner (CLF-C02) Task 3.6 Explorer EFS et comparer les répertoires et permissions de fichiers au stockage objet.

Vue d’ensemble

Schéma conceptuel ; consultez les identifiants de votre nouvel environnement.

Préparer le système partagé et le point de connexion NFS

Dans cette étape, créez le stockage et le point de connexion limité des applications.

Travaillez dans /home/labex/project et identifiez le réseau fourni. AWS CLI est configurée :

cd /home/labex/project
aws sts \
  get-caller-identity
SUBNET_ID=$(jq -r .subnet_id resources.json)
APP_GROUP_ID=$(jq -r .application_group_id resources.json)
VPC_ID=$(jq -r .vpc_id resources.json)
echo "$SUBNET_ID"
echo "$APP_GROUP_ID"
echo "$VPC_ID"

Créez un nouveau système EFS. Les applications utilisent la même ressource ; les points d’accès sélectionnent des répertoires différents :

FS_ID=$(aws efs \
  create-file-system \
  --creation-token fs02-application-files \
  --encrypted \
  --tags Key=Name,Value=fs02-application-files \
  --query FileSystemId --output text)
echo "$FS_ID"

Créez un groupe de stockage dédié :

EFS_GROUP_ID=$(aws ec2 \
  create-security-group \
  --group-name fs02-efs-access \
  --description 'NFS for the upload application servers' \
  --vpc-id "$VPC_ID" \
  --query GroupId --output text)
echo "$EFS_GROUP_ID"

Autorisez TCP 2049 depuis le groupe des applications. Cette règle permet NFS, mais ne choisit ni le répertoire ni l’identité de l’application :

aws ec2 \
  authorize-security-group-ingress \
  --group-id "$EFS_GROUP_ID" \
  --ip-permissions "IpProtocol=tcp,FromPort=2049,ToPort=2049,UserIdGroupPairs=[{GroupId=$APP_GROUP_ID}]"

Créez la cible dans le sous-réseau préparé :

MOUNT_TARGET_ID=$(aws efs \
  create-mount-target \
  --file-system-id "$FS_ID" \
  --subnet-id "$SUBNET_ID" \
  --security-groups "$EFS_GROUP_ID" \
  --query MountTargetId --output text)
echo "$MOUNT_TARGET_ID"

Inspectez les états et attendez que les deux ressources soient available :

aws efs \
  describe-file-systems \
  --file-system-id "$FS_ID" \
  --query 'FileSystems[].{ID:FileSystemId,State:LifeCycleState}'
aws efs \
  describe-mount-targets \
  --file-system-id "$FS_ID" \
  --query 'MountTargets[].{ID:MountTargetId,IP:IpAddress,State:LifeCycleState}'

Créer des points d’accès propres aux applications

Dans cette étape, définissez la racine et l’identité des opérations pour chaque montage.

Un point d’accès est une entrée EFS propre à une application. Sa racine devient / dans le montage et son utilisateur POSIX remplace l’identité des opérations du client. POSIX identifie les utilisateurs par un UID numérique et les groupes par un GID.

Créez le point de A :

AP_A_ID=$(aws efs \
  create-access-point \
  --file-system-id "$FS_ID" \
  --posix-user Uid=2001,Gid=2001 \
  --root-directory 'Path=/app-a,CreationInfo={OwnerUid=2001,OwnerGid=2001,Permissions=700}' \
  --tags Key=Name,Value=fs02-app-a \
  --query AccessPointId --output text)
echo "$AP_A_ID"

Si /app-a n’existe pas, CreationInfo fournit le propriétaire et les permissions. 700 donne au propriétaire lecture, écriture et traversée du répertoire sans les accorder aux autres utilisateurs. L’UID/GID du point correspond au propriétaire.

Créez un deuxième point avec une racine et une identité différentes :

AP_B_ID=$(aws efs \
  create-access-point \
  --file-system-id "$FS_ID" \
  --posix-user Uid=2002,Gid=2002 \
  --root-directory 'Path=/app-b,CreationInfo={OwnerUid=2002,OwnerGid=2002,Permissions=700}' \
  --tags Key=Name,Value=fs02-app-b \
  --query AccessPointId --output text)
echo "$AP_B_ID"

Inspectez les deux définitions :

aws efs \
  describe-access-points \
  --file-system-id "$FS_ID" \
  --query 'AccessPoints[].{ID:AccessPointId,Root:RootDirectory.Path,User:PosixUser,Creation:RootDirectory.CreationInfo}'

Les racines sont /app-a et /app-b, les identités 2001:2001 et 2002:2002. L’étape suivante vérifie le comportement réel ; la configuration seule ne prouve pas la limite.

Le point contraint la racine et l’identité du montage qui le sélectionne. Il n’empêche pas à lui seul un client autorisé de choisir un autre point. En production, IAM et les politiques du système peuvent limiter les points autorisés. Cet exercice porte sur les répertoires et POSIX.

Observer la séparation et la propriété imposée

Dans cette étape, montez les points et prouvez qu’un même nom désigne des fichiers différents.

Montez le point de A sur A. Les montages avec point d’accès nécessitent TLS :

ssh -F ssh_config application-a \
  "sudo mkdir -p /srv/shared && sudo mount -t efs -o tls,stunnel,lookupcache=positive,accesspoint=${AP_A_ID} ${FS_ID}:/ /srv/shared"

lookupcache=positive interroge de nouveau les noms absents lorsqu’une autre application crée un fichier. Cela rend l’exercice court observable ; les réglages de cache en production demandent une évaluation de performance séparée. Voir les options de cache NFS Linux.

Montez le point de B sur B :

ssh -F ssh_config application-b \
  "sudo mkdir -p /srv/shared && sudo mount -t efs -o tls,stunnel,lookupcache=positive,accesspoint=${AP_B_ID} ${FS_ID}:/ /srv/shared"

Les deux chemins locaux sont /srv/shared, mais ils représentent /app-a sur A et /app-b sur B. Configurez les applications pour utiliser la racine de leur point :

ssh -F ssh_config application-a \
  'printf "{\"upload_directory\":\"/srv/shared\"}\n" | sudo tee /etc/uploads-app/config.json'
ssh -F ssh_config application-b \
  'printf "{\"upload_directory\":\"/srv/shared\"}\n" | sudo tee /etc/uploads-app/config.json'

Écrivez private.txt par A et essayez de le lire par B :

curl -i -X PUT --data-binary 'Private upload for application A' \
  http://127.0.0.1:8081/uploads/private.txt
curl -i http://127.0.0.1:8082/uploads/private.txt

A renvoie 201 Created, B 404 Not Found. Créez maintenant le fichier propre à B avec le même nom :

curl -i -X PUT --data-binary 'Private upload for application B' \
  http://127.0.0.1:8082/uploads/private.txt
curl -i http://127.0.0.1:8081/uploads/private.txt
curl -i http://127.0.0.1:8082/uploads/private.txt

A conserve son contenu et B renvoie le sien. Choisissez private.txt et Read upload dans les deux cartes AWS View.

Inspectez les montages et identités réels :

ssh -F ssh_config application-a 'findmnt -t nfs4 /srv/shared; stat -c "%i %u:%g" /srv/shared/private.txt'
ssh -F ssh_config application-b 'findmnt -t nfs4 /srv/shared; stat -c "%i %u:%g" /srv/shared/private.txt'

Les inodes diffèrent et les propriétaires sont 2001:2001 et 2002:2002. L’application tourne comme labex, mais le serveur applique l’identité du point.

Même une écriture de root par le montage de A utilise cette identité :

ssh -F ssh_config application-a \
  'printf "Access-point identity also applies to root callers\n" | sudo tee /srv/shared/root-caller.txt; stat -c "%u:%g" /srv/shared/root-caller.txt'

Le propriétaire est 2001:2001. EFS applique ces identités numériques sans comptes locaux nommés 2001 et 2002.

Le montage de A expose /app-a, pas toute la racine EFS. Le répertoire frère de B n’est pas un enfant de ce montage :

ssh -F ssh_config application-a 'ls -a /srv/shared'
ssh -F ssh_config application-a 'cat /srv/shared/app-b/private.txt'

La dernière commande retourne No such file or directory, alors que B lit son fichier existant. Les racines indépendantes et contenus distincts démontrent la séparation. Depuis le point de montage local, .. mène au parent local, pas au répertoire frère EFS.

Répertoires séparés dans AWS View

Le même nom a des contenus différents dans deux racines. Les identifiants varient entre environnements.

Supprimer les points d’accès et le stockage

Dans cette étape, libérez les montages et supprimez uniquement votre stockage.

Rétablissez les répertoires locaux avant de démonter :

ssh -F ssh_config application-a \
  'printf "{\"upload_directory\":\"/srv/uploads\"}\n" | sudo tee /etc/uploads-app/config.json'
ssh -F ssh_config application-b \
  'printf "{\"upload_directory\":\"/srv/uploads\"}\n" | sudo tee /etc/uploads-app/config.json'
ssh -F ssh_config application-a 'sudo umount /srv/shared'
ssh -F ssh_config application-b 'sudo umount /srv/shared'

Supprimez les deux points puis confirmez qu’il n’en reste aucun :

aws efs \
  delete-access-point \
  --access-point-id "$AP_A_ID"
aws efs \
  delete-access-point \
  --access-point-id "$AP_B_ID"
aws efs \
  describe-access-points \
  --file-system-id "$FS_ID"

AccessPoints doit être vide. Supprimer un point enlève sa définition, pas les fichiers de son répertoire. Vous allez supprimer tout le système jetable et ses données :

aws efs \
  delete-mount-target \
  --mount-target-id "$MOUNT_TARGET_ID"
aws efs \
  describe-mount-targets \
  --file-system-id "$FS_ID"

Attendez que MountTargets soit vide avant de continuer :

aws efs \
  delete-file-system \
  --file-system-id "$FS_ID"
aws ec2 \
  delete-security-group \
  --group-id "$EFS_GROUP_ID"

Confirmez des réponses réussies et vides pour vos ressources nommées :

aws efs \
  describe-file-systems \
  --query 'FileSystems[?Name==`fs02-application-files`].FileSystemId'
aws ec2 \
  describe-security-groups \
  --filters Name=group-name,Values=fs02-efs-access \
  --query 'SecurityGroups[].GroupId'

Les deux listes sont vides. Conservez les serveurs, groupes et sous-réseau fournis, puis exécutez la vérification.

Résumé

Deux points d’accès ont sélectionné des racines et identités POSIX différentes dans le même EFS. Des noms identiques contenaient des données distinctes ; le serveur imposait la propriété même aux clients root. Vous avez ensuite démonté et supprimé les points, la cible et le système jetable.

La connexion réseau, le choix du montage et les permissions sont des couches différentes. Le prochain exercice les utilise pour diagnostiquer une connexion EFS.

Pour approfondir ce sujet, consultez la documentation AWS : Racines, identités et portée d’autorisation des points d’accès.