Public/Private Subnet Architecture on AWS - amazon-web-services

I am having trouble understanding this image:
Specifically what I want to have is the Global Accelerator attached to every region, with each region having a VPC and Load Balancer. Then in each AZ in a region, have a public and private subnet. The private subnet or database servers will do all the computation and rendering. The public subnet is the Load Balancer (or does the public subnet need to be a set of instances?).
The public subnet also has an Internet Gateway and NAT Gateway attached. The docs say a private subnet can access the internet using a NAT Gateway in the public subnet, but I don't understand why it doesn't just use the Internet Gateway.
I have a route table in the public subnet, and the private subnet. In the public subnet, the route table goes to 0.0.0.0/0 pointing to the internet gateway. In the private subnet, it goes to 0.0.0.0/0 pointing to the NAT gateway.
There are also an Elastic IP associated with the NAT Gateway, presumably so that's what the internet sees when I make a request from a private server.
My question is, what is connected to what? The docs aren't clear enough on a practical example. I would like to have a public subnet, which I think doesn't require having any instances (am I wrong?), only the load balancer. Then the private subnet is the computation/database subnet which does consist of instances which can only connect to the internet through the load balancer connected to the NAT gateway.
I am confused. I have read the docs over and over again but still don't see how this is supposed to be wired up. Any help explaining what is connected to what in this diagram (extending it to include the Global Accelerator) would be greatly appreciated.

Please don't take this the wrong way, but I don't think you really need everything you are saying that you want.
I would recommend that you start with one region and no Global Accelerator. Implement your system and either creating a test platform that can simulate user traffic, or release your system to your customers and monitor it to determine performance.
If you run in multiple regions, you have a problem with where to keep your data -- data might be kept separate in each region, or replicated. This all depends upon your needs. I suggest you start simple, then expand if you need to operate differently.
Global Accelerator does not make sense when using multiple regions, since it is designed to send traffic to one location. Instead, consider Amazon CloudFront to cache data closer to your customers to provide better performance.
If your application runs on multiple web servers, put a Load Balancer in public subnet(s) and everything else in private subnet(s).
Put simply, start simple. Get your application working in the simplest possible way. Then, if you have greater requirements (eg low latency to users), look at adding Amazon CloudFront. Very few applications span multiple regions, so make that choice carefully and have a specific reason for doing so.

When you use AWS Global Accelerator, you can keep your ALB and instance private, without exposing them to the internet.
Such architecture is explained in the recent AWS blog post:
Accessing private Application Load Balancers and EC2 instances through AWS Global Accelerator
In this architecture, internal ALB is used, and there are no public subnets. The only requirements is the pretense of internet gateway in the VPC. It should be noted, that even though there is internet gateway, no routes are configured for the subnets to access the internet:
To avoid internet traffic from inadvertently flowing into a private subnet, we require that an internet gateway is attached to the VPC that contains resources when a client address-preserving accelerator is created.

I came in late but:
One rule is "if it can stay in private subnet then keep it in private subnet". Accessing the internet will always be costlier. When that is done if you must reach the internet then use VPC endpoints (if possible) instead of NATG and IGW. Endpoints are cheaper and make cheaper data transfers.
For Accelerator and Cloudfront, if data cacheing will be a pain for you then use Accelerator, if not, simply put, CloudFront is cheaper and better.
Despite all this, your architecture and use case will always decide your best and cheapest set up.

Related

Why do AWS recommend public and private subnets with a nat gateway?

I'll be complying with AWS best practise and having e.g. database instances inside a private subnet but I am wondering why this architecture is recommended?
AWS recommend this architecture so that the DBMS is not accessible to the outside world. If you want to patch it, or some other operation and it needs access to the internet, you should provision a NAT gateway in your public subnet. The DBMS instance in the private subnet can then get access to internet through this NAT gateway.
Could the same be achieved via security groups with the DBMS instance in the public subnet? It's worth noting that AWS charge around 40 USD / month for a NAT gateway.
On the DBMS instance you could have a security group rule which allows all outbound traffic but blocks inbound traffic (which I think is the default rule). This rule could be extended to only allow inbound traffic from a specific web server in the public subnet.
Is the answer that instances inside a public subnet automatically get a public IPv4 address? This would be undesirable for my DBMS instance even though it is effectively fire-walled through my security group rules as outlined above.
Thanks for your help in assisting me to understand AWS networking better.
You are right that this is the reference architecture, and you are indeed the not the first person to raise an eyebrow regarding the cost for the NAT Gateway.
It is true that the separation of public and private networks is an additional security layer that can prevent inadvertent exposure of your critical infrastructure to the public internet, but also to less privileged resources in your VPC.
Keep in mind that not every private subnet needs a NAT gateway; this is only necessary if the machines need to initiate traffic to the internet themselves. You could for example have pre-baked, regularily updated AMIs that don’t need the usual yum update at boot or any other such activities, and you might get away without the NAT Gateway.
Also, best practices doesn’t mean that it’s mandatory. For instance, if you deploy via Cloudformation, do regular security and architectural reviews and are sure to have SGs/NACLs/etc. set up properly, you could place the database in a “public” subnet as well. TL;DR: Use your own judgement to assess the tradeoff between security and cost, one way or the other.
Disclaimer: This is not the official position of AWS but my personal perspective.

