📍 Article principal du cluster : HashiCorp Consul Associate (003) — guide pratique de la certification 2026
Ce tutoriel fait partie du cluster certification Consul Associate. Pour la vue d’ensemble, lisez d’abord le pilier.
Introduction
Le service mesh est la fonctionnalité la plus différenciante de Consul face à un simple service registry. Il introduit un sidecar Envoy à côté de chaque service applicatif, négocie automatiquement le mTLS entre sidecars, applique des règles d’autorisation appelées « intentions » et expose des métriques riches sur tout le trafic est-ouest. Pour la certification Consul Associate, les domaines 5 et 8 du syllabus couvrent exactement cette couche : architecture du mesh, intentions L4 et L7, terminating et ingress gateways, et communication entre datacenters. Ce tutoriel monte un mesh fonctionnel entre les services `api-orders` et `web-frontend` enregistrés dans le tutoriel précédent, écrit une intention L4 « web-frontend → api-orders : allow », puis monte une intention L7 plus fine basée sur les chemins HTTP. Tous les exercices sont compatibles examen 003 ciblant Consul 1.15 mais utilisent Consul 1.20 pour profiter des dernières améliorations Envoy.
Prérequis
- Cluster Consul fonctionnel avec services enregistrés issu des deux tutoriels précédents
- Envoy 1.30+ disponible sur les conteneurs clients (installation rapide pendant le tuto)
- Notions de base TLS et certificats X.509
- 45 minutes de temps
Étape 1 — Activer Connect côté serveurs
Connect est le composant de Consul qui gère le service mesh. Il s’active dans la configuration des serveurs via le bloc `connect`. Cette activation crée automatiquement une autorité de certification interne (Connect CA) qui émet des certificats X.509 pour chaque service du mesh — chaque sidecar reçoit son propre certificat avec une SAN URI au format `spiffe://CLUSTER_ID.consul/ns/default/dc/dc1/svc/SERVICE_NAME`.
for srv in consul-srv-1 consul-srv-2 consul-srv-3; do
incus exec $srv -- bash -c "cat >> /etc/consul.d/consul.hcl <<EOF
connect {
enabled = true
}
ports {
grpc = 8502
grpc_tls = 8503
}
EOF"
incus exec $srv -- systemctl restart consul
done
sleep 10
incus exec consul-srv-1 -- consul members
incus exec consul-srv-1 -- consul connect ca get-config | jq .
La sortie de `consul connect ca get-config` doit afficher la configuration de l’autorité interne (provider `consul` par défaut, RootCertTTL généralement 87600 heures soit 10 ans). En production, on remplace souvent cette CA interne par Vault PKI pour profiter de la rotation automatique et des audits — ce point est documenté en domaine 6b. Pour le labo, la CA Consul intégrée suffit largement.
Étape 2 — Installer Envoy sur les clients
Le sidecar utilisé par Consul Connect est Envoy. Consul fournit un binaire `consul connect envoy` qui démarre une instance Envoy correctement configurée pour parler à l’agent client local en gRPC et récupérer les certificats du mesh. Sur les conteneurs clients, on installe Envoy 1.30+ depuis le dépôt officiel.
for cli in consul-cli-1 consul-cli-2; do
incus exec $cli -- bash -c "
apt update && apt install -y curl gnupg lsb-release
curl -sL 'https://deb.dl.getenvoy.io/public/gpg.8115BA8E629CC074.key' | gpg --dearmor -o /usr/share/keyrings/getenvoy.gpg
echo \"deb [signed-by=/usr/share/keyrings/getenvoy.gpg] https://deb.dl.getenvoy.io/public/deb/ubuntu \$(lsb_release -cs) main\" > /etc/apt/sources.list.d/getenvoy.list
apt update && apt install -y getenvoy-envoy
envoy --version
"
done
Vous devez voir `envoy version: 1.30.x` ou supérieur. Si le dépôt getenvoy est indisponible, installez Envoy depuis func-e (`func-e use 1.30.0`) ou compilez-le statiquement. La version d’Envoy doit correspondre à celle supportée par Consul — la matrice de compatibilité est publiée sur la documentation officielle.
Étape 3 — Enregistrer les services en mode Connect
On modifie les définitions de services existantes pour ajouter un bloc `connect` qui demande l’enregistrement automatique d’un sidecar proxy. C’est la transition entre service registry classique et service mesh.
incus exec consul-cli-1 -- bash -c "cat > /etc/consul.d/services/api-orders.hcl <<EOF
service {
name = \"api-orders\"
id = \"api-orders-1\"
port = 8081
tags = [\"v1\"]
check {
id = \"health-check-http\"
name = \"HTTP /health\"
http = \"http://localhost:8081/health\"
interval = \"10s\"
}
connect {
sidecar_service {
port = 21000
}
}
}
EOF"
incus exec consul-cli-1 -- bash -c "cat > /etc/consul.d/services/web-frontend.hcl <<EOF
service {
name = \"web-frontend\"
id = \"web-frontend-1\"
port = 3000
connect {
sidecar_service {
port = 21001
proxy {
upstreams = [
{
destination_name = \"api-orders\"
local_bind_port = 9091
}
]
}
}
}
}
EOF"
incus exec consul-cli-1 -- consul reload
Le bloc `upstreams` est le concept central : web-frontend déclare qu’il a besoin de parler à api-orders, et le sidecar de web-frontend va exposer un port local (9091) qui forwarde le trafic vers le sidecar de api-orders, en mTLS. L’application web-frontend parle simplement à `http://localhost:9091` — elle ignore complètement Consul, le mesh et le mTLS.
Étape 4 — Démarrer les sidecars Envoy
On lance maintenant les sidecars pour les deux services. Chaque sidecar tourne en tant que processus séparé et établit une connexion gRPC avec l’agent Consul local pour récupérer son certificat X.509 et la configuration du mesh.
incus exec consul-cli-1 -- bash -c "
nohup consul connect envoy -sidecar-for api-orders-1 \
-admin-bind 127.0.0.1:19000 \
> /var/log/envoy-api-orders.log 2>&1 &
nohup consul connect envoy -sidecar-for web-frontend-1 \
-admin-bind 127.0.0.1:19001 \
> /var/log/envoy-web-frontend.log 2>&1 &
"
sleep 5
incus exec consul-cli-1 -- ps aux | grep envoy | grep -v grep
incus exec consul-cli-1 -- curl -s http://127.0.0.1:19000/clusters | head -20
Vous devez voir deux processus envoy. La sortie de l’admin endpoint Envoy (`/clusters`) liste les clusters configurés — vous y verrez `api-orders` comme cluster cible. Si Envoy refuse de démarrer avec une erreur sur la résolution du token gRPC, c’est que les ACL Consul sont activées sans token agent — pour ce labo on suppose que les ACL ne sont pas encore activées (elles arrivent dans le tutoriel suivant).
Étape 5 — Tester la connectivité service-à-service via le mesh
Maintenant le moment de vérité. On simule l’application web-frontend qui appelle api-orders, mais en passant par le sidecar local sur le port 9091 plutôt que directement.
# Test direct via le sidecar
incus exec consul-cli-1 -- curl -s http://localhost:9091/orders
# Comparer avec un appel direct hors mesh (doit aussi marcher car pas encore d'intentions)
incus exec consul-cli-1 -- curl -s http://localhost:8081/orders
# Vérifier dans les logs Envoy que le trafic est passé
incus exec consul-cli-1 -- tail -20 /var/log/envoy-api-orders.log
La sortie doit afficher `[« order-1″, »order-2″, »order-3 »]` dans les deux cas. Pour le moment, la communication via le sidecar fonctionne mais aucune règle d’autorisation n’est en place — c’est exactement ce que les intentions vont changer dans la prochaine étape.
Étape 6 — Configurer le default ACL en deny pour les intentions
Par défaut, Consul applique une politique « default-allow » sur les intentions : tout le trafic est-ouest est autorisé sauf interdiction explicite. Pour un service mesh sécurisé, c’est l’inverse qu’on veut : « default-deny », et on autorise explicitement les flux autorisés.
incus exec consul-srv-1 -- bash -c "cat > /tmp/proxy-defaults.hcl <<EOF
Kind = \"proxy-defaults\"
Name = \"global\"
Config {
protocol = \"http\"
}
EOF"
incus exec consul-srv-1 -- consul config write /tmp/proxy-defaults.hcl
incus exec consul-srv-1 -- bash -c "cat > /tmp/service-intentions-default.hcl <<EOF
Kind = \"service-intentions\"
Name = \"*\"
Sources = [
{
Name = \"*\"
Action = \"deny\"
Description = \"Default deny — explicit allow required\"
}
]
EOF"
incus exec consul-srv-1 -- consul config write /tmp/service-intentions-default.hcl
# Tester : le trafic doit maintenant échouer
incus exec consul-cli-1 -- curl -s -o /dev/null -w "%{http_code}\n" http://localhost:9091/orders
La réponse doit être un code HTTP 403 ou la connexion doit être réinitialisée par Envoy — le sidecar refuse maintenant la communication car aucune intention n’autorise web-frontend à parler à api-orders. Ce comportement default-deny est le mode recommandé en production et tombe en domaine 5b.
Étape 7 — Écrire une intention L4 explicite
On rédige maintenant une intention qui autorise spécifiquement web-frontend à appeler api-orders. La couche 4 signifie que l’autorisation est binaire : « source → destination : allow » sans détail sur le contenu HTTP.
incus exec consul-srv-1 -- bash -c "cat > /tmp/intention-web-to-api.hcl <<EOF
Kind = \"service-intentions\"
Name = \"api-orders\"
Sources = [
{
Name = \"web-frontend\"
Action = \"allow\"
}
]
EOF"
incus exec consul-srv-1 -- consul config write /tmp/intention-web-to-api.hcl
# Test : le trafic doit maintenant repasser
sleep 2
incus exec consul-cli-1 -- curl -s http://localhost:9091/orders
La requête doit renvoyer le JSON des commandes. Vous venez d’autoriser un et un seul flux de service à service au sein du mesh, en mTLS, avec une politique default-deny par défaut sur tout le reste. C’est le pattern de sécurité « zero-trust » que les organisations matures appliquent en production.
Étape 8 — Monter en gamme avec une intention L7
Les intentions L4 sont binaires. Les intentions L7 permettent de filtrer sur les chemins HTTP, les méthodes, les headers — bref tout ce qu’un proxy applicatif peut inspecter. Domaine 5c du syllabus.
incus exec consul-srv-1 -- bash -c "cat > /tmp/intention-l7.hcl <<EOF
Kind = \"service-intentions\"
Name = \"api-orders\"
Sources = [
{
Name = \"web-frontend\"
Permissions = [
{
Action = \"allow\"
HTTP {
PathPrefix = \"/orders\"
Methods = [\"GET\"]
}
},
{
Action = \"deny\"
HTTP {
PathPrefix = \"/admin\"
}
}
]
}
]
EOF"
incus exec consul-srv-1 -- consul config write /tmp/intention-l7.hcl
# Test 1 : GET /orders doit passer (200)
incus exec consul-cli-1 -- curl -s -o /dev/null -w "GET /orders => %{http_code}\n" http://localhost:9091/orders
# Test 2 : POST /orders doit être refusé (403)
incus exec consul-cli-1 -- curl -s -o /dev/null -w "POST /orders => %{http_code}\n" -X POST http://localhost:9091/orders
# Test 3 : GET /admin doit être refusé (403)
incus exec consul-cli-1 -- curl -s -o /dev/null -w "GET /admin => %{http_code}\n" http://localhost:9091/admin
Les codes attendus sont respectivement 200, 403, 403. L’intention L7 inspecte la première ligne HTTP avant de relayer le trafic et applique les règles configurées. C’est extrêmement puissant : vous pouvez segmenter finement les permissions sans toucher au code applicatif.
Étape 9 — Vérification finale dans l’UI Consul
L’UI Consul expose un onglet « Intentions » qui visualise toutes les règles actives. Sur `http://localhost:8500/ui/dc1/intentions`, vous voyez la matrice source × destination avec les couleurs allow/deny et les détails L7 quand applicable. C’est l’outil de référence pour auditer l’état du mesh — beaucoup de questions du domaine 5b vous demandent d’interpréter cette matrice mentalement.
Comprendre la différence entre service mesh et API gateway
Une question récurrente en entretien — et indirectement testée dans le syllabus Consul Associate — concerne la distinction entre service mesh et API gateway. Les deux concepts sont proches mais répondent à des problématiques différentes. Une API gateway gère le trafic nord-sud (utilisateur final → backend) avec des préoccupations très spécifiques : authentification utilisateur (OAuth, JWT), rate limiting par client, transformation de requêtes, agrégation de réponses, monétisation des APIs publiques. Un service mesh gère le trafic est-ouest (service interne → service interne) avec des préoccupations différentes : mTLS automatique, intentions de service, observabilité fine du trafic interne, retry et circuit breaker.
Consul propose les deux primitives. Le mesh gère l’est-ouest avec Connect et les intentions, comme vu dans ce tutoriel. Côté nord-sud, Consul expose les ingress gateways (un Envoy frontal qui route le trafic externe vers les services internes du mesh) et les terminating gateways (l’inverse, qui permettent à des services du mesh de parler à des systèmes externes non-mesh). Ces deux types de gateways font partie du domaine 8 du syllabus officiel et il est fréquent qu’une question demande de choisir le bon type pour un cas d’usage donné.
Le rôle de SPIFFE et SPIRE dans Consul Connect
Quand vous démarrez un sidecar Envoy avec Connect, l’agent client local génère un certificat X.509 dont la SAN URI suit le format SPIFFE : `spiffe://
Cette identité SPIFFE est centrale pour les intentions Consul. Quand vous écrivez une intention « web-frontend → api-orders : allow », Consul traduit cela en règles Envoy qui acceptent uniquement les certificats dont la SAN URI matche `spiffe://
Erreurs fréquentes
| Erreur | Cause | Solution |
|---|---|---|
| Sidecar Envoy refuse de démarrer | gRPC port (8502) non activé sur les serveurs | Ajouter `ports.grpc = 8502` et redémarrer les serveurs |
| Intention L7 ignorée — trafic passe en allow | `proxy-defaults.protocol = http` non défini | Écrire le proxy-defaults global avant les intentions L7 |
| Trafic refusé même avec une intention allow | Wildcard `*` source/destination non écrasé correctement | Vérifier l’ordre des règles dans la matrice — l’allow le plus spécifique gagne |
| Certificats Connect expirent rapidement | RootCertTTL trop court | Configurer la CA avec un TTL approprié ou intégrer Vault PKI |
| Latence ajoutée par le sidecar | Mode debug Envoy activé | Démarrer Envoy avec `-loglevel info` et non `-loglevel debug` |
Adaptation au contexte ouest-africain
Pour les équipes plateforme à Abidjan ou Dakar qui opèrent des services PCI-DSS ou bancaires régulés, le mesh Consul offre une voie pragmatique vers la conformité « zero-trust ». Le mTLS automatique entre sidecars satisfait l’exigence de chiffrement en transit pour les flux est-ouest, et les intentions L7 documentent formellement les autorisations service-à-service — ce qui est précieux lors des audits annuels imposés par la BCEAO ou par les régulateurs nationaux. Comptez environ une journée homme pour migrer un service applicatif vers le mesh, et deux à trois semaines pour un parc de 15 services dont les développeurs sont impliqués dans la rédaction des intentions.
Côté infrastructure, le sidecar Envoy ajoute environ 30-50 Mo de RAM par instance et une latence de 2-5 ms par hop. Sur un VPS Hostinger Cloud Startup à 9,99 USD/mois, vous pouvez confortablement opérer 8 à 12 services avec leurs sidecars sur la même instance pour un environnement de test.
Tutoriels frères
- Installer un cluster Consul multi-nœuds Raft sur VPS Hostinger en 2026 (informations vérifiées en avril 2026, susceptibles d’évoluer ; vérifier la source officielle avant toute décision technique)
- Service discovery et health checks Consul
Pour aller plus loin
- 🔝 Retour au pilier : HashiCorp Consul Associate (003) — guide pratique
- Documentation officielle Connect : developer.hashicorp.com/consul/docs/connect
- Référence Service Intentions : developer.hashicorp.com/consul/docs/connect/intentions
- Suggestion suivante : sécuriser le cluster avec ACL en profondeur pour atteindre la maturité production
FAQ
Quelle différence entre intention L4 et L7 ?
L4 autorise ou refuse l’intégralité du trafic d’un service à un autre, sans inspection. L7 inspecte les chemins HTTP, méthodes, et headers pour autoriser ou refuser au cas par cas. L7 demande `protocol = http` configuré au niveau proxy-defaults, alors que L4 fonctionne pour n’importe quel protocole TCP.
Faut-il toujours avoir un sidecar par service ?
Oui dans le mode service mesh classique. Sur Kubernetes, l’alternative Consul Dataplane permet d’avoir un Envoy injecté dans le pod sans agent client — gain de simplicité opérationnelle. Hors k8s, le pattern sidecar reste la norme.
Comment migrer une intention L4 existante vers L7 ?
Définir d’abord `protocol = http` au niveau proxy-defaults, puis écrire la nouvelle intention avec un bloc Permissions au lieu d’Action. Aucune interruption de service si vous appliquez les changements dans l’ordre. La règle implicite est qu’une absence de match conduit à un deny, donc soyez exhaustif dans vos paths.
Mots-clés secondaires : consul connect tutoriel, intentions L7 consul, sidecar envoy mtls, service mesh hashicorp, mesh gateway consul, default deny intentions, certificats spiffe consul