Even if you plan what hardware to have and what software to run on your network, it's easy to end up with at least some heterogeneity. A slightly different configuration on some of the machines, a different communication protocol used by that legacy system that you need to integrate with, or different mobile phones sending requests to your system are just a few examples of this. Another one is extending your on-premises solution by using additional workers in the cloud.
Try to limit the number of protocols and formats used, strive to use standard ones, and avoid vendor lock-in to ensure your system can still communicate properly in such heterogeneous environments. Heterogeneity can also mean differences in resiliency. Try to use the circuit breaker pattern along with retries to handle this.
Now that we've discussed all the fallacies, let's discuss yet another pretty important aspect of distributed architectures.