Il n'y a pas de solution miracle et tout dépend des détails.
Tout d'abord, je considère que la meilleure pratique consiste à séparer le code source de la configuration dans un dépôt séparé. Ainsi, le code source reste le code source, mais son installation ou son déploiement (avec la configuration, les mots de passe, etc.) est une toute autre chose. De cette façon, vous séparez fermement les tâches des développeurs de celles des administrateurs système et vous pouvez finalement constituer deux équipes distinctes qui font ce qu'elles savent faire.
Lorsque vous disposez d'un dépôt de code source et d'un dépôt de déploiement séparés, votre meilleure option est d'envisager des options de déploiement. Le meilleur moyen que je vois ici est d'utiliser des procédures de déploiement typiques pour un système d'exploitation choisi (c'est-à-dire construire des paquets autonomes pour un système d'exploitation choisi de la manière dont les mainteneurs de ce système d'exploitation le font).
Par exemple, les procédures d'empaquetage de Red Hat ou de Debian impliquent généralement de récupérer une archive de logiciel sur un site externe (ce qui correspond à l'exportation des sources de votre VCS de code source), de la déballer, de la compiler et de préparer les paquets pour le déploiement. Le déploiement proprement dit devrait idéalement consister à exécuter une commande simple et rapide pour installer les paquets, par exemple rpm -U package.rpm
, dpkg --install package.deb
o apt-get dist-upgrade
(étant donné que vos paquets construits sont placés dans un dépôt où apt-get est capable de les trouver).
Évidemment, pour que cela fonctionne de cette façon, vous devrez fournir tous les fichiers de configuration de tous les composants d'un système dans un état de fonctionnement complet, y compris toutes les adresses et les informations d'identification.
Pour être plus concis, considérons une situation typique de "petit service" : une application PHP déployée sur n les serveurs d'applications fonctionnant sous apache / mod_php, accédant à m Serveurs MySQL. Tous ces serveurs (ou conteneurs virtuels, cela n'a pas vraiment d'importance) résident dans un réseau privé protégé. Pour faciliter cet exemple, supposons que toute la connectivité Internet réelle est assurée par un cluster de serveurs de k accélérateurs http / reverse proxies (tels que nginx / lighttpd / apache) dont la configuration est très simple (il suffit de faire suivre les IP internes).
De quoi avons-nous besoin pour qu'ils soient connectés et fonctionnent pleinement ?
- Serveurs MySQL : configurer les IPs/noms d'hôtes, configurer les bases de données, fournir les logins et les mots de passe.
- Application PHP : mise en place des IPs/noms d'hôtes, création du fichier de configuration qui mentionnera les IPs des serveurs MySQL, les logins, les mots de passe et les bases de données.
Notez qu'il y a deux "types" différents d'informations ici : Les IPs/noms d'hôtes sont quelque chose de fixe, vous voudrez probablement les attribuer une fois pour toutes. Les identifiants et mots de passe (et même les noms des bases de données), d'un autre côté, sont purement destinés à des fins de connectivité - pour s'assurer pour MySQL que c'est bien notre application PHP qui s'y connecte. Je recommande donc de séparer ces deux "types" :
- Les informations "permanentes", telles que les adresses IP, doivent être stockées dans un VCS (différent du VCS du code source).
- Les informations "transitoires", telles que les mots de passe entre 2 applications, ne devraient jamais être stockées, mais générées lors de la génération des paquets de déploiement.
La dernière et la plus difficile des questions reste ici : comment créer des paquets de déploiement ? Il existe de multiples techniques, dont les deux principales sont les suivantes :
- Code source exporté de VCS1 + configuration "permanente" de VCS2 + construction de script de VCS3 = paquets
- Le code source est dans VCS1 ; VCS2 est un contrôle de version distribué (comme git ou hg) qui contient essentiellement des "forks" de VCS1 + des informations de configuration + des scripts de construction qui peuvent générer . Personnellement, je préfère cette approche, elle est beaucoup plus courte et finalement plus facile à utiliser, mais la courbe d'apprentissage peut être un peu plus raide, surtout pour les gars de l'administration qui devront maîtriser git ou hg pour cela.
Pour un exemple ci-dessus, je créerais des paquets comme :
-
my-application-php
- qui dépendrait de mod_php, apache et inclurait le fichier généré comme /etc/my-php-application/config.inc.php
qui inclura les IPs/noms d'hôtes de la base de données MySQL et le login/mot de passe généré comme md5(current source code revision + salt)
. Ce paquet sera installé sur chaque n des serveurs d'applications. Idéalement, il devrait être capable de s'installer sur un système d'exploitation propre et de créer un nœud de cluster d'applications entièrement fonctionnel sans aucune activité manuelle.
-
my-application-mysql
- qui dépendrait de MySQL-server et inclurait un script post-installation qui :
- démarre le serveur MySQL et s'assure qu'il sera lancé automatiquement au démarrage du système d'exploitation.
- se connecte au serveur MySQL
- vérifie si la base de données requise existe
- si non - crée la base de données, l'amorce avec son contenu et crée un login avec un mot de passe (les mêmes logins et mots de passe que ceux générés en
/etc/my-php-application/config.inc.php
en utilisant l'algorithme md5)
- si oui - se connecte à la base de données, applique les migrations pour l'amener à la nouvelle version, tue tous les anciens login/mots de passe et recrée la nouvelle paire login/mot de passe (à nouveau, générée par la méthode md5(revision + salt))
En fin de compte, il devrait apporter l'avantage de mettre à niveau votre déploiement en utilisant une commande unique telle que generate-packages && ssh-all apt-get dist-upgrade
. De plus, vous ne stockez nulle part les mots de passe inter-applications et ils sont régénérés à chaque mise à jour.
Cet exemple assez simple illustre un grand nombre de méthodes que vous pouvez employer ici - mais, en fin de compte, c'est à vous de décider quelle solution est la meilleure ici et laquelle est exagérée. Si vous voulez donner plus de détails ici ou dans une question séparée, je serai heureux d'essayer d'entrer dans les détails.