When a service A is deployed, some configuration needs to be added to service B, and only then. For example, when deploying a service A to perform backups, then a Localization service B needs to be configured to be able to translate the names of the backup operations, which are then queried by a UI service C. That is, deploying A involves changing the configuration to B.
That's not the microservice way.
It's perfectly fine for one microservice (A) to make use of another (B), but it's not okay to have to manually configure B to be able to serve A. That breaks B's independence.
- A number of around 50 microservices are available
- Depending on their needs, clients design their deployment choosing which of those microservices they need
- Most of them are not usable in isolation, but require others to be available, which is perfectly understandable.
I'm assuming a tenanted situation here to simplify the explanation, but the gist (and specifically the part I think you need answered) is the same even if not in a tenanted setup.
It's perfectly fine to setup your system to tell the tenant that if they want to have microservice A, that they're also going to need microservice B. There are several way to go about this:
- Provisioning A automatically provisions B, the customer doesn't have to think about it.
- You expect the customer to know that B needs to be provisioned, and to explicitly provision B before A.
- You write your A service so that it has a fallback behavior if B is not provisioned, effectively making the provisioning of B optional.
I'm not a fan of option 2, as it's not a great experience for the customer. It's a mandated hoop for them to jump through that you could have easily automated since you knew in advance that it needed to be done.
In cases where A can optionally depend on B, I'd favor option 3. Otherwise I'd favor option 1.
Similarly, if they provision a C microservice which would query B if it exists, I'd offer option 3, where C can graciously handle the case where there is no B, e.g. a clear message to the user that the C features relating to B are not available because there is no B.
If B is not optional, and the customer only provisions A and C, then A and C's B-dependent features will not work. This is not a problematic situation from a development perspective. At best, you graciously handle the subsequent errors/exceptions, but A and C can do nothing more than report that they "cannot find a B that my own feature needs".
Usually, this is no different from already handling an unexpected outage of B, as both scenarios look the same from the perspective of A: it cannot successfully interact with B.
Or does this simply smell like an architectural problem for there is a different solution.
The main issue here is that if B is a microservice, you should be able to deploy B before you even know who will be consuming it.
The only exception here is if A "registers" itself to B (e.g. pubsub scenario). But that is not a configuration setting, that's an actual interaction between A and B where A calls the "subscribe" endpoint of an already operational B microservice.
Your example is light on concrete reasons why B must be reconfigured, but it seems to me like you've not properly defined B the way a microservice should be defined. It's much too dependent on knowledge who will specifically consume it, which means it's not independent.
That is, deploying A involves changing the configuration to B.
If I assume that you're not in a tenanted situation, but rather that there is only one of each (A, B, C), then it's important to define "configuration".
If by "configuration" you mean things like consumers registering/subscribing to the service, that's not configuration. The ability to register is part of the responsibility of the app itself, so needing to register is just "using the app", in that sense. You could go about this in several ways:
- A can register itself in B by having the end user call the correct A endpoint.
- A automatically registers itself with B on startup.
- A automatically registers itself with B on startup, and internally stores a reminder that it doesn't need to re-register when it next starts up.
- As part of the A release pipeline, after A is deployed you then call the appropriate A endpoint which makes A register itself with B.
However, if by "configuration" you mean app configuration, i.e. config files, a bulk data upload behind the scenes, or other data needed for the service to even work, then you're doing it wrong.