Elastic does this in a single cluster using Cluster-level shard allocation and routing settings | Elasticsearch Guide [8.6] | Elastic
Use the region name for the "rack" value. Put a master in each space and I'd put a voting-only master in yet a third region. Put ingest and Kibana in both regions. Allocate 1 replica for each index, replica's won't be housed in the same "rack".
I did that self hosted where we had campuses in various locations state wide and it's worked for several years.