Yeah it's hard.
For http API design I like to start with an openapi spec then generate as much of the server and client library implementation from this as possible.
The spec gives a language/implementation agnostic way to describe what you're intending to build that's nicely diff-able over time, and you can generate a lot of the boilerplate that's easy to screw up in a way that's both compile time (static types) and runtime (parsing/validation of inputs & outputs) safe.
I can imagine a world where a similar approach could work for higher level architecture. It's pretty common to have a shared helm chart that (largely) defines each individual logical service in k8s environments.
Taken to the extreme you could provision your data stores, and network policies etc using this approach such that an individual services chart defines exactly what it depends on. Throw in some metadata fields for descriptions and you're well on the way to having something that could generate some useful diagrams / documentation.
Of course the issue with such helm charts is that if you make them flexible enough to suit everybody eventually you'll just reimplement the underlying APIs they are calling - perhaps some approach using direct introspection of k8s resources and cloud resources with a standardized set of metadata to group and describe relationships might be more feasible.
For the moment I'll probably stick to excalidraw