Paul Hammant's Blog: Application Architecture in the CD Era for Pro-Services teams
Say your platform is ‘YoorBank’ and you host real community banks in a white-label architecture. You provide the infrastructure and IT operations, they wheelbarrow the cash into their own vaults, but are otherwise integrated into the scaled YoorBank production facility. You have Sales people that visit community banks, and sign them up (or try to). Henceforth I’ll talk generically about ‘Customers’ that require ‘configuration’ into the your system, with a committed-to go-live date, as this is not just for high-street banking…
Base Product vs Customer config.
Your team has a base product onto which multiple customers are integrated, in a single stack. Each customer’s config work, most likely, involves customizing import and export of data. Featured technologies could include ETL. XSLT, FTP and so on. The base product goes live a number of times a year. The customer configuration, if your services are in demand, could go out way more frequently than that. That would be new customer integrations, but also modifications to the existing ones. Indeed, there’s a strong business need to be able to tweak customer configuration in production without first proving that somewhere else.
Anyway, if your entire stack and development is a full-speed Continuous Deployment one, then the base product and the completed customer configuration can fire-hose into production. Refer the right hand side of the first picture on this article You’ll need the nerve to essentially merge customer config and binary code into a releases in that style.
If it is not, and you’re more in the middle of the same logarithmic chart (like most enterprises), then perhaps decouple the binary releases from the customer config releases. Back the latter with formal source-control as I’ve said before, and you have a more safe way of managing customer config.
With Infrastructure as Code, that makes three source control repos that can affect an environment (live or non-live).
Use of those three source-control repos
The Infrastructure as Code (IaC) repo governs the build-out of Dev, QA, and UAT. At least those three, and dropping and rebuild them too, not just the initial creation. The same code is used to build production, but you will not be so cavalier about dropping (de-provisioning) production. At least not the data tier. How often does that one run? infrequently for non-live environments, and humans always choose when. Success (for non-live environments) means only a small delay between asking for a new environment, and getting it. That means mere hours specifically, and we did not head off for a round of approvals and budget-finding first.
The Application Code repo, has a CI daemon (Jenkins, ThoughtWorks’ Go) watching it and at least making labelled binaries that could be deployed. If you’re on the ball as an enterprise, you are deploying that to (say) a ‘Jenkins01’ environment somehow. Either for more automated testing (Selenium2 etc), or manual testing if the stack is up long enough for humans to get in and poke around. Other buttons presses in that CI daemon’s web interface could deploy other more curated environments. Of course, you’ve previously used the IaC provisioning scripts to make the environment that you’re using for each of these purposes.
The Config as Code one would (as I’ve described it before) have one branch per meaningful environment. That would include production. For applications that include the customer configuration aspect, promoting select config to Production from UAT (or v.v.) is a strong requirement. Promotion as a business concept maps to merge the source-control concept, and directories would separate customers. There’s a ton a safety from using formal source control, as long as the config is essentially carriage-return delimited text, and is consistently represented. Formal source-control also allows a ‘round-trip’ capability. That’s editing via the purpose-built user interface as well as from the command-line after a separate checkout.
Path to Production for Code and Config
I’m only representing five environments (four non-live) here, and you should imagine more, but for the sake of a simple diagram ..
(If that doesn’t load for your older browser, click here)
The Development environment is a place where devs work on feature that more than one customer will need. The Product Owner is steering development here. They have their own contrived development customers that have the features and behaviors of the real signed-up production ones, but are in no way connected to live systems, or share branding trademarks etc of live customers. For testing there would be stood-up mock and stub integration points, that are perfectly reliable and scriptable.
The Pro Services team has their own development environment that is separate. The frequently ask for ‘stable’ code drops from the base product development team. This team is developing configuration for their assigned customers, and planning their own release schedule. Sales people feed into the requirements and backlog there, and the team might have to expand or contract as it is demand driven.
Complicating Factors.
It’s never as simple as just config. There’s inevitably some custom code (say Java) too.
Further reading
If you have not previous read my articles on Configuration as Code, perhaps you should. After that, think about the elegance of a formal source-control tool backing that toggles & customer config, with an open choice of pull or push for propagating changes to running stacks.