Comment intégrer des variables d'environnement dans NGINX
Comment intégrer des variables d'environnement dans NGINX
Nginx au sein de l'architecture DXP-Cloud
L'infrastructure DXP-Cloud utilise le serveur NGINX comme reverse proxy. Cet outil est largement utilisé dans les projets web. Il permet notamment de définir des règles sur les flux entrant et sortant avant que les flux n'atteignent le serveur Liferay. Les usages les plus courants sont la mise en place de règles de filtrage / redirection. Il est également possible de définir des règles de pare-feu applicatif notamment via le module modSecurity (par exemple pour limiter la taille des requêtes / fichiers envoyés...)
Les contraintes liées à la modification de NGINX
Cependant hormis les variables d'environnement fournies par les équipes Liferay (https://learn.liferay.com/w/liferay-cloud/platform-services/web-server-service#environment-variables), chaque évolution que l'on souhaite apporter sur NGINX requiert une mise à jour des fichiers de configuration et donc un processus de déploiement. On peut choisir un déploiement soit partiel avec le client lcp-deploy
, soit complet avec un build via la CI suivi d'un déploiement complet de la stack. Ces opérations peuvent être assez contraignantes en fonction de la régularité des modifications. Par exemple, prenons le cas où nous avons besoin de gérer une liste d'adresse IP qui seraient autorisées à accéder à une partie spécifique du site. Il n'est pas possible de modifier cette liste sans procéder à un nouveau déploiement de Liferay, ni modifier la liste sans avoir accès au code source du projet. La solution qui semble convenir pour ce cas d'usage est l'utilisation de variables d'environnement.
NGINX et les variables d'environnement
Une fois que l'on a identifié les parties pertinentes à externaliser, il est nécessaire de choisir la méthode pour exploiter ces variables au sein de NGinX. Plusieurs méthodes existent. On peut notamment penser à un mécanisme de fichier template qui permet à NGinX de prendre en compte directement les variables d'environnement. Existe également l'utilisation d'une fonctionnalité basique de linux qui permet la substitution de variables d’environnement directement dans des fichiers (envsubst).
Liferay et les variables d’environnement
Le choix qui a été retenu par Liferay est l'utilisation la fonction envsubst
qui permet de substituer les variables d'environnement directement au sein des fichiers NGinX, avant l’exécution du service. Pour exploiter les variables qui ont été mis à disposition, l'équipe Liferay a mis en place un ensemble de scripts avec notamment le fichier /usr/local/bin/replace-environment-variables.sh
. Ce script procède à la vérification puis à la substitution des variables d'environnement au sein des fichiers de configuration NGinX.
Voici un extrait du script :
check_and_export_webserver_proxy_timeouts
check_and_export_environment_variable PROXY_PASS ${PROXY_ADDRESS}
check_and_export_environment_variable ERROR_LOG_LEVEL "warn"
check_and_export_environment_variable NGINX_STATUS_ACCESS_LOG "off"
check_and_export_environment_variable LCP_WEBSERVER_HSTS "max-age=31536000; includeSubDomains"
check_and_export_environment_variable LCP_WEBSERVER_PROXY_MAX_TEMP_FILE_SIZE "1024m"
check_and_export_environment_variable LCP_WEBSERVER_LOG_ESCAPE "default"
check_and_export_environment_variable LCP_WEBSERVER_LOG_FORMAT "${log_format_parts[*]}"
check_and_export_nginx_modsecurity_mode
check_and_export_modsecurity_rule_engine
export ENVSUBST_ARGS="
\${PROXY_PASS},
\${PROXY_ADDRESS},
\${ERROR_LOG_LEVEL},
\${NGINX_MODSECURITY_MODE},
\${NGINX_STATUS_ACCESS_LOG},
\${LCP_WEBSERVER_GLOBAL_TIMEOUT},
\${LCP_WEBSERVER_HSTS},
\${LCP_WEBSERVER_PROXY_MAX_TEMP_FILE_SIZE},
\${LCP_WEBSERVER_PROXY_CONNECT_TIMEOUT},
\${LCP_WEBSERVER_PROXY_READ_TIMEOUT},
\${LCP_WEBSERVER_PROXY_SEND_TIMEOUT},
\${LCP_WEBSERVER_LOG_ESCAPE},
\${LCP_WEBSERVER_LOG_FORMAT},
\${LCP_WEBSERVER_MODSECURITY}"
find "${SERVICE_HOME_DIR}" -name "*.conf" -exec bash -c 'envsubst "${ENVSUBST_ARGS}" < $1 | sponge $1' _ {} \;
Comment intégrer ses propres variables
Je vous propose donc de reprendre ce fonctionnement et d'établir votre propre script de substitution afin d'y intégrer les variables de votre projet.
Le fichier devra être positionné dans le répertoire /webserver/configs/[env]/scripts/
; par exemple /webserver/configs/common/scripts/
si vous souhaitez le mettre en place pour tous les environnements.
Notre script sera nommé : replace-environment-variables-project.sh
Voici une structure simple qui permet d'intégrer votre variable d'environnement correspondant à la liste d'IP :
#!/bin/bash
check_and_export_environment_variable() {
local env_variable=${1}
local env_variable_custom_value=${2}
if [[ -z ${!env_variable} ]]; then
echo "[DXP Cloud] Setting ${env_variable}=${env_variable_custom_value}"
export ${env_variable}="${env_variable_custom_value}"
else
echo "[DXP Cloud] Using ${env_variable}=${!env_variable}"
fi
}
main() {
echo "[DXP Cloud] replacing Environment variables in *.conf files"
check_and_export_environment_variable LCP_WEBSERVER_SPECIFIC_IP_ALLOWED "0.0.0.0"
export ENVSUBST_ARGS="
\${LCP_WEBSERVER_SPECIFIC_IP_ALLOWED}
find "${SERVICE_HOME_DIR}" -name "*.conf" -exec bash -c 'envsubst "${ENVSUBST_ARGS}" < $1 | sponge $1' _ {} \;
}
main
Voici ensuite la modification à réaliser au niveau de votre configuration NGinX.
Avant :
if ($remote_addr ~ (192.168.1.1,192.168.1.2,192.168.1.3)) {
return 503;
}
Après :
if ($remote_addr ~ (${LCP_WEBSERVER_SPECIFIC_IP_ALLOWED})) {
return 503;
}
Configuration des variables d'environnement
Maintenant au niveau de la console, il faut ajouter la nouvelle variable, puis la valeur associée et enfin enregistrer. L'enregistrement déclenche un re-démarrage du service avec les nouvelles valeurs. Au bout de quelques secondes, le service est de nouveau en ligne avec les nouvelles données.
Les possibilités avancées
Dans le cas où vous auriez plusieurs valeurs à traiter, vous pouvez utiliser le même script et déclarer à la suite vos différentes variables. Il est également possible de faire comme dans le script de Liferay et contrôler que les variables fournies soient cohérentes afin de ne pas charger des données qui ne seraient pas prévues.
Et pour les données sensibles
Si vos variables d'environnement contiennent des données sensibles et / ou que vous souhaitez limiter leur accès depuis la console DXP Cloud, vous avez la possibilité de basculer sur l'utilisation de variables de type secret
. L'utilisation de secret variable ne change pas la procédure ci-dessus, il s'agit seulement de déclarer les variables dans la partie secret au niveau de l'interface plutôt que dans la partie regular.