With microservices they're obviously complicated, and that's better. There's a complexity in monoliths as well, but it's hidden complexity. That gives developers a false impression that things are simpler.
For example, in microservices if you want some data that another service owns you have to define what it is, write an API, and handle all the fun of network problems. But once it's done you have a nice contract for getting that data.
In a monolith you can just reach over and take what you want. If you know there's a function for getting something you can use it. If you know the instantiated db connection has permission to view a row, just query the db directly. If you want to pipe some data somewhere just add it to the session object and it magically appears where you need it. And so on. You can go so fast! But then someone else does the same thing, and over time your monolith gets slower and slower, and needs more memory, and you find yourself having things on a god object that really shouldn't be there but it's hard to change because the behavior is threaded through everything.
Both of these problems are relatively simpler architectural issues, but it's always preferable to have well-defined complexity over accidental complexity. If you can define how code goes into a monolith and stick with those rules then a monolith is great. Most people can't, and I've never seen a company with multiple teams manage it.
You don't need network boundaries for good architecture. Split monolith into modules with an interface
That's a modular monolith, not microservices. It's a nice architecture for dev but it comes with a downside that you need to deploy everything whenever there's a change. You usually end up with a complex release train process. Again, the complexity is still there, but it moves. Where your complexity lives is a choice.