Reprend l'amorce de la PR 164 et l'intègre à la stack : service `garage` (dxflrs/garage v2.4.1, `--single-node --default-bucket`) dans docker-compose.yml, garage.toml versionné sans secret, ports sur 127.0.0.1 décalés par environnement dans provision-host.sh, garde des six clés GARAGE_* dans le Makefile, cible Prometheus avec jeton, tests de fumée déplacés dans tests/garage et joués par le job compose d'infra.yml contre le vrai conteneur, SSE-C compris. Variables APP_S3_* et APP_READING_RETENTION_DAYS posées sur airflow-scheduler pour le DAG `retention`. ADR 0019. Closes #24
141 lines
5.4 KiB
YAML
141 lines
5.4 KiB
YAML
name: Infra
|
|
|
|
# Pourquoi : rien de ce qui décrit l'infrastructure ne s'exécute avant le déploiement. Terraform est
|
|
# resté cassé sans que rien ne le dise, faute de job qui le joue : ce workflow n'applique rien, il
|
|
# vérifie le Terraform, les fichiers Compose et les workflows eux-mêmes - jobs terraform, compose,
|
|
# workflows. ci.yml choisit par ses entrées ceux qui tournent (ADR 0014).
|
|
# Piège : la boucle Terraform parcourt `environments/*`, pour qu'une racine ajoutée soit couverte
|
|
# sans toucher à ce fichier.
|
|
|
|
on:
|
|
workflow_call:
|
|
inputs:
|
|
terraform:
|
|
type: boolean
|
|
default: false
|
|
compose:
|
|
type: boolean
|
|
default: false
|
|
workflows:
|
|
type: boolean
|
|
default: false
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
terraform:
|
|
name: Formatage et validation Terraform
|
|
if: inputs.terraform
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 10
|
|
|
|
steps:
|
|
- name: Récupère le dépôt
|
|
uses: actions/checkout@v7
|
|
|
|
# Action tierce, épinglée sur le commit du tag (règle Sonar githubactions:S7637).
|
|
- name: Installe Terraform
|
|
uses: hashicorp/setup-terraform@dfe3c3f87815947d99a8997f908cb6525fc44e9e # v4.0.1
|
|
with:
|
|
terraform_version: 1.16.3
|
|
terraform_wrapper: false
|
|
|
|
- name: Vérifie le formatage
|
|
run: terraform fmt -check -recursive infra/terraform
|
|
|
|
- name: Valide chaque racine
|
|
run: |
|
|
for racine in infra/terraform/environments/*/; do
|
|
echo "::group::${racine}"
|
|
terraform -chdir="${racine}" init -backend=false -input=false
|
|
terraform -chdir="${racine}" validate
|
|
echo "::endgroup::"
|
|
done
|
|
|
|
compose:
|
|
name: Validation des fichiers Compose et de la supervision
|
|
if: inputs.compose
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 10
|
|
|
|
steps:
|
|
- name: Récupère le dépôt
|
|
uses: actions/checkout@v7
|
|
|
|
# Compose interpole tout le fichier : les `:?` exigent une valeur, pas un vrai secret.
|
|
- name: Prépare un .env d'exemple
|
|
run: cp .env.example .env
|
|
|
|
# Garage refuse un rpc_secret qui n'est pas 32 octets hexadécimaux : `change_me` ne suffit pas.
|
|
- name: Génère les secrets Garage du .env
|
|
run: |
|
|
sed -i -e "s|^GARAGE_RPC_SECRET=.*|GARAGE_RPC_SECRET=$(openssl rand -hex 32)|" \
|
|
-e "s|^GARAGE_ADMIN_TOKEN=.*|GARAGE_ADMIN_TOKEN=$(openssl rand -hex 32)|" \
|
|
-e "s|^GARAGE_METRICS_TOKEN=.*|GARAGE_METRICS_TOKEN=$(openssl rand -hex 32)|" \
|
|
-e "s|^GARAGE_ACCESS_KEY=.*|GARAGE_ACCESS_KEY=GK$(openssl rand -hex 12)|" \
|
|
-e "s|^GARAGE_SECRET_KEY=.*|GARAGE_SECRET_KEY=$(openssl rand -hex 32)|" \
|
|
-e "s|^GARAGE_SSE_KEY=.*|GARAGE_SSE_KEY=$(openssl rand -base64 32)|" .env
|
|
|
|
- name: Valide la stack de développement
|
|
run: docker compose config --quiet
|
|
|
|
- name: Valide la stack déployée, profils compris
|
|
run: docker compose -f docker-compose.yml -f docker-compose.prod.yml --profile acme --profile monitoring --profile load config --quiet
|
|
|
|
- name: Valide le frontal SNI de la VM
|
|
run: |
|
|
docker compose -f infra/front/compose.yml config --quiet
|
|
docker run --rm -v "$PWD/infra/front/nginx.conf:/etc/nginx/nginx.conf:ro" nginx:1.31-alpine nginx -t
|
|
|
|
# Mêmes commandes que `make monitoring-check` : images et montages viennent du fichier Compose.
|
|
- name: Valide la configuration de Prometheus et ses règles
|
|
run: docker compose --profile monitoring run --rm --no-deps --entrypoint promtool prometheus check config /etc/prometheus/prometheus.yml
|
|
|
|
- name: Joue les tests unitaires des règles d'alerte
|
|
run: docker compose --profile monitoring run --rm --no-deps --entrypoint promtool prometheus test rules /etc/prometheus/tests/enervision.test.yml
|
|
|
|
- name: Valide la configuration d'Alertmanager
|
|
run: docker compose --profile monitoring run --rm --no-deps --entrypoint amtool alertmanager check-config /etc/alertmanager/alertmanager.yml
|
|
|
|
- name: Valide les tableaux de bord Grafana
|
|
run: for tableau in monitoring/grafana/dashboards/*.json; do jq empty "$tableau"; done
|
|
|
|
# Action tierce, épinglée sur le commit du tag (règle Sonar githubactions:S7637).
|
|
- name: Installe uv
|
|
uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
|
|
with:
|
|
enable-cache: false
|
|
|
|
# Même image et même healthcheck qu'en prod : `--wait` ne rend la main qu'une fois le S3 prêt.
|
|
- name: Démarre Garage
|
|
run: docker compose up -d --wait --wait-timeout 120 garage
|
|
|
|
- name: Fumée S3 sur Garage, SSE-C compris
|
|
run: |
|
|
set -a; . ./.env; set +a
|
|
uvx --with boto3==1.43.101 pytest==9.1.1 tests/garage -q
|
|
|
|
- name: Journaux de Garage en cas d'échec
|
|
if: failure()
|
|
run: docker compose logs --tail=100 garage
|
|
|
|
- name: Arrête Garage
|
|
if: always()
|
|
run: docker compose down --volumes
|
|
|
|
workflows:
|
|
name: Analyse des workflows
|
|
if: inputs.workflows
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 10
|
|
|
|
steps:
|
|
- name: Récupère le dépôt
|
|
uses: actions/checkout@v7
|
|
|
|
# Image épinglée par tag, comme les images des fichiers Compose. Elle embarque shellcheck,
|
|
# qui analyse aussi les blocs `run:`.
|
|
- name: actionlint
|
|
run: docker run --rm -v "$PWD:/repo" --workdir /repo rhysd/actionlint:1.7.12 -color
|