Aller au contenu

Infrastructure Azure

Souscription AI Intelligence Management, resource group rg-aim-prod, région westeurope. Tout est décrit en Bicep dans infra/.

Topologie

Une seule application est accessible depuis Internet ; tout le reste vit derrière elle.

flowchart TD
    NET([Internet]) -->|HTTPS| CA[ca-aim-api<br/>Container App]
    CA -.identité managée.-> ACR[acraim…<br/>Container Registry]
    CA --> PG[(pg-aim-…<br/>PostgreSQL Flexible)]
    CA --> ST[(staim…<br/>Blob Storage)]
    CA --> KV[kv-aim-…<br/>Key Vault]
    CA --> LOG[log-aim<br/>Log Analytics]
    subgraph vnet["vnet-aim — 10.20.0.0/16"]
        SNA["snet-aca<br/>10.20.0.0/23"]
        SNP["snet-pg<br/>10.20.4.0/28"]
    end
    CA -.- SNA
    PG -.- SNP

Les onze ressources

Ressource Nom Rôle
Container App ca-aim-api API + MCP, 0,5 vCPU / 1 Gio, 1 à 3 réplicas
Environnement cae-aim Intégré au réseau virtuel
PostgreSQL Flexible pg-aim-… B1ms burstable, 32 Gio, accès public désactivé
Réseau virtuel vnet-aim Deux sous-réseaux délégués
Zone DNS privée pg-aim-….private.postgres.database.azure.com Résolution de la base
Lien DNS link-vnet-aim Rattache la zone au réseau
Container Registry acraim… Basic, sans compte d'administration
Storage staim… LRS, allowSharedKeyAccess: false
Key Vault kv-aim-… RBAC, pas de politiques d'accès
Identité managée id-aim Porte tous les droits de l'application
Log Analytics log-aim Rétention 30 jours

Réseau

PostgreSQL vit dans snet-pg, délégué à Microsoft.DBforPostgreSQL/flexibleServers, sans adresse publique. La zone DNS privée est indispensable : sans elle, le nom du serveur ne se résout pas depuis le réseau virtuel et l'application ne trouve jamais sa base.

Container Apps occupe snet-aca, un /23 — le minimum exigé pour son infrastructure.

Identité et secrets

L'identité managée id-aim porte trois attributions :

Rôle Portée
AcrPull Le registre
Storage Blob Data Contributor Le compte de stockage
Key Vault Secrets User Le coffre

Conséquence : aucune clé de service n'existe nulle part. Le registre n'a pas de compte d'administration, le stockage refuse l'authentification par clé partagée, et le coffre est en RBAC.

Deux secrets subsistent, portés par la Container App et copiés dans Key Vault : le DSN PostgreSQL complet et la clé d'API Anthropic.

Déploiement en deux temps

Container Apps refuse de créer une révision dont l'image n'existe pas encore. D'où deux déploiements Bicep :

  1. infra/registry.bicep — le registre seul.
  2. az acr build --platform linux/amd64 — construction dans le cloud. La machine de développement est arm64 ; une image construite localement ne démarrerait pas.
  3. infra/main.bicep — le reste.

scripts/deploy.sh enchaîne les trois. Voir Déployer.

Deux détails qui ont coûté du temps

Le tag d'image doit changer à chaque build

Avec un tag fixe, Container Apps voit un modèle de révision identique, ne crée aucune révision, et le déploiement « réussit » sans que le nouveau code ne tourne. Le tag dérive désormais du SHA git, et le script vérifie l'image réellement servie avant de déclarer le succès.

Le nom d'hôte public doit être déclaré au MCP

Le SDK MCP protège contre le DNS rebinding en n'acceptant par défaut que des hôtes locaux. Derrière une ingress publique, tout est rejeté en 421. CONTAINER_APP_HOSTNAME n'existe pas ; le FQDN est calculé en Bicep depuis le domaine par défaut de l'environnement, créé avant l'application.

Environnements

Usage
Azure rg-aim-prod Recette utilisateur et usage réel
Docker Compose Développement et tests automatisés uniquement

Il n'existe pas encore d'environnement de développement séparé sur Azure. Tant que l'usage reste individuel, c'est un compromis assumé ; il faudra un rg-aim-dev dès que plusieurs personnes modifieront le code.