Mise en place
Comment tout installer depuis zéro : les ressources Google Cloud, la configuration des machines par Ansible, puis le premier compte administrateur.
Prérequis
- Google Cloud CLI (
gcloud), connecté au projettimemanager-eh28; - Ansible (le paquet complet, avec la collection
community.general) ; - une clé SSH ajoutée aux métadonnées du projet ;
- le mot de passe du vault Ansible.
1. Créer l'infrastructure (une seule fois)
# Compte de service sans aucun rôle, attaché aux VM
gcloud iam service-accounts create tm-nodes --display-name="Time Manager nodes"
# Pare-feu
gcloud compute firewall-rules delete default-allow-rdp --quiet
gcloud compute firewall-rules create tm-allow-web \
--network=default --allow=tcp:80,tcp:443 \
--source-ranges=0.0.0.0/0 --target-tags=web
# IP statiques
gcloud compute addresses create tm-prod-ip tm-tooling-ip --region=europe-west1
# VM
gcloud compute instances create tm-prod \
--zone=europe-west1-b --machine-type=e2-medium \
--image-family=ubuntu-2404-lts-amd64 --image-project=ubuntu-os-cloud \
--boot-disk-size=30GB --boot-disk-type=pd-balanced \
--address=tm-prod-ip --tags=web \
--service-account=tm-nodes@timemanager-eh28.iam.gserviceaccount.com --scopes=cloud-platform \
--shielded-secure-boot --shielded-vtpm --shielded-integrity-monitoring
gcloud compute instances create tm-tooling \
--zone=europe-west1-b --machine-type=e2-standard-2 \
--image-family=ubuntu-2404-lts-amd64 --image-project=ubuntu-os-cloud \
--boot-disk-size=50GB --boot-disk-type=pd-balanced \
--address=tm-tooling-ip \
--service-account=tm-nodes@timemanager-eh28.iam.gserviceaccount.com --scopes=cloud-platform \
--shielded-secure-boot --shielded-vtpm --shielded-integrity-monitoring| Commande | Ce qu'elle fait |
|---|---|
iam service-accounts create tm-nodes | Un compte de service sans aucun droit, à la place du compte par défaut qui peut tout modifier dans le projet |
firewall-rules delete default-allow-rdp | Retire l'accès au bureau à distance Windows, inutile sous Linux |
firewall-rules create tm-allow-web | Ouvre 80 et 443, uniquement pour les VM avec le tag web |
addresses create | Deux IP fixes, qui ne changent pas quand on arrête une VM |
instances create | Les deux VM, avec Shielded VM (démarrage sécurisé, vTPM, contrôle d'intégrité) |
Seule tm-prod reçoit le tag web : tm-tooling n'a aucun port web ouvert.
2. Remplir l'inventaire
Mettre les IP publiques et internes dans ansible/inventory.ini, puis enregistrer les empreintes SSH des serveurs (Ansible les vérifie, host_key_checking = True) :
ssh-keyscan -t ed25519 <ip-prod> <ip-tooling> >> ~/.ssh/known_hostsFaire pointer les enregistrements DNS time, api et ci vers l'IP statique de tm-prod, chez Hostinger. Voir Infrastructure.
3. Configurer les machines
cd timemanager-devops/ansible
ansible all -m ping --ask-vault-pass
ansible-playbook playbook.yml --ask-vault-passansible all -m ping vérifie qu'Ansible joint bien les deux machines. Le playbook installe ensuite tout : paquets, Docker, pare-feu, Traefik, l'application et Jenkins.
Il est idempotent : le relancer ne change que ce qui diffère de l'état attendu.
4. Premier déploiement
Les images n'existent pas encore sur GHCR la toute première fois. Ouvrir ci.time.jostud.com et lancer Build Now sur les deux jobs : ils construisent, publient et déploient le site et l'API. Voir Accéder aux pipelines.
5. Créer le premier administrateur
La production ne lance jamais les données de démonstration. Le premier general manager est créé une seule fois, à travers la release, avec des identifiants tapés au clavier :
ssh <admin>@<ip-prod>
read -r -p "Email: " ADMIN_EMAIL
read -r -s -p "Password: " ADMIN_PASSWORD; echo
export ADMIN_EMAIL ADMIN_PASSWORD
docker exec -e ADMIN_EMAIL -e ADMIN_PASSWORD timemanager-back /app/bin/timemanager eval \
'Application.load(:timemanager); Ecto.Migrator.with_repo(Timemanager.Repo, fn _ -> Code.eval_file(Application.app_dir(:timemanager, "priv/repo/seeds.exs")) end)'
unset ADMIN_EMAIL ADMIN_PASSWORD| Ligne | Pourquoi |
|---|---|
read -r -s | Le mot de passe est tapé sans s'afficher, et n'est jamais écrit dans l'historique du shell |
docker exec -e ... | Les identifiants sont passés au conteneur comme variables, pas dans la commande elle-même |
bin/timemanager eval | Exécute le fichier de seeds à l'intérieur de la release, avec la connexion à la base |
unset | Efface les identifiants de la session |
Une commande à la fois
Lance les commandes une par une. Si on colle tout d'un coup, une ligne collée peut être lue par read à la place du mot de passe tapé.
Ce general manager invite ensuite les autres comptes depuis l'application.