There is an excellent document called the "Twelve-Factor App" (http://www.12factor.net/) in which the authors attempt to define the perfect way to design, build, and deploy a modern app-as-a-service.
The document is very general and in many cases the practices described are not optimal, not easily possible or in contravention of Microsoft's best practices. eg: The document discourages using config files but rather to use environment variables for config. This would seem incorrect in the .NET where it is common (best?) practice to use XML config files.
In an ideal world (i.e. forget budget/technical/skills constraints) in an organisation where the Microsoft platform has been chosen as the platform of choice for all deployments and .NET/TFS the development environment/tools of choice how would one follow the guidance in the Twelve-Factor App?
Are there any good examples of such an application (perhaps an open source one that has an excellent reference architecture)?
There are numerous issues with the design that I think are a bit naive.
For example in the Backing Services section they state that you should be able to swap out datastores without regard for code changes.
The problem is that in order to leverage the performance and capability benefits of any particular data store you will naturally gravitate towards utilizing the specific features of the store you've started with.
Further, not every datastore supports a common set of commands such that you could easily move from one to another. Their particular example of using MySql or CouchDB is, well, interesting because those two DB systems are conceptually very different: one is more of a traditional RDBMS, the other is document based. You can't just take your table structure and apply it directly to a CouchDB and expect to throw SQL commands at it.
Which means that you have to put a front end in place to essentially wrap each particular datastore with a set of commands exposed as a web service... Which, imho, makes development much more difficult for very little (if any) benefit.
Now, if they are limiting it down to exchanging a like server (local mysql) to a remote one (Amazon RDS) then the requirement that the datastore resources be accessed via a url is immaterial. Further the requirement that no code changes occur for that move is unnecessary as you shouldn't have to change code just to support having your exact DB running on a different server.
The above is just the first area I honestly looked at. As John Saunders said, the config one also shows a complete lack of understanding of tech like .Net. Quite frankly the whole thing looks like it was written by someone who has been in the Ruby world for awhile, and hasn't looked at what else is out there.
12 Factor has 3 "requirements" for configuration.
I'd say that .NET config files comply with half of these.
While I can agree with the intent of their requirements, I think that their suggestion of Environment Variables is a bad suggestion. They chose Environment Variables because they view them as a lowest common denominator and available on all platforms, but they really might not be available on all platforms. If you're running in a partial-trust web app (common on a shared hosting platform), you might not have access to get/set environment variables.
Environment variables are set per machine. If I have to make a configuration change to my production environment I want to make it once, in one place, for all servers. Environment variables don't let you do that.
While I can see their point that you don't want secrets stored in version control that are accessible to all developers. There are definitely benefits to version controlling your configuration. When your production environment goes down because of a configuration change, it's easy to ask .. "what changed"? The audit trail left by someone just ssh'ing to a prod machine and setting an environment variable might not be so easy to trace. Having said that, I often don't store my configuration files in the same part of version control as the rest of the code. I put them in a folder that has restricted security so that only the necessary people need access. You could conceivably take that a step further and put them in a different project.
I'd be willing to bet that they violate their own rules of not putting configuration in files. For example. The first bullet point on their home page is "Use declarative formats for setup automation, to minimize time and cost for new developers joining the project;" I'm betting that all those config settings that aren't supposed to be in a file anywhere are in a chef recipe. To achieve the goal of automation, you have to persist them in some file somewhere. And I'd be surprised if someone that spent a lot of time getting a chef recipe right didn't store it in version control somewhere.
I think they could have written the configuration page differently and just said keep your configuration separate from your code. Keep it in separate files (don't embed it in code), and store it somewhere separately (don't put it in the same repository). Your deployment process will bring these back together (code and config) into one deployable package, but they should be separate until that point.
My suggestion for configuration would be to treat the configuration as an "attached resource" and store it in a backing store (a database). This makes your app tier even more stateless which is another one of their goals.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With