Here's where you lose me:
> You say these are easy to change, but when your infrastructure is set up correctly services are also easy to change, it is all just code.
Unless you have extremely simple infrastructure, it's very much not "all just code": it's programs that are running on different machines that don't intrinsically know about each other.
Then it becomes a coordination problem. For example, if service B calls service A and you want to change the hostname of service A, you need to first make sure that service A will respond to the new hostname, and then that your discovery layer knows about that change before service B — and also that it still handles the old name correctly until service B has been updated.
"Oh, but I have all my infrastructure in [Terraform/Cloudformation/Pulumi/etc], that's not a problem for me." First of all, there are a ton of reasons things might slip through the cracks. Maybe you're migrating from one system to another, or maybe some dependency doesn't have great support, etc. But second of all, infrastructure is stateful and things can go wrong. If your change fails halfway through for some reason, and only some pieces are aware of the new name, are you sure your system is consistent?
Code, on the other hand, is just code — changes are atomic and self-contained. If I change a function name, I know that everything that could possibly use that function is contained within my codebase. When I deploy, it's either using the new name or not — and it doesn't matter if half of my servers have different names for the function, because they don't interfere with each other.
The one exception to this is public APIs, which are difficult to change without breaking downstream consumers. But consumers can always choose not to upgrade their version of the library. And when they can't — when it's a proxy for an external dependency, like a web service — the issue isn't the name in the code, but the name in the infrastructure.