@alexey.zimarev there are a few scenarios to cover, so let’s look at them.
First, I need to be able to run tests during development. I do this using JUnit and TestContainers, so ES is started as a Docker container, then my test code runs. If the projection configuration and setup is included in my code it just runs as part of the startup, and after that I know that the config is correct for the code I’m running. If there’s a separate tool this becomes much more complex.
Second, when I am running my application locally during development I often wipe the databases (including ES), and startup my application. I think of databases essentially as a persistent storage, whether it’s a file directory, ES, or some other db. So by running “schema scripts” on startup the application can be sure that after startup the persistent storage is in the state it needs to be given the assumptions of the application. Database migrations can also be done on startup, see LiquiBase for example. If there are major changes such that many application instances are accessing the same ES with very different assumptions, this is when you would do a blue migration instead, so that’s a separate situation.
For development, staging, and production environments, again I still treat ES and other databases as a peristent storage, and it is the application that decides what the schema/assumptions should be. Since the assumptions are encoded in the application it makes sense that the application enforces these assumptions on startup. It makes it easy to test older versions, newer versions, patches, etc. without having to worry about syncing schema management with a separate tool. That separation to me just creates accidental complexity that is unnecessary.
All in all, personally I have always preferred to look at persistent storage as an internal implementation detail of an application, which it therefore manages as per above. It makes life easier.
In this case it is very close to being doable, it is just missing to either allow idempotent changes, where updating a projection to the same query is a no-op, or allowing the client to see what the query currently is and make the decision based on that, since in some cases we have 6+ app instances to the same ES cluster. Whichever of these instances comes up first should do the setup, and the others are no-op’s or skipped.
Makes sense?