When I started designing my AWS setup, one of my early goals was clear:
keep backend servers completely private.
So my EC2 instances lived in private subnets, with no public IPs. That felt right from a security perspective.
But very quickly, a practical problem showed up:
If my servers aren’t reachable from the internet, how do I access them when something breaks?
This article isn’t a guide on how to configure access.
It’s about what I tried, what felt wrong, and what finally clicked.
⸻
The First Solution I Tried: A Bastion Host
Like many people, I started with a Bastion Host.
The idea was straightforward:
• One small EC2 instance in a public subnet
• Port 22 open
• SSH into the bastion, then hop into private instances
And honestly — it worked.
But the more I used it, the more friction I felt:
• I was managing SSH keys again
• One public-facing server became a critical choke point
• Security started depending on how well I protected that single box
Nothing was broken, but something didn’t feel aligned with the rest of the architecture I was building.
⸻
The Question That Changed My Approach
At some point I stopped asking:
“How do I reach my servers?”
and started asking:
“Why does access depend on network paths at all?”
That shift led me to AWS Systems Manager (SSM) Session Manager.
⸻
What Changed When I Switched to SSM
Once I set up SSM and removed the Bastion Host, a few things became very clear.
- Access became identity-based, not network-based
I wasn’t thinking about IPs, ports, or jump paths anymore.
Access was simply about who I am and what IAM permissions I have.
That felt like a more natural fit for cloud-native systems.
⸻
- No inbound ports felt… relieving
Closing port 22 everywhere wasn’t just a security improvement — it simplified things mentally.
There was no longer a “special server” that needed extra attention or hardening.
⸻
- Visibility improved without extra effort
Every session was logged.
Every action had an identity attached to it.
I didn’t have to bolt on monitoring — it was part of the access model itself.
⸻
What This Shift Changed in My Mental Model
Before:
• Security felt like layers of network controls
• Access meant “finding a safe path to the server”
After:
• Security feels like identity + intent
• Access means “am I allowed to be here?”
That distinction mattered more to me than I expected.
⸻
Where I Am Now
This is how I currently think about server access in my setups:
• Backend EC2 instances stay in private subnets
• The load balancer is the only public-facing component
• Administrative access happens through SSM, not SSH
• Security groups are chained tightly, not opened broadly
I’m not saying Bastion Hosts are wrong — they still have valid use cases.
But for my learning and the systems I’m building right now, SSM feels like the right default.
⸻
A Question for People Further Along
If you’ve worked on production AWS environments:
• Do you still rely on Bastion Hosts?
• Or have you moved fully toward SSM / identity-based access?
• In what cases do you still prefer a bastion?
I’m still learning, and I’d love to hear how others think about this trade-off.

Top comments (0)