Most AWS estates we inherit have the same two problems: nobody can draw the network, and nobody can explain the bill. Both are fixable, and both are cheaper to get right at the start.
The account and the boundary
Separate accounts for production and everything else, so a mistake in staging cannot reach a customer. Roles instead of long-lived keys. A private network with only the surfaces that must face the internet facing it. This is the layer that decides how bad an incident can get.
Compute, sized to the job
Containers on ECS or EKS for services that run continuously, Lambda for event-shaped work that would otherwise idle. We do not migrate a working application to serverless as an end in itself — the reason has to be a real cost or scaling number.
The bill as a design output
Cost is tagged by environment and service and reviewed monthly. Storage classes and retention are set deliberately. Egress is understood before it appears. When a bill surprises a client, the cause is almost always a default nobody chose.
Backups you have actually restored
A backup that has never been restored is a hope. We test recovery on a schedule and write down how long it takes, so the recovery target is a measured number rather than a sentence in a contract.
Everything as code
Environments are defined in Terraform and deployed by pipelines. Nothing important is created by clicking, because a console change is invisible to the next person.
Also comfortable on Google Cloud; container platform detail sits under Kubernetes and Docker.