AWS: Public subnet + VPN gateway

Question
Can we make a route table which has both igw-id (Internet gateway ID) and vgw-id (VPN gateway ID)? If we can't/shouldn't do it, why?
Example
10.0.0.0/16 --> Local
172.16.0.0/12 --> vgw-id
0.0.0.0/0 --> igw-id
Reference
https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Scenario3.html
(I mainly refer to "Overview" section and "Alternate routing" section.)
Explanation
This webpage above shows the scenario where one VPC has one public subnet, one private subnet and one VPN gateway. In this example, the VPN gateway is always accessed from instances in the private subnet (meaning its route table doesn't have the record "igw-id"). I wonder why one route table doesn't have both "igw-id" and "vgw-id".
Yes, we can have both igw and vgw. In fact, the example above would be a perfect for a public subnet which can connect to your corporate network through direct connect or site-to-site VPN, and also have internet access and be accessible from the internet.
Now, weather you would want this or not, it is an architectural decision. In the example scenario given by AWS, they try to segregate subnets by having a public subnet (with the igw) which can contain services accessible from the internet and a private subnet for other backend services (exmaple: databases). These backend services can be accessed from the corporate network using a site-to-site VPN, this is why the subnet has the vgw.
Yes, you can have a route table with the 3 routes you specified. However, bear in mind that with a route 0.0.0.0/0 --> igw-id, hosts on the internet can initiate connections with the instances in that subnet. Typically, you would want to secure the instances in a subnet that you allow a route to your on-premise network, and not expose it to the internet. If these instances require to connect to the internet, AWS recommends NAT devices for your VPC.
While it's technically possible, the main reason not to do that is due to a concept called network segmentation. It basically follows a "defense in depth" approach that network layers should be separated in a "public" and a "private" part (more zones are also often used like third tier for data storage and a fourth for infra used to manage the other three tiers).
Since your public subnet is directly exposed to the internet, it'most likely to be breached when you misconfigure something. If you would have routes in your public subnet to your VPN gateway, a single breach enables an attacker to attack your on-prem environment as well.
This is why its best practice to add one or two network tiers to your architecture. Even when the public tier is compromised, they still need to get into an instance in the private tier before they can attack your on prem environment.
It's recommended that your public subnet only contains an elastic load balancer or similar when possible. Its a pretty good way to reduce the attack surface of your application servers (less chance that you expose an unwanted port etc.).
A nice guide on this can be found here. It doenst include vpns, but you can condisider them part of the app layer.

Do AWS EC2 instances in same VPC connect through internet using public IP?

For example, when I deploy two AWS EC2 instances in same VPC and same subnet, that two instances connect through internet using public IP?
I already know that traffic flows referring to route table and my current route table sends all traffic except between private IP to internet gateway.
By the way, I wonder if those "all traffic except between private IP" includes AWS public IP.
In this situation, Does AWS automatically route traffic just inside VPC or not??
Yes, all traffic between the EC2 instances within the same VPC will be routed using internal, private IP obtained from the private DNS.
You can find more in the VPC international DNS here https://docs.aws.amazon.com/vpc/latest/userguide/vpc-dns.html#vpc-dns-viewing
Best, Stefan
The question is a little confusing, but I think I understand. Quick rephrasing:
How does traffic route for EC2 Instances.
If traffic has to go to the internet, then it will. There are techniques where this is done on purpose, such as hairpinning, and if this is your intention, there shouldn't be any problem with doing something like this.
AWS has a 'Backend' (Sometimes called a backbone) network. All communication to EC2 Instances, or Amazon Services in General, should be routed on the AWS Backbone.
I had a little trouble locating a doc with the exact wording, but this doc covers it a bit. Please remember that the AWS Backbone is fast, so it is a good thing to use it.
https://docs.aws.amazon.com/vpc/latest/userguide/how-it-works.html

Why does a AWS NAT Gateway require an ElasticIP?

While creating NAT Gateway an Elastic IP Address is created in AWS. The AWS documentation (1) also mentions the same. Why is an Elastic IP Address required for NAT Gateway?
Simply stated, the EIP is required because that is the way the NAT Gateway feature was engineered.
It wouldn't make sense to have a dynamic address on a NAT device -- if the address changed, that would be guaranteed to break any sessions in progress... and the only way to allocate a static address is by allocating an Elastic IP address (EIP).
It's also common to have external vendors whitelist your servers (for access to their servers) by providing them with the EIP of your NAT Gateway, in which case a dynamic address from the public pool would be unacceptable.
There may also be internal, proprietary reasons related to the way EIPs function that made this requirement a necessity... but that is not documented, so such an assertion would be mere speculation. An example of this: the public pool addresses (like those auto-assigned to EC2 instances configured with a public IP address from the pool, not an EIP) might be engineered to the specific availability zone, or even a subset of a single availability zone (they do, after all, change, when an instance is stopped/started, implying that they might be dedicated to specific server bays within an AZ), while EIPs can migrate anywhere from one zone to another within a region. This strongly implies different internal topologies.
This requirement (constraint?), to me, seems insignificant: you shouldn't be charged for this EIP, and if you need to increase the maximum allowed number of EIPs in a region, you can submit a support request at no charge, describing your use case, to request a limit increase.
The EIP requirement is rather arbitrary. Having a static IP makes coding the NAT easier (it doesn't have to check the WAN Interface for upstream address changes) but NATs that support a dynamic upstream address are very common - almost every home served by a major ISP has one. Sure, there's a risk the external address might change and break the current connections, but the ISPs know this and try hard NOT to change the address. Generally it changes only when you reboot the router, and at that point all your connections are broken anyway.
On AWS there there are many similar scenarios where you don't care if your NAT gateways external address changes, especially if your VPC does not contain any public servers. I have a lot of these, and I'm trying to run them on free accounts - it annoys me that they force me to burn through my short supply of static IPs.
As others observed this is a small expense, and AWS is still way cheaper than any other way I know to get this kind of cloud power; but that EIP is not strictly required.
No insignificant at all, you are only allowed to have 5 EIPs, so having 2 or 3 apps in two availability zones will hit that threshold.
As of June 2021, the AWS NAT Gateway does not require an ElasticIP (if you choose "Private" mode):
A private NAT Gateway, or NAT Gateway with connectivity type set to private, does not require EIP and you do not need to attach an internet gateway with your VPC.
https://aws.amazon.com/about-aws/whats-new/2021/06/aws-removes-nat-gateways-dependence-on-internet-gateway-for-private-communications/
I think what the answers here are missing is that the NAT Gateway (NATG) traffic is still being routed through an Internet Gateway (IGW), which performs static (one private IP to one public IP) NAT. As the image in the question indicates, the Elastic IP (EIP) is an association. It is the IGW that is translating the NATG's private IP to its associated public EIP.
This EIP requirement is therefore consistent from an AWS implementation perspective for any resource (e.g. EC2 instance) in a public subnet accessing the internet through an IGW.
Let's say you have private network instances, how will they connect to internet? That's when NAT comes in. NAT ip is public. And private subnets can be associated with NAT. So in that way, the instance in private subnet can connect to internet using NAT. This is very useful when you have server to whitelist your ip. Just give them the NAT EIP and problem solved.

What are the reasons to use private subnet in aws vpc?

I am trying to evaluate private and public subnets while creating a new VPC.
Is seclusion from inbound traffic from internet the only reason to go ahead with a private subnet? These points also need to be taken into account when considering the private subnet.
NAT Gateway is chargeable - 0.045$/hour and 0.045$ for per GB of data transferred. So there is cost consideration. I would need NAT gateway for pulling code or updates from internet.
I should be able to secure instances in my public subnets by using security groups with different levels of strictness.
When launching an instance I would assign a public ip to only those instances which I want to access from outside the VPC.
I went through this question but it didn't solve my doubts with respect to above points. Any help is appreciated.
From 7 Security Measures to Protect Your Servers:
Isolated Execution Environments
How Do They Enhance Security?
Isolating your processes into individual execution environments
increases your ability to isolate any security problems that may
arise. Similar to how bulkheads and compartments can help contain hull
breaches in ships, separating your individual components can limit the
access that an intruder has to other pieces of your infrastructure.
So, IMHO, do you need private subnets? Depends. In a production environment with public and private services, VPN, databases, etc., yes; but if you have only one server, and you don't want to deal with the configuration of network ACLs, routing, NAT, and so on, maybe a public subnet with your server and a well configured security group could be enough.
To answer your questions:
Use NAT instance (t2.small or m3.medium) instead of NAT gateway. Far cheaper.
Why launch them in public subnet and then tweak the security group if there is no need to accept the incoming internet traffic. There is always a chance to make a mistake in SG rules and allow malicious traffic unintentionally. Even if you want to accept internet traffic, I suggest using a reverse proxy like haproxy
Then launch only those instances in public subnet or use a reverse proxy
The private subnet is an extremely useful feature to protect your instances from DDoS, unauthorized access etc., Do not bypass it for the sake of convenience.