It is considered bad practice to place machines that shouldn't be accessible from the internet in a public subnet, because such topology, other than being logically wrong (private instance in an internet-facing subnet) also exposes the machines on the public internet.
If we were talking about an on-premise environment, this fits perfectly. Machines that are public should be in a DMZ while private machines should be in a separate private network and protected by a firewall.
But, in a cloud environment such as AWS, we have Security Groups. So, while of course it is logically wrong to have private instances in a public subnet, are there any objective reasons not to do so in a cloud like AWS? Is it somehow more insecure to use Security Groups to isolate a machine?
I am asking this because there are various advantages in having all the machines in public subnets in a smaller environment, such as:
- Lower costs, you can save money on a NAT gateway needed for a private subnet by using the already existing Internet Gateway
- It is far easier to allow traffic from the internet to specific instances. Say, if you wanted to allow access from some external vendor to only one machine, you could simply add a rule for a specific IP in the Security Group and then use a CNAME pointing at the public DNS of the machine through some automation, or use dynamic DNS.
- The traffic from machine to machine is still inside AWS, so I still get the advantages of lower costs.
- I can also still do VPC peering, so if I wanted to connect to a VPC in another account, it would still be possible to do without going through the public internet.
- I can have more specific per-instance security
So, while it is logically wrong, are there any objective reasons not to do so?
We were doing this conversation with a colleague and, when asked the actual reason why an EC2 instance shouldn't be public, I simply replied that it is logically wrong and tends to do more confusion, but I remained with the doubt about any objective reasons why this shouldn't be done and is actually wrong practice.
Here are a few downsides that I was able to find:
- Security groups are limited to 5 per network interface
- Public IPs are not paid if they are non-static, but are bound to the number of machines you have (only 1 ip per machine). This limit can be increased though.
- IP rebounds have a cost. It seems the first 100 IPs are free, but once you go above that limit it's $0.20 per IP refresh.
Some correlated threads:
AWS VPC - why have a private subnet at all?
Is it worth setting up a private subnet in Amazon EC2 (VPC)
AWS EC2 instance: security groups and firewalls
EC2 - should security groups be specialized and stacked?
The above threads elaborate on the topic but don't provide enough objective reasons as to why it is wrong, aside from a security implication (again, ignoring the fact you would configure security groups correctly with Terraform to avoid even more any misconfigurations).