There is no single "silver bullet", and all this will greatly depend on the details.
First of all, I believe that it is best to separate the entire source code from the configuration in a separate repository. Thus, the source code remains the source code, but its installation or deployment (with configuration, passwords, etc.) is all the rest. Thus, you will decisively separate the tasks of the developers from the tasks of sysadmins and you will be able to eventually create two excellent teams that do what is good for them.
When you have a separate source code repository + deployment repository, your best next bet is considering deployment options. The best way that I see here is to use the deployment procedures typical of the selected OS (i.e. creating standalone packages for the selected OS in the way that the OS operators do).
For example, Red Hat or Debian packaging procedures typically mean grabbing tarball software from an external site (which will export sources from your VCS source code), unpacking, compiling, and preparing packages ready for deployment. Deployment itself ideally means simply executing a quick and simple command that will install packages, such as rpm -U package.rpm , dpkg --install package.deb or apt-get dist-upgrade (given that your built-in packages are sent to the repository where apt-get can find them).
Obviously, in order to make it work this way, you will need to provide all configuration files for all system components in a fully operational state, including all addresses and credentials.
To get a brief overview, consider a typical “small maintenance” situation: one PHP application deployed on n application servers running apache / mod_php to access MySQL servers. All of these servers (or virtual containers that really don't matter) are on a secure private network. To simplify this example, suppose that for all real Internet connections there is a cluster of k http accelerators / reverse proxies (for example, nginx / lighttpd / apache) that have a very light configuration (only internal IP addresses for forwarding).
What do we need for them to be plugged in and fully working?
- MySQL servers: setting IP addresses / host names, setting up databases, providing usernames and passwords.
- PHP application: configure IP addresses / hostnames, create a configuration file that displays the IP addresses of MySQL servers, logins, passwords and databases.
Note that there are 2 different types of data here: IPs / hostnames are something fixed, you probably want to assign them once and for all. Logics and passwords (and even database names), on the other hand, are solely for the purpose of connecting here - to make sure that MySQL really supports our PHP application. So, my recommendations here are to separate these two “types”:
- "Permanent" information, such as IP addresses, must be stored in some VCS (other than the VCS source code)
- “Temporary” information, such as passwords between two applications, should never be stored, but generated when creating deployment packages.
The last and most difficult question remains here: how to create deployment packages? Several methods are available, 2 main methods:
- Exported source code from VCS1 + "persistent" configuration from building VCS2 + script from VCS3 = packages
- The source code is in VCS1; VCS2 is a distributed version control (for example, git or hg) that essentially contains plugs of VCS1 + + configuration information that build scripts can generate. I personally like this approach better, it is much shorter and ultimately easier to use, but the learning curve can be a little steeper, especially for admins who have to master git or hg for this.
In the above example, I would create packages such as:
my-application-php - which will depend on mod_php, apache and will include a generated file of type /etc/my-php-application/config.inc.php , which will include IP addresses / MySQL database names and password / password generated as md5(current source code revision + salt) . This package will be installed on each of the n application servers. Ideally, it should be able to install on a clean installed OS and make a fully functioning cluster of node applications without any manual action.my-application-mysql - which will depend on the MySQL server and will include a post-install script that:- starts the MySQL server and ensures that it starts automatically when the OS starts
- connects to MySQL server
- checks for an existing database
- if no - creates a database, loads it with contents and creates a login with a password (the same usernames and passwords as those generated in
/etc/my-php-application/config.inc.php using the md5 algorithm) - if so, it connects to the database, applies migration to bring it to the new version, kills all old logins / passwords and recreates a new login / password pair (again, generated using the md5 method (version + salt))
Ultimately, this should be useful for updating your deployment using a single command, such as generate-packages && ssh-all apt-get dist-upgrade . In addition, you do not store passwords between applications anywhere, and they are updated with each update.
This pretty simple example illustrates the many methods you can use here, but ultimately, you decide which solution is better here and which one is crowded. If you write more detailed information here or as a separate issue, I will be happy to try to sort it out in detail.