Présentation
Vous souhaitez héberger un site statique mais n’avez pas envie de devoir gérer l’installation d’un serveur web et la configuration d’un apache/nginx/…, il existe aujourd’hui des alternatives, sans aucune configuration de machine, sans maintenance, supportant les pics de charge et très performant.
Je vous présente ici une solution reposant sur les services fournis par AWS, ainsi qu’une gestion du site au travers de Gitlab ou Azure Devops et d’un pipeline de CI/CD.
Nous avons besoin de :
-
un bucket S3 (non public) pour héberger les données du site
-
un CDN, Cloudfront
-
Un runner (EC2, runner Azure, ...)
Si votre nom de domaine est géré par un tiers (OVH, Ghandi, …), il faudra faire quelques manipulations supplémentaires décrites plus bas, ici nous verrons pour la délégation d’un sous-domaine.
La création du certificat et son renouvellement sera là aussi complètement géré par AWS.
Création du site docusaurus
Nous avons fait le choix de docusaurus pour sa simplicité, sa légèreté, et sa communauté active qui montre l’engouement envers ce projet open-source.
Pour en savoir plus : https://docusaurus.io
Installation des dépendances
La première chose est de préparer le site, qui a besoin de certaines dépendances pour pouvoir être généré.
Voici les dépendances requises à la date de rédaction de l'article (2.0.0-beta.9) :
- Node.js version >= 14 ou supérieure
- Yarn version >= 1.5
Nous installons donc en local les dépendances (si vous êtes sous Linux ou via WSL sur un poste Windows par exemple)
apt install yarn
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
On peut vérifier l’installation de nvm (après avoir relancé le terminal)
command -v nvm
Installation de nodejs en version 14.18.1 (quelques soucis avec les dernières versions)
nvm install 14.18.1
Génération de l’arborescence Docusaurus
Pour générer l’arborescence du site
npm init docusaurus@latest nom_du_projet classic
classic
représente le template sélectionné.
Et voilà, la base du site est prête !
Vous pouvez configurer le site à votre convenance (je vous renvoie une nouvelle fois vers la doc ; très bien faire ; de docusaurus -> https://docusaurus.io/fr/docs/configuration)
Pour tester le site rapidement (vous voyez même les changements en direct dès qu'un fichier est modifié)
- npm
- yarn
npm start
yarn start
Génération du build
Depuis le dossier de votre projet, lancer le build
- npm
- yarn
npm run build
yarn run build
Cela va générer un dossier build contenant tous les fichiers nécessaires.
Vous pouvez tester ce build avec cette commande :
- npm
- yarn
npm run serve
yarn run serve
Création de l’infra AWS
Maintenant que vous avez le contenu du site, on va pouvoir créer l’infra qui va l’héberger chez AWS.
Nom de domaine
Comme précisé plus tôt, si votre gestionnaire de nom de domaine est externe à AWS, pas de panique, il n’y a pas grand-chose à faire de plus pour déléguer le sous-domaine.
Dans votre console AWS, vous devez créer une nouvelle Hosted zones correspondant au nom de domaine.
Puis côté OVH (par exemple) vous devez ajouter les 4 entrés NS générées par AWS en spécifiant le sous-domaine voulu.
Terraform
Nous utilisons Terraform pour des questions pratiques. Il s’agit d’un outil logiciel permettant d’automatiser la création et la gestion des infrastructures IT dans le cloud. Si vous ne connaissez pas cet outils d’Infra-As-Code, je vous conseille très fortement de vous y intéresser ! Cela fera d'ailleurs l'objet d'un futur article.
Pour télécharger le template =>
Pensez à modifier les valeurs des variables dans le fichier main.auto.tfvars ainsi que le fichier providers.tf
Vous aurez besoin de spécifier une Key pour la création de la machine, si vous n’en avez pas encore, vous pouvez en générer une sur la console AWS, au travers de EC2 / (Key Pairs)
L’EC2 créée sert de runner gitlab-ci, et est automatiquement ajoutée en tant que runner actif à votre projet via les commandes passées au démarrage de la machine (grâce au bloc user_data).
Pensez à bien récupérer le registration-token sur votre projet Gitlab, dans settings/ci_cd#js-runners-settings
Si vous souhaitez le faire à la main :
sudo apt update
sudo curl -L --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64
sudo chmod +x /usr/local/bin/gitlab-runner
sudo useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash
sudo gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner
sudo gitlab-runner start
sudo gitlab-runner register --non-interactive --url https://gitlab.com/ --registration-token 0123456798azerty --executor docker+machine --docker-image registry.gitlab.com/gitlab-org/cloud-deploy/aws-base:latest --description "runner" --tag-list "docker,aws" --run-untagged="true" --locked="false" --access-level="not_protected"
Si vous n’avez pas Terraform d’installé
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add –
sudo apt-add-repository "deb [arch=$(dpkg --print-architecture)] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
sudo apt install terraform
Vous avez aussi besoin d’AWS CLI
apt install awscli
Puis de configurer un profil AWS ayant les droits nécessaires au déploiement
aws configure
Si vous avez bien tout configuré, vous pouvez passer au déploiement de l’infra
Depuis le dossier Terraform
terraform init
terraform apply
Après quelques minutes, l’infra devrait être complètement déployée et fonctionnelle.
Git
Si ce n’est déjà fait, vous pouvez déposer le dossier build dans votre dépôt git.
Désactivez les Shared runners dans les paramètres d'Intégration et livraison continue pour éviter d'être bloqué en mode docker+machine (ce qui empechera l'utilisation du role IAM)
Puis à la racine, créez un fichier .gitlab-ci.yml
image: registry.gitlab.com/gitlab-org/cloud-deploy/aws-base:latest
variables:
GIT_SUBMODULE_STRATEGY: recursive
AWS_DEFAULT_REGION: eu-west-3
BUCKET_NAME: le_nom_de_votre_bucket
CLOUDFRONT_ID : id_du_cloudfont
deploy:
stage: deploy
script:
- aws --region $AWS_DEFAULT_REGION s3 sync ./build s3://$BUCKET_NAME/site --delete
- aws --region $AWS_DEFAULT_REGION cloudfront create-invalidation --distribution-id $CLOUDFRONT_ID --paths "/*"
when: manual
only:
- main
Vous pouvez lancer le pipeline créé via le menu Intégration et livraison continue
Si tout se passe bien, le contenu du dossier build devrait être poussé sur le bucket S3, puis une invalidation du Cloudfront devrait se lancer pour rafraichir le cache, et ainsi voir le site publié.
Azure-Devops
Si vous ne voulez pas utiliser gitlab, vous pouvez utiliser d’autres gestionnaires de CI/CD, comme Azure-DevOps par exemple.
Vous pouvez réutiliser le runner créé précédemment (en installant l'agent sur la machine), ou bien en passant par les runner Microsoft.
Vous avez accès gratuitement à des runners grace à l'offre Free tier (1 parallel job up to 1800 mins/mo), mais vous êtes obligé de créer des credentials IAM.
Vous aurez besoin d'installer l'extension AWS Toolkit for Azure DevOps depuis la marketplace.
Pour renseigner les Access Key et Secret Key AWS (pensez bien aux droits nécessaires, vous pouvez reprendre la policy décrite dans le terraform), ajouter les valeurs dans la section Service connections des paramètres de votre projet Azure DevOps.
Créez un nouveau pipeline qui servira à builder le site puis pousser les données sur le bucket S3 et enfin créer l'invalidation Cloudfront.
trigger:
- main
stages:
- stage: Build
jobs:
- job: Build
pool:
vmImage: "ubuntu-latest"
steps:
- task: NodeTool@0
inputs:
versionSpec: '14.x'
checkLatest: true
displayName: "Install Node.js"
- script: |
yarn
yarn build
displayName: "yarn and yarn build"
workingDirectory: "docusaurus/"
- task: CopyFiles@2
inputs:
SourceFolder: "docusaurus/build"
Contents: "**"
TargetFolder: "$(Build.ArtifactStagingDirectory)"
- task: PublishBuildArtifacts@1
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
ArtifactName: 'site'
publishLocation: 'Container'
- stage: Deployment
displayName: Deploy to S3
dependsOn: Build
condition: succeeded()
jobs:
- deployment:
pool:
vmImage: "ubuntu-latest"
environment: prod
strategy:
runOnce:
deploy:
steps:
- task: S3Upload@1
inputs:
awsCredentials: 'YOUR_AWS_SERVICE_CONNECTION'
regionName: 'YOUR_AWS_REGION_NAME'
bucketName: 'YOUR_BUCKET_NAME'
sourceFolder: '$(Pipeline.Workspace)'
globExpressions: '**'
keyManagement: 'awsManaged'
encryptionAlgorithm: 'AES256'
- task: AWSCLI@1
inputs:
awsCredentials: "YOUR_AWS_SERVICE_CONNECTION"
regionName: 'YOUR_AWS_REGION_NAME'
awsCommand: "cloudfront"
awsSubCommand: "create-invalidation"
awsArguments: '--distribution-id YOUR_DISTRIBUTION_ID --paths "/*"'
displayName: "Invalidate CloudFront Cache"
Pensez à renseigner le fichier avec vos valeurs !
Mises à jour du contenu
Pour éditer ou ajouter du contenu, vous avez juste à mettre à jour les fichiers du dossier de votre projet docusaurus, puis relancer un build
- npm
- yarn
npm run build
yarn run build
Enfin vous pouvez relancer votre pipeline gitlab afin de déployer les changements en live
Mises à jour docusaurus
Pour mettre à jour la version de docusaurus, vous pouvez suivre la documentation officielle
Mettre à jour la version dans le fichier package.json
"dependencies": {
"@docusaurus/core": "^2.0.0-beta.9",
"@docusaurus/preset-classic": "^2.0.0-beta.9",
// ...
}
Puis lancez la commande
- npm
- yarn
npm install
yarn install
Puis pour vérifier que la mise à jour s'est bien été effectuée
- npm
- yarn
npx docusaurus --version
npx docusaurus --version
Conclusion
Comme vous avez pu le voir, la mise en place d'un site statique sur une infra managée est assez simple.
La gestion du site est réduite au minimum, il faut juste penser de temps en temps à mettre à jour l'outil pour profiter des corrections des failles de sécurité ainsi que des améliorations apportées au fil des mises à jour de docusaurus.