1. It is a single point of failure for your application instances.
You indeed have one single point of failure. But f.e.:
To see how generally difficult configuration management can be, we only need to
look at the simplest of configurations: a flag to tell our web servers whether we’re
under maintenance. If so, we shouldn’t make requests against the database, and
should instead return a simple “Sorry, we’re under maintenance; try again later”
message to visitors. If the site isn’t under maintenance, all of the normal
web-serving behavior should happen.
In a typical situation, updating that single flag can force us to push updated configuration
files to all of our web servers, and may force us to reload configurations on all
of our servers, if not force us to restart our application servers themselves.
Yes, as the title says, this thread is about app env and it’s closely related cousins config scripts.
Just to be clear, I don’t deny that there’s a thing called system configuration. I just think that app env and config scripts are in most cases an inferior mechanism for managing the system configuration. Moreover, I think that the defaults promoted by e.g. phx.new are arbitrary, confusing, and at the same time limiting.
In my impression, a bunch of stuff ends up in config scripts for dubious reasons, and they don’t even help with actual system configuration (assuming you want to run OTP releases). I’ve been personally confused by config scripts, the team I’m a part of has been confused by config scripts, I’ve seen other people being confused by them, and a lot of libraries promoting them for no particular reasons.
I think we need to strongly challenge this approach, and reevaluate do we really need to promote config scripts and app env so much. I don’t say that they are useless, but I think that in most cases they are not the most appropriate choice. I think that we should instead promote regular code as much as possible, and leave the special code for the few cases where it’s really needed.
What I often saw as freelancer, working on huge administrative applications for customers, was very little config in files (not much more than db startup config), and customer-specific config in the database. Mostly the same database as where other applicationdata were maintained. The customer-specific config was configured by consultants. Application + db were on a separate server per customer.
And how would you handle customer-specific application configuration (with software + db installed on a server per customer). Configuration should be possible for consultants, so a user-friendly way is let’s say extra preferred.
The approach I’m arguing for is to provide as much parameters as possible from the regular code. That code is runtime friendly so you can fetch most of your config from arbitrary sources, including external databases. You could even configure e.g. your endpoint by fetching the parameters from your repo.
How would you provide those parameters from regular code? I would think of something like I proposed here: Rethinking app env (with the get_env(keys) call).
I feel that’s not only good advice for library authors, but does also provide the opportunity to move the knowledge about the different ways of doing configuration (with it’s pros/cons) to users – instead of relying on library authors to choose a fitting way – and the developer can choose one way to do config instead of being forced into multiple ways of doing things by used libraries.
E.g. I really like the pattern of MyApp.Repo in the way it abstracts a set of configurations into a module I call, which could be generally useful for any library, as long as it’s not configured by it’s own app env preventing multiple parallel configurations.
If a library Foo requires some parameters which you want to fetch from external sources you can invoke e.g. Foo.bar(fetch_params_from_external_source(...))?