VPC In A Nutshell
VPC is defined as a virtual private cloud. Please refer to our homepage to understand more about the cloud.
Before we delve into the artifacts of the VPC we need to understand two fundamental components of Amazon and their data centres.

VPCs In Detail
Region
A Region is a geographic location within a country in amazon terms
eu-west-2 being London where amazon host their data centers.
https://docs.aws.amazon.com
/general/latest/gr/rande.html
Availability Zones
Within London AWS can have multiple data centres, say for instance they can host a data Center in Fulham London and another in Camden London.
The purpose of this being to ensure availability of Amazon services within a region in-case there is a disaster or outage within a single data centre.
All these data centres are linked together through the Amazon network backbone.
Types of VPCs
When we create an AWS service account, by default Amazon gives us access to what you would class as default VPCs within each region.
We can also create our own VPCs based on requirements and use cases.
Each availability zone will consist of its network address range which is known as a subnet. We can create our own VPC and subnets, the IP address ranges for these subnets need to be of a certain class. Routing between these subnets are handled by route tables, we can also control the flow of traffic between the subnets via a network access control list NACLs, that are stateless firewalls.
Subnets can be further classified as private and public. Public subnets are accessible via the internet through the AWS internet gateway. Private subnets cannot be accessed externally, unless we utilize a jumpbox hosted on a public subnet which has access to the private subnet or via a nat gateway, the routes within the internal route table (AWS VPC routers) enable internal traffic routing within these subnets, In any situation all external traffic has to traverse through the internet gateway.

NACLs and Security Groups
NACls (Network Access Control Lists)
NACLs are firewalls with specific rules and precedence that enable one to either block or allow traffic to and from a subnet. These rules can be configured bi directionally. For example allowing traffic from subnet A to B on port number, while denying traffic from the subnets B to A on the same port number. NACLs are known as stateless since they don't have logic to understand an incoming request to return a packet to the sender upon requests by opening a return port for that specific request. By default, NACLs are configured to allow all ingress and egress traffic. (This can be a security risk hence ensure that NACLs are always configured to allow or deny traffic based on the use case.
Security Groups
Security groups are classed* as stateful, they operate at the instance level within your VPC. By default they don't allow any incoming and outgoing traffic.
For instance if you would like your EC2 instance to communicate with your RDS instance you would need to open ports on your security groups for communication.
As a best practice I prefer to have security groups assigned to each service, and the communication is established between these groups at the security group level.
For instance, assign security group A to RDS and Security Group B to the EC2 instance then I would open the required ports between security group A and security group B. this ensures a SOA architecture even for simple services.
In practice I 've experienced that these security groups are not as stateful as they are supposed to be.
If I open port 22 on a security group it will definitely allow ingress and support egress traffic (return traffic) on port 22 the required behaviour.
(A)
Now if I already have an existing TCP client connection and block the same port on the security group, the initial connection that I had with the service will continue to exist until I terminate the connection at the client end. (Which I think is a bit of a security risk, in case you need to terminate a connection immediately for some reason, it's worth keeping this in mind).
(B)
There is also a requirement to open ephemeral ports in security groups, if a client sends a request on a specific port and the application responds via an ephemeral port, security groups are not able to logically understand that they need to open that specific ephemeral port for outgoing traffic. Hence these ephemeral port ranges need to be continuously open to allow return traffic based on the OS and other criteria.

VPC & Global Services
As I mentioned earlier there are many AWS services and the list keeps building up. Some of these services can be contained within a VPC and some of these services are Global. To ensure security of client data we need to understand initially whether these are global or VPC services. By default none of these services have access to each other, access has to be granted via Security "IAM".

IAM
Identity and Access Management (IAM)
Is the core mechanism of AWS, that grants access to a service within AWS.
IAM consists of the following:
Users
An entity that can be created to be granted either AWS console or programmatic access to a AWS service.
Groups
Groups can contain a collection of users, the benefit being that the group can be granted access to the resource/s and users can be added to or removed from these groups. Groups enable granularity of access to resources.
Roles
This is the best access mechanism within AWS, a role can be assigned to a service or multiple services. And the service can be given access to another service via a role.
Policies
Policies enable roles to be granted granular access to resources. A policy is a json document specifying a set of permissions to a resource.
The json object within the document consists of the following attributes.
The version characterised by AWS.
Effect, being allow or deny access to the resource
Action, the actions that can be performed on the service
Resource, ARN, the Amazon resource name of the specific resource the action can be performed on. Following is an example that allows a role to : perform the following actions :
Create log groups, create log streams and put log events on the resource AWS CloudWatch Logs.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
}
]
}