MAJ le 21 septembre 2017
Qu'est-ce que Amazon Elastic File System (Amazon EFS) ?
Annoncé cet été par Andy Jassy lors du sommet AWS de San Francisco, Amazon Elastic File System (EFS) est un nouveau service permettant de partager un système de fichier entre plusieurs instances EC2 en NFSv4.
Reposant sur des disques SSD, ce service est managé par AWS qui s'occupe de répliquer les données entre différentes zones de disponbilités et de provisionner de manière transparente le nombre d'instances nécéssaires à son bon fonctionnement. Enfin, la tarification repose uniquement sur la quantité d'espace de stockage utilisée à raison de 0,30 USD/Go/mois.
Le services est disponible dans six régions : Dublin et Francfort en Europe, Virginie du Nord, Ohio et Oregon aux États-Unis, et Sydney en Australie.
Pourquoi utiliser Amazon EFS ?
Nous avons déjà S3 non ? Oui, mais S3 n'est pas un filesystem. C'est du stockage objet. Et malheureusement bien peu d'applications savent parler nativement avec S3. Il n'est par exemple pas trivial de rendre cloud-compatible des logiciels aussi fréquents que WordPress, Magento ou encore Drupal.
Création d'un site WordPress scalable
Nous allons ici monter une plateforme WordPress scalable complète basée sur EFS.
On va en profiter pour revoir en détail comment monter un VPC from scratch, avec ses subnets, et route-table. Ça ne fait jamais de mal de reprendre les bases, en suivant les best-practices.
Création des ressources de base
VPC
On commence par créer le VPC :
$ aws ec2 create-vpc \
--cidr-block 10.1.0.0/16
vpc-8fe172ea
Puis on active le support du DNS :
$ aws ec2 modify-vpc-attribute \
--vpc-id vpc-8fe172ea \
--enable-dns-support
$ aws ec2 modify-vpc-attribute \
--vpc-id vpc-8fe172ea \
--enable-dns-hostnames
Etape fondamentale, on nomme notre VPC :
$ aws ec2 create-tags \
--resources vpc-8fe172ea \
--tags Key=Name,Value=efs
Le VPC doit pouvoir accéder à Internet. Il faut donc lui attacher une Internet Gateway :
$ aws ec2 create-internet-gateway
igw-744efa11
On nomme notre Internet Gateway :
$ aws ec2 create-tags \
--resources igw-744efa11 \
--tags Key=Name,Value=efs
Puis enfin, on attache l'attache au VPC :
$ aws ec2 attach-internet-gateway \
--internet-gateway-id igw-744efa11 \
--vpc-id vpc-8fe172ea
Subnets
On va créer deux subnets publics:
1 subnet public en zone A :
$ aws ec2 create-subnet \
--vpc-id vpc-8fe172ea \
--cidr-block 10.1.0.0/24 \
--availability-zone us-west-2a
subnet-d2f890b7
$ aws ec2 create-tags \
--resources subnet-d2f890b7 \
--tags Key=Name,Value=efs-public-subnet-A
$ aws ec2 modify-subnet-attribute \
--subnet-id subnet-d2f890b7 \
--map-public-ip-on-launch
1 subnet public en zone B :
$ aws ec2 create-subnet \
--vpc-id vpc-8fe172ea \
--cidr-block 10.1.1.0/24 \
--availability-zone us-west-2b
subnet-8cc049fb
$ aws ec2 create-tags \
--resources subnet-8cc049fb \
--tags Key=Name,Value=efs-public-subnet-B
$ aws ec2 modify-subnet-attribute \
--subnet-id subnet-8cc049fb \
--map-public-ip-on-launch
Routage
Création et nommage de la table de routage publique
$ aws ec2 create-route-table \
--vpc-id vpc-8fe172ea
rtb-21751244
$ aws ec2 create-tags \
--resources rtb-21751244 \
--tags Key=Name,Value=efs-public-route-table
Ajout de la route par défaut via l'internet gateway, et association de la table de routage aux deux subnets publics
$ aws ec2 create-route \
--route-table-id rtb-21751244 \
--destination-cidr-block 0.0.0.0/0 \
--gateway-id igw-744efa11
$ aws ec2 associate-route-table \
--subnet-id subnet-d2f890b7 \
--route-table-id rtb-21751244
$ aws ec2 associate-route-table \
--subnet-id subnet-8cc049fb \
--route-table-id rtb-21751244
Security Groups
Comme d'habitude, on va créer un groupe par ensemble logique. Dans notre cas :
- Un groupe par defaut pour tout le projet
- Un groupe pour les frontaux PHP
- Un groupe pour la base de données
- Un groupe pour EFS
$ aws ec2 create-security-group \
--group-name efs-default \
--description 'groupe par defaut pour tout le projet' \
--vpc-id vpc-8fe172ea
sg-0b4bb66f
$ aws ec2 create-tags \
--resources sg-0b4bb66f \
--tags Key=Name,Value=efs-default
etc. On répète cette même opération pour les trois autres groupes.
Frontaux et base de données
Base MysQL RDS
On va déployer une instance RDS MySQL single-AZ (pour notre exemple), dans le VPC efs.
DB subnet group
$ aws rds create-db-subnet-group \
--db-subnet-group-name efs \
--db-subnet-group-description efs \
--subnet-ids subnet-d2f890b7 subnet-8cc049fb
Paramètres
$ aws rds create-db-parameter-group \
--db-parameter-group-name efs \
--db-parameter-group-family MySQL5.6 \
--description efs
Démarrage de l'instance RDS
$ aws rds create-db-instance \
--db-instance-identifier efs-mysql \
--db-instance-class db.t2.micro \
--storage-type gp2 \
--engine MySQL \
--allocated-storage 10 \
--db-parameter-group-name efs \
--master-username root \
--master-user-password ************ \
--backup-retention-period 1 \
--no-publicly-accessible \
--region us-west-2 \
--availability-zone us-west-2a \
--vpc-security-group-ids sg-d04bb6b4 \
--db-subnet-group-name efs
Frontaux PHP
On l'a vu, l'usage d'EFS ici va être de pouvoir scaler horizontalement notre WordPress. Qui dit scaler dit donc AutoScaling Group.
Launch configuration
Avant de commencer, il nous faut créer un fichier temporaire contenant les user-data qui seront attachés aux instances de notre groupe d'autoscaling :
$ cat > /tmp/userdata << EOF
#!/bin/bash
wget https://s3-us-west-2.amazonaws.com/test-efs/init-www.sh
chmod +x ./init-www.sh
./init-www.sh
EOF
On va commencer par créer une launch configuration pour nos WordPress a partir d'une image Amazon Linux de base, dans les security
groups efs-default
, efs-www
et, nous verrons plus loin pourquoi, également dans efs-nfs
$ aws autoscaling create-launch-configuration \
--launch-configuration-name efs-www \
--image-id ami-e7527ed7 \
--key-name efs \
--security-groups sg-0b4bb66f sg-cc4bb6a8 sg-da4bb6be \
--instance-type t2.micro \
--user-data file:///tmp/userdata
Préparation des User-Data
On l'a vu, les user-data appelés par la launch config font eux-même référence à un script stocké dans S3. C'est ce script, très simple, qui va installer tout ce qu'il faut pour faire tourner WordPress.
$ cat > /tmp/init-www.sh << EOF
#!/bin/bash
yum -y update
yum -y install httpd24 mysql php56 php56-mysqlnd
chkconfig httpd on
service httpd start
cd /var/www/html
wget https://wordpress.org/latest.tar.gz
tar xf latest.tar.gz
rm latest.tar.gz
chown -R apache:apache /var/www/html
service httpd restart
EOF
Puis on envoie ce fichier dans S3 :
$ aws s3 cp /tmp/init-www.sh s3://test-efs/ --acl public-read
Elastic Load Balancer
Avant de pouvoir lancer nos instances, il nous faut un ELB :
$ aws elb create-load-balancer \
--load-balancer-name efs-www \
--listeners Protocol=HTTP,LoadBalancerPort=80,InstanceProtocol=HTTP,InstancePort=80 \
--subnets subnet-d2f890b7 subnet-8cc049fb \
--security-groups sg-3246bb56
efs-www-464796227.us-west-2.elb.amazonaws.com
AutoScaling Group
On va pouvoir maintenant démarrer notre premier frontal, configurer WordPress et EFS... et voir la magie opérer.
$ aws autoscaling create-auto-scaling-group \
--auto-scaling-group-name efs-www \
--launch-configuration-name efs-www \
--min-size 1 \
--desired-capacity 1 \
--max-size 10 \
--load-balancer-names efs-www \
--vpc-zone-identifier subnet-d2f890b7,subnet-8cc049fb \
--health-check-type ELB \
--health-check-grace-period 300 \
--tags ResourceId=efs-www,ResourceType=auto-scaling-group,Key=Name,Value=efs-www,PropagateAtLaunch=true
Installation et configuration de WordPress
Base de données
on commence tout de suite par configurer la base de données MySQL :
mysql -uroot -hefs-mysql.czpll9qoxxxd.us-west-2.rds.amazonaws.com -p
mysql> CREATE USER "wordpress-user"@"%" IDENTIFIED BY "*************";
mysql> CREATE DATABASE "wordpress-db";
mysql> GRANT ALL PRIVILEGES ON "wordpress-db".* TO "wordpress-user"@"%";
mysql> exit
Configuration de WordPress
Rendez vous à l'adresse de votre ELB /wordpress. dans notre cas : http://efs-www-464796227.us-west-2.elb.amazonaws.com/wordpress
Vous devriez voir aparaître l'assistant de configuration. Faites ce qu'il faut. (nous ne sommes pas ici dans un tutorial WordPress).
C'est parfait, nous avons maitenant notre WordPress fonctionnel !
Et maintenant ?
Et oui ? et maintenant ? On vient de passer tout ce temps pour juste avoir un WordPress qui marche ? Quel était le sujet initial déjà ? Ah oui, Elastic File System.
Et si on scalait ?
Autrement dit, que se passe-t-il si on ajoute un second frontal parce que subitement notre superbe blog se met a avoir un succès fou ?
Il suffit de passer notre --desired-capacity
a 2 au niveau de l'autoscaling group, et puis voilà !
Oui... mais non.
Oui, ça fonctionnera, on aura bien un second frontal avec WordPress fonctionnel... Sauf que... les données ne seront pas partagées entre les deux
frontaux. Typiquement, si vous envoyez une photo depuis l'interface d'administration, celle-ci sera stockée sur un des deux frontal. Si un visiteur arrive
et tombe sur l'autre frontal, il ne verra pas l'image. Dommage.
Il faut donc trouver un moyen fiable d'avoir un système de fichier partagé, étant donné que WordPress n'est pas nativement Cloud-Ready. (Exemple, il n'est pas capable nativement de stocker ces medias dans S3...)
C'est là qu'EFS arrive à notre secours (on ne s'en doutait pas...).
EFS va nous permettre de monter un système de fichier partagé (NFS) fiable, scalable et... pas trop cher.
EFS, nous voilà
Avant de commencer, il nous faut générer une chaîne aléatoire :
$ uuidgen
7fd8f05d-1841-4f5d-b0a9-a5c539048f4c
On peut donc maitenant créer notre EFS :
$ aws efs create-file-system \
--creation-token 7fd8f05d-1841-4f5d-b0a9-a5c539048f4c
fs-aee10d07
Comme d'habitude, on respecte les bonnes pratiques, et on nomme notre EFS :
$ aws efs create-tags \
--file-system-id fs-aee10d07 \
--tags Key=Name,Value=efs-www
Maintenant, il nous faut créer une cible de montage (horrible traduction de mount target)
$ aws efs create-mount-target \
--file-system-id fs-aee10d07 \
--subnet-id subnet-d2f890b7 \
--security-groups sg-da4bb6be
$ aws efs create-mount-target \
--file-system-id fs-aee10d07 \
--subnet-id subnet-8cc049fb \
--security-groups sg-da4bb6be
Pour que tout fonctionne, il faut autoriser le port tcp/2049 au niveau du security group efs-nfs
en provenance du groupe efs-www
.
Et voilà !
Nous avons maintenant un superbe système de fichier NFS disponible sur nos frontaux wordpress. Allons voir ça.
Montage de l'EFS sur les frontaux
On se connecte à notre pour le moment unique frontal, et on va tester que tout fonctionne.
On commence par installer le client NFS :
$ sudo yum install -y nfs-utils
puis on va créer un dossier partagé :
$ sudo mkdir /efs
$ sudo mount -t nfs4 $(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone).fs-aee10d07.efs.us-west-2.amazonaws.com:/ /efs
copions maintenant tout le contenu de /var/www/html/wordpress dans /efs
$ sudo mv /var/www/html/wordpress /efs
et, même si ce n'est pas la plus belle façon de faire, faisons rapidement un lien symbolique :
$ sudo mv /var/www/html /var/www/html.SAV
$ sudo ln -s /efs /var/www/html
et redémarrons Apache
$ sudo service httpd restart
Testons
On peut maintenant visiter notre superbe blog en se rendant sur l'adresse de notre ELB. Dans notre cas : http://efs-www-464796227.us-west-2.elb.amazonaws.com/wordpress
C'est parfait, nous avons un WordPress qui semble fonctionner à merveille. Oui et ? Tout ça pour ça ?
Non ! Car maintenant notre blog est scalable ! Si nous souhaitons avoir non plus un frontal, mais deux, dix, trente-six, c'est possible ! Et nous allons le prouver.
Mise à jour des user-data
Avant tout, il faut un peu modifier notre script d'init appelé lors du premier démarrage des instances. Rappelez-vous, c'est le script que nous avons poussé dans S3.
$ cat > /tmp/init-www.sh << EOF
#!/bin/bash
yum -y update
yum -y install httpd24 mysql php56 php56-mysqlnd nfs-utils
mkdir /efs
mount -t nfs4 $(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone).fs-aee10d07.efs.us-west-2.amazonaws.com:/ /efs
mv /var/www/html /var/www/html.SAV
ln -s /efs /var/www/html
service httpd start
chkconfig httpd on
EOF
Il nous faut maintenant envoyer ce script dans S3 :
$ aws s3 cp /tmp/init-www.sh s3://test-efs/ --acl public-read
Scale-up
Voilà, tout est prêt, nous pouvons maintenant passer de 1 frontal à 2. Pour cela, il suffit de changer le desired-capacity
de
l'autoscaling group :
$ aws autoscaling set-desired-capacity \
--auto-scaling-group-name efs-www \
--desired-capacity 2
Conclusion
Alors, EFS, bien ? pas bien ?
Les deux mon capitaine !
Techniquement, il faut bien avouer qu'EFS est un petit bijou. Un NFSaaS (As a Service), multi-AZ, à un coût raisonnable manquait cruellement à l'offre Amazon. Où est donc le problème ? Et bien le NFS, c'est bien, mais ce n'est vraiment pas cloud. Dans l'idéal, dans du vrai cloud, les instances ne devraient jamais avoir comme pré-requis un système de fichier partagé. Malheureusement, nos amis les développeurs n'ont pour beaucoup toujours pas intégré ce problème.
Il est dommage que WordPress ne sache pas nativement communiquer avec S3 pour y stocker les fichiers partagés (les médias, les thèmes, etc.). Ce problème n'est malheureusement pas propre à WordPress. Rares sont en fait les outils (Magento, Drupal, etc.) réellement cloud-ready. Le problème d'EFS peut donc, paradoxalement être sa trop grande simplicité. Maintenant qu'EFS existe, pourquoi les développeurs s'embêteraient-ils à dépenser temps et argent pour modifier leurs logiciels pour les rendre cloud-friendly ? ...
Si le Cloud a réussi à prouver ses nombreux avantages, force est de constater que les applications - et notamment les CMS les plus connus - nécessitent encore des aménagements pour en tirer le meilleur profit. Avec Amazon EFS, cet effort de "cloudification" de l'applicatif se réduit un peu plus, le reste du chemin pouvant être confié aux équipes d'Osones qui travaillent aux côtés de vos développeurs pour s'assurer du bon respect des best practices. Et une fois que vous profiterez de la même infrastructure que le géant mondial du e-commerce, qui vous arrêtera ?
Alexis GÜNST HORN
C'est à vous de jouer !
Questions, remarques, suggestions... Contactez-nous directement sur Twitter sur @osones !
Pour discuter avec nous de vos projets, nous restons disponibles directement via contact@osones.com ou via le chat !
- Encore un peu de temps ? Parcourez nos dossiers :
A la découverte d'AWS Lambda
A la découverte d'Amazon DynamoDB Streams
Container as a Service avec Amazon EC2 Container Service (ECS)
On a testé Amazon Elastic File System (EFS)
Rejoignez VOTRE groupe LinkedIn dès maintenant : Utilisateurs Francophones d'Amazon Web Services (AWS).
Découvrez les derniers articles d'alter way
- kubevpn
- Kubernetes 1.32
- re:Invent 2024 : AWS mise tout sur l'IA pour son Cloud
- OVHcloud Summit 2024 : L’innovation au cœur d’un cloud souverain et performant
- Big Data & AI Paris 2024 : L'IA au cœur de toutes les transformations.
- Un retour vers l'open-source ? Vos outils DevOps préférés et leurs equivalents open-source.