What is this rule to only build once? I can see not wanting to create multiple artifacts of your codebase, but with machines it is possible to continually update them and sometimes desirable as well. In the "cloud" world, you can arguably rebuild a server every time it needs updates, but at the physical level you don't always have capacity to absorb the hit of rebuilding multiple boxes at once. The physical servers need to get updated and managed post-install.
Unless you're snapshotting that vagrant box and then deploying that to all your servers somehow, you are building multiple times.
> What is this rule to only build once?
I'd recommend reading the book Continuous Delivery. It is a fantastically helpful read.
I prefer not to update my machines, but that is because I follow immutable deployments. But, even if I did update my machines, it is far cleaner (and easier to roll back!) to deploy an asset which has all its dependencies in the box. than to push out code and maybe have to upgrade or install new packages. The gemfile.lock and friends make this a bit less of a problem, but you also get to lock things like libxml version or ffmpeg or...
> In the "cloud" world, you can arguably rebuild a server every time it needs updates, but at the physical level you don't always have capacity to absorb the hit of rebuilding multiple boxes at once.
Totally true, and we don't do this. We build a machine image and do a rolling-deploy replacing existing servers with the new machine image.
> The physical servers need to get updated and managed post-install.
One of the reasons I try not to work with hardware. Physical hardware is hard, and avoiding it makes my life much simpler. I love it.
You're also configuring many things in many different potentially complex ways.
The docker method of using environment variables as a configuration hack to get around this is pretty horrible, IMHO. Especially compared to ansible's YAML/jinja2 configuration.
YAML/jinja2 is just terrible. When you have to introduce a templating system to programmatically generate your YAML configuration files, what you have really needed the whole time is an actual programming language.
Taking out the turing completeness restricts the mess which you can make and lets non-programmers do more while still being customizable.
I think the point is not to conflate configuration that is equivalent to code (which, sure, put it in version control) with configuration that is specific to how code is deployed (which your deployment tool should just tell you, via env vars).
Which one? The one by Humble and Farley (Addison-Wesley) is from 2010, is it still relevant?
The book is excellent. I was surprised that it wasn't older.
If your cycle is "build, test, build, deploy", then you are not deploying those artifacts that you tested.
Any number of factors (different dependency version, toolchain difference, environment differences, non-reproducible builds) could lead to the second build being different from the first one, and then you deploy an untested artifact.
Not to mention that rebuild can be resource intenstive.