Unless required, your instances should not be publicly exposed to the internet. When your instances are on the internet, you have to assume they will be attacked at some stage.
This means most of your workloads should run on instances in private subnets. Private subnets are those that are not connected directly to the internet.
To give your private instances access to the internet, you use NAT. A NAT gateway allows your instances to initiate a connection to the internet, without allowing connections from the internet.