Aller au contenu

Utiliser envsubst pour vos configs dynamiques

Mise à jour :

La commande envsubst permet de remplacer dynamiquement des variables d’environnement dans un texte. Elle est particulièrement utile dans les contextes DevOps, où les fichiers de configuration doivent s’adapter à différents environnements sans être recréés à chaque fois.

envsubst fait partie du paquet GNU gettext, principalement utilisé pour l’internationalisation des logiciels, mais cette commande en particulier sert surtout à injecter des valeurs dynamiques dans des fichiers texte à partir des variables d’environnement du shell.

Prenons un exemple simple :

Terminal window
export NOM_SITE="mon-super-site.fr"
echo "Bienvenue sur \$NOM_SITE" | envsubst
Bienvenue sur mon-super-site.fr

Cela peut sembler basique, mais dans un contexte réel — comme la génération de fichiers de configuration comme nginx.conf, docker-compose.yml ou des manifestes Kubernetes — envsubst devient un outil clé pour automatiser les déploiements.

Avantages principaux :

  • Facile à intégrer dans des scripts shell ou des pipelines CI/CD.
  • Aucune dépendance externe (présent dans gettext, souvent préinstallé).
  • Permet de gérer des modèles de configuration dynamiques sans outils complexes.

C’est une solution légère, rapide et efficace pour tous les administrateurs systèmes et développeurs qui veulent automatiser la configuration sans passer par des outils de templating lourds.

Syntaxe de base et options disponibles

La commande envsubst possède une syntaxe simple et directe, conçue pour remplacer les variables d’environnement dans une entrée texte, généralement un fichier ou un flux standard.

Syntaxe générale

Terminal window
envsubst [OPTION] [SHELL-FORMAT]

Par défaut, envsubst lit l’entrée depuis stdin (entrée standard) et écrit le résultat sur stdout (sortie standard).

Exemple minimal

Terminal window
export HOSTNAME=serveur01
echo "Nom d'hôte : \$HOSTNAME" | envsubst
Nom d'hôte : serveur01

Format SHELL-FORMAT

L’argument [SHELL-FORMAT] permet de limiter les substitutions aux variables spécifiées :

Terminal window
envsubst '$USER $HOME' < input.txt

Cela permet d’éviter que certaines variables non voulues soient remplacées.

Utilisation simple avec des fichiers de configuration

L’usage typique de envsubst concerne la génération de fichiers de configuration dynamiques à partir de modèles contenant des variables d’environnement.

Étape 1 : Créer un fichier modèle

Ce fichier, souvent avec une extension comme .template, contient des variables sous forme $VAR ou ${VAR} :

Terminal window
# config.template
server {
listen 80;
server_name $SERVER_NAME;
root /var/www/$SITE_DIR;
}

Étape 2 : Définir les variables d’environnement

Dans votre terminal ou script :

Terminal window
export SERVER_NAME=example.com
export SITE_DIR=html

Étape 3 : Générer le fichier final

Utilisez la commande envsubst pour produire un fichier prêt à l’emploi :

Terminal window
envsubst < config.template > config.conf

Le contenu du fichier config.conf :

server {
listen 80;
server_name example.com;
root /var/www/html;
}

Cette méthode est idéale pour automatiser la configuration de serveurs web (nginx, Apache), services Docker ou applications Node.js, sans dupliquer les fichiers selon les environnements. Grâce à envsubst, un seul template suffit : ce sont les variables exportées qui font toute la différence.

Substitution sélective avec SHELL-FORMAT

Par défaut, envsubst remplace toutes les variables d’environnement présentes dans le fichier ou le texte. Mais dans certains cas, vous ne souhaitez substituer que certaines variables spécifiques. C’est là qu’intervient l’argument SHELL-FORMAT.

Syntaxe avec SHELL-FORMAT

Terminal window
envsubst '$VAR1 $VAR2' < input.template > output.conf

Seules $VAR1 et $VAR2 seront remplacées, les autres resteront inchangées.

Exemple concret :

  • Fichier db.template :
DB_HOST=$DB_HOST
DB_USER=$DB_USER
DB_PASS=$DB_PASS
DB_PORT=$DB_PORT
  • Variables d’environnement définies :
Terminal window
export DB_HOST=db.local
export DB_USER=admin
export DB_HOST=db.local
export DB_USER=admin
  • Commande :
Terminal window
envsubst '$DB_HOST $DB_USER' < db.template > db.conf
  • Résultat :
DB_HOST=db.local
DB_USER=admin
DB_PASS=$DB_PASS
DB_PORT=$DB_PORT

Les variables non listées dans le SHELL-FORMAT ($DB_PASS et $DB_PORT) sont laissées intactes.

Cette fonctionnalité permet une plus grande maîtrise lors de la substitution, surtout quand :

  • plusieurs outils manipulent le même fichier modèle.
  • certaines variables doivent être définies plus tard ou par un autre processus.
  • on souhaite éviter de remplacer accidentellement des variables critiques.

Intégration dans des pipelines CI/CD

La commande envsubst s’intègre parfaitement dans les pipelines de déploiement CI/CD, car elle permet de générer à la volée des fichiers de configuration adaptés à l’environnement cible (développement, staging, production…).

Exemple avec un manifeste Kubernetes :

  • Fichier deployment.yaml.template :
apiVersion: apps/v1
kind: Deployment
metadata:
name: $APP_NAME
spec:
replicas: $REPLICAS
template:
spec:
containers:
- name: $APP_NAME
image: $IMAGE_NAME
  • Variables exportées dans le pipeline :
Terminal window
export APP_NAME=mon-app
export REPLICAS=3
export IMAGE_NAME=registry.example.com/mon-app:latest
  • Intégration dans un pipeline Github :
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Generate deployment file
run: |
envsubst < .k8s/deployment.yaml.template > deployment.yaml
kubectl apply -f deployment.yaml
  • Intégration dans GitLab CI/CD :
deploy:
script:
- envsubst < .k8s/deployment.tpl.yaml > deployment.yaml
- kubectl apply -f deployment.yaml

Cette commande remplace les variables, puis transmet le résultat à kubectl.

Cas d’usage courants

  • Génération de fichiers docker-compose.yml
  • Configuration automatique d’applications Node.js, Python, PHP
  • Déploiement via Ansible ou Terraform avec des modèles simples

Avec envsubst, vos pipelines deviennent plus souples et moins dépendants de fichiers statiques, vous permettant de gérer facilement différents environnements sans duplicata de configuration.

Bonnes pratiques et précautions

L’utilisation de envsubst peut sembler triviale, mais quelques erreurs courantes peuvent causer des comportements inattendus. Voici les bonnes pratiques à suivre pour éviter les pièges les plus fréquents.

Utilisez des guillemets simples autour des variables

Lorsque vous passez des variables à envsubst, utilisez des guillemets simples (') pour empêcher leur expansion prématurée par le shell.

Terminal window
# Correct
envsubst '$DB_USER $DB_PASS'
# Incorrect : le shell remplace déjà les variables
envsubst "$DB_USER $DB_PASS"

2. Exportez toutes les variables nécessaires

envsubst ne remplace que les variables déjà exportées. Si une variable n’est pas exportée, elle ne sera pas substituée.

Terminal window
export API_KEY=abc123
envsubst '$API_KEY' < config.template > config.yaml

Sans export, la variable restera vide dans le fichier final.

3. Gérez les variables non définies

Si une variable mentionnée dans le template n’est pas définie, envsubst la remplacera par une chaîne vide, ce qui peut casser un fichier de configuration :

Terminal window
# config.template
api_key=$API_KEY
# Résultat si API_KEY n’est pas définie
api_key=

Utilisez des valeurs par défaut en Bash :

Terminal window
export API_KEY=${API_KEY:-defaultkey}

Ou vérifiez explicitement la présence des variables :

Terminal window
: "${API_KEY:?Variable API_KEY non définie}"

4. Vérifiez le résultat

Avant d’appliquer une configuration générée, affichez-la dans le terminal :

Terminal window
envsubst < config.template

Ou validez le fichier via des outils comme nginx -t, kubectl apply --dry-run=client, etc.

Respecter ces bonnes pratiques garantit une utilisation fiable et prévisible de envsubst, notamment dans des scripts automatisés où chaque détail compte.

Alternatives et limites de envsubst

Bien que envsubst soit léger et pratique, il présente aussi des limites qui peuvent le rendre insuffisant pour certains cas d’usage avancés. Connaître ses alternatives permet de choisir l’outil le mieux adapté selon vos besoins.

Limitations de envsubst

  • Pas de logique conditionnelle : impossible d’ajouter des blocs if, else, ou de tester la présence de variables.
  • Pas de boucles : on ne peut pas générer dynamiquement des sections répétitives.
  • Pas de gestion d’erreurs native : aucune alerte si une variable est absente ou vide.
  • Remplacement simple uniquement : pas de support pour les fonctions ou les transformations de variables.

Alternatives plus puissantes

  1. Jinja2 (Python)

Permet d’utiliser une syntaxe expressive avec des conditions, boucles, et filtres :

{% if DEBUG %}
debug = true
{% endif %}

Idéal pour les projets complexes, souvent utilisé avec des templates Ansible ou dans des scripts Python.

  1. envplate (Go)

Utilitaire très rapide et conçu pour les containers Docker. Il peut injecter les variables dans plusieurs fichiers.

https://github.com/kreuzwerker/envplate

  1. mustache / handlebars (JavaScript)

Systèmes de templating simples, orientés substitution de données JSON dans des fichiers modèles. Disponibles dans de nombreux langages.

  1. gomplate (Go)

Plus avancé que envsubst, avec des fonctions intégrées, des sources multiples (fichiers, API, Vault…), et des conditions.

https://github.com/hairyhenderson/gomplate

Conclusion : utilisez envsubst pour des substitutions simples et rapides dans vos fichiers de configuration. Mais pour des besoins plus dynamiques ou structurés, tournez-vous vers Jinja2, gomplate ou d’autres moteurs de templates adaptés aux workflows DevOps modernes.

Conclusion

Comme vous l’aurez compris, envsubst se distingue par sa simplicité et son efficacité pour la génération dynamique de fichiers de configuration. Facile à intégrer dans un shell ou un pipeline CI/CD, il répond parfaitement aux besoins des administrateurs système et des développeurs cherchant à automatiser sans complexifier. Pour aller plus loin, d’autres outils existent, mais envsubst reste une valeur sûre dans la boîte à outil DevOps.