For resources like databases, you don't need cross-account access if you're using internal DB authentication systems. For IAM-based DB authentication, you can simply write policies to trust the target accounts.
Occasionally, you'll need to create a cross-account trust (via AssumeRole), but it's not at all that frequent.
My personal wish is for AWS to allow account _names_ instead of ID numbers in policies.
What you should do instead is have one account per environment (as you said).
I'm honestly not sure if thats a great idea, but this might be a possible way to do one account per DB/backend/frontend in a somewhat sane way.
Generally I'd stick to accounts per environment, you'll be worrying about a lot more when you get to FAANG scale.
That said, I still think it's overkill and doesn't bring any real benefit? Sure you're reducing the blast radius of a security breach, but are the overcomplications worth it? Also, you now have to manage multiple accounts with multiple policies and users / roles, won't that extra complexity actually increase the attack surface?
To be honest, I'd probably prefer a single account per environment. But managing the IAM for that would be much more work.
That's how AWS works internally. A team can easily have several hundred accounts: one for each region, and for each env.
You absolutely need tools to manage them, and AWS is not great in this regard. IAM Identity Center is a good first step, but its usability sucks compared to the AWS internal tool (called "Isengard").
> You're going to have to expose your DB to the internet instead of having everything inside a single VPC.
There are several ways to NOT do this. The easiest one is to use IPv6 with your own block (you can get it from ARIN for around $100). Then split it into "public" and "private" subnets, and install a network ACL prohibiting external connections into the private subnet.
Or even without that, there are plenty of footguns. AWS has a good blog post: https://aws.amazon.com/blogs/security/protect-sensitive-data...
Use multiple AWS accounts, and keep your policies simple. One account for DB, one for the backend servers, etc. Each environment (prod, staging, dev) also gets its own set of accounts.
This way, a misconfigured policy won't give admin access to everything.