Retour sur le forum PHP 2024
Revivez les moments forts du Forum PHP 2024 avec l'AFUP ! Découvrez l'avenir du PHP et les innovations qui feront la différence.
Cet article va nous permettre de publier un site vueJs ou dans notre cas un site en nuxtJs sur un S3 Amazon, avec un cache CDN sous le nom de CloudFront.Tout ceci de manière automatisée avec Gitlab CI/CD.
Pour ceci, nous allons avoir besoin de 3 choses :
Une fois connecté, vous pouvez aller sur la section S3 > "Créer un compartiment".
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::nuxt-website-efficience-it/*"
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::nuxt-website-efficience-it/*"
}
]
}
Ainsi vous pourrez cliquer sur le lien spécifié dans votre S3 : voici celui de l'exemple
http://nuxt-website-efficience-it.s3-website.eu-west-3.amazonaws.com/
Vous devez avoir une erreur 404 vous disant que le fichier racine (index.html) n'existe pas, ce qui est normal.
404 Not Found
Code: NoSuchKey
Message: The specified key does not exist.
Key: index.html
Je vous invite donc à créer un fichier index.html et y insérer ce que vous souhaitez afin de le déposer à la racine du S3 et vérifier que vous avez bien votre page qui s'affiche.
Cloudfront sert en fait, à faire un cache réseau pour votre contenu css, js et html. Nous allons donc le configurer pour gagner en performance et également pour éviter de payer à chaque fois qu'une personne souhaite aller sur le site.
Dans la section CloudFront de votre Console Amazon, vous pouvez
Je vous invite à lire de la doc sur le sujet si vous souhaitez aller plus loin et attribuer un nom de domaine, un certificat SSL.
Avant de partir, vous devez récupérer l'identifiant de la distribution que nous mettrons plus tard dans une variable nommmée AWS_CLOUDFRONT_INVALIDATION_ID
Dans votre console toujours, je vous invite à taper IAM, pour ajouter un utilisateur, le 'gitlab-runner'. Vous devrez lui ajouter ces autorisations, à savoir :
Il faudra ensuite que vous alliez dans "Informations d'identification de sécurité" pour y créer une clé d'accès que nous nommerons AWS_ACCESS_KEY_ID & AWS_SECRET_ACCESS_KEY.
Ces accès vous permettront d'utiliser l'utilisateur gitlab-runner avec les droits d'accés que nous venons de configurer. Il sera autorisé ainsi à déposer des éléments dans votre S3 et invalider le cache CDN pour que vos prochains visiteurs bénéficient de votre nouveau contenu.
Afin de générer les fichiers que nous allons pousser sur le S3, nous allons créer une première étape qui est le 'build'. Dans cette étape, nous installons les dépendances, puis nous générons le projet dans un dossier '/dist' qui va être transmis dans ce qu'on appelle un artifact.
C'est un genre de résultat de l'étape que l'on va réutiliser ensuite pour déployer le projet.
La Ci permet également de bénéficier du cache d'un run à l'autre. Ce que nous allons utiliser ici avec /node_modules, afin d'optimiser le temps de déploiement.
stages:
- build
cache:
paths:
- node_modules/
build_site:
image: node:lts
before_script:
- npm install
script:
- npm run generate --fail-on-error --quiet --no-optional
artifacts:
paths:
- dist
Dans celle-ci, nous reprenons l'articfact généré dans l'étape précédente, pour l'envoyer sur notre S3. La deploy part alors d'une machine python, dans lequel, on installe awscli (ce sont des commandes bash pour interagir avec l'API Amazon).
stages:
- deploy
variables:
AWS_DEFAULT_REGION: eu-central-1
deploy_s3:
image: python:latest
stage: deploy
before_script:
- pip install awscli
script:
- aws s3 sync dist s3://${AWS_BUCKET_NAME} --delete --cache-control "max-age=31536000" --expires 2030-01-01T00:00:00Z
- aws cloudfront create-invalidation --distribution-id ${AWS_CLOUDFRONT_INVALIDATION_ID} --paths "/*"
Pour cela, vous allez devoir configurer les variables qui seront protégées et non visibles dans votre repository.
Avec ceci, dès que vous ferez un commit/push sur votre gitlab, vous verrez dans votre pipeline, le Build puis le Deploy tourner.
Le principe est de faire un bucket et un CloudFront pour vos environnements de développement et un autre pour votre environnement de production. Selon ce principe, vous avez votre branche master déployé sur la prod et la branche develop sur votre environnement de développement de manière automatisée.
Et enfin, lorsque vous créez une branche avec votre nouvelle feature/etc ou un fix/etc, vous avez un bouton manuel sur votre interface Gitlab qui vous permet de déployer cette branche sur votre environnement de developpement. Et lorsque vous la fusionnerez avec la branche develop lors de votre MR, la branche develop se redéploiera sur votre environnement de développement avant que vous ne mergiez sur la master pour que cela soit déployé en prod.
stages:
- build
- deploy
cache:
paths:
- node_modules/
.build_site:
stage: build
image: node:lts
before_script:
- npm install
artifacts:
paths:
- dist
build_site_prod:
extends: .build_site
script:
- npm run generate --fail-on-error --quiet --no-optional
only:
- master
build_site_dev:
extends: .build_site
script:
- npm run generate --fail-on-error --quiet --no-optional
only:
- dev
build_site_branch:
extends: .build_site
script:
- npm run generate --fail-on-error --quiet --no-optional
when: manual
except:
- master
- dev
variables:
AWS_DEFAULT_REGION: eu-central-1
.deploy_s3:
image: python:latest
stage: deploy
before_script:
- pip install awscli
deploy_s3_branch:
needs:
- build_site_branch
extends: .deploy_s3
when: on_success
except:
- master
- dev
script:
- aws s3 sync dist s3://dev.exemple.com --delete --cache-control "max-age=31536000" --expires 2030-01-01T00:00:00Z
- aws cloudfront create-invalidation --distribution-id ${AWS_CLOUDFRONT_INVALIDATION_ID_DEV} --paths "/*"
environment:
name: developement
url: https://dev.exemple.com
deploy_s3_dev:
needs:
- build_site_dev
extends: .deploy_s3
when: on_success
only:
- dev
script:
- aws s3 sync dist s3://dev.exemple.com --delete --cache-control "max-age=31536000" --expires 2030-01-01T00:00:00Z
- aws cloudfront create-invalidation --distribution-id ${AWS_CLOUDFRONT_INVALIDATION_ID_DEV} --paths "/*"
environment:
name: developement
url: https://dev.exemple.com
deploy_s3_prod:
extends: .deploy_s3
only:
- master
before_script:
- pip install awscli
script:
- aws s3 sync dist s3://www.exemple.com --delete --cache-control "max-age=31536000" --expires 2030-01-01T00:00:00Z
- aws cloudfront create-invalidation --distribution-id ${AWS_CLOUDFRONT_INVALIDATION_ID_PROD} --paths "/*"
environment:
name: production
url: https://www.exemple.com
Pour en savoir plus sur Gitlab CI/CD, visitez notre blog !