AWS provides you with all the tools to build, secure, and manage your Cloud infrastructure globally. It’s vital to understand the different components involved in architecting a secure, scalable, and fault-tolerant Cloud environment. This blog will focus on the Virtual Private Cloud (VPC) and the use of Security Groups and Network Access Control Lists (NACLs) to control and restrict traffic.
Virtual Private Cloud
A VPC in AWS is an isolated network within your AWS account. You define the IP address ranges (via CIDR blocks) and configure various components to control how your resources communicate – both internally and externally. AWS provides a default VPC for quick testing, but it’s not suitable for production environments, where tighter security and control are essential.
A VPC is segmented into subnets, which are smaller IP address ranges within the VPC’s CIDR block. Subnets allow you to group resources based on accessibility and function. Typically, public subnets are used for internet-facing resources (like load balancers or bastion hosts), while private subnets house backend systems that shouldn’t be directly exposed (such as databases or internal services).
Each subnet is associated with a specific Availability Zone, enabling high availability and fault tolerance. By deploying resources across multiple zones, you can ensure your application remains operational even if one zone fails. Effective subnet planning is critical for controlling traffic flow, managing IP allocation, and enforcing security boundaries between application layers.
While subnets define the structural layout of your network, Security Groups govern how traffic flows between individual resources – within the VPC and from external sources.
Security Groups
Once the VPC and subnets are in place, traffic between resources is secured using Security Groups. These act as virtual firewalls for EC2 instances, load balancers, and other VPC resources. They control inbound and outbound traffic based on user-defined rules involving IP ranges, protocols, and ports.
Security Groups are stateful – if an inbound request is allowed (e.g., an HTTP request on port 80), the corresponding outbound response is automatically permitted, even if no explicit outbound rule exists. This simplifies configuration but still requires careful rule definition to prevent unwanted exposure.
By default, Security Groups deny all traffic unless explicitly allowed through rules.
There are two key use cases for security groups in a production environment:
Restricting Traffic Between the Internet and Your VPC
Public-facing resources like load balancers and bastion hosts should only allow required ports (e.g., 443 for HTTPS) and trusted IP ranges. This reduces the attack surface and ensures only legitimate traffic reaches your services.Restricting Traffic Within Your VPC
Internal resources shouldn’t all communicate freely. For instance, application servers may need database access, but not all services should have the same privileges. Security Groups help enforce role-based access control and network segmentation, reducing the risk of lateral movement in case of a compromise.
Security Group Best Practices:
- Use the principle of least privilege: Only allow traffic that is required.
- Create security groups per role: Rather than reusing a single security group across different resources, ensure each group is designed for a specific purpose (e.g. “app-server”, “database”).
- Limit IP ranges: Avoid using overly permissive IP ranges (e.g.,
0.0.0.0/0
), except when absolutely necessary, and restrict access to trusted IPs whenever possible. - Use Elastic Load Balancers (ELBs): Expose only the ELB to the Internet. Backend instances should only accept traffic from the ELB Security Group.
- Use Internal-Only Security Groups: For backend servers like databases, allow traffic only from the application server Security Group (not from any IP or CIDR range).
- Group Communication by Function: Allow communication only between necessary components. For example, only allow database ports (e.g., TCP 3306 for MySQL) from app servers.
- Regularly audit and clean up unused Security Groups: Especially after decommissioning resources.
- Use Security Group references: Instead of static IPs, to make access control more dynamic and maintainable.
- Enable VPC Flow Logs: Use VPC Flow Logs to capture information about IP traffic going to and from network interfaces for further analysis.
Network Access Control Lists (NACLs)
While security groups protect individual instances, Network Access Control Lists (NACLs) are used to manage inbound and outbound traffic at the subnet level. NACLs are stateless, meaning both inbound and outbound traffic must be explicitly allowed. If you deny inbound traffic, the corresponding outbound traffic must also be explicitly denied.
NACLs provide an additional layer of protection by allowing or denying traffic at the subnet boundary. This is especially important for enforcing network segmentation, ensuring that traffic between public and private subnets is properly controlled, or blocking potentially malicious traffic before it even reaches your EC2 instances.
Best Practices for NACLs:
- Use NACLs to define broad traffic rules at the subnet level. For example, ensure that only necessary subnets have access to the internet, and tightly control the flow of data between subnets.
- Implement explicit deny rules — NACLs allow you to define both “allow” and “deny” rules, so make sure to explicitly deny any unnecessary traffic to reduce exposure.
- Order Rules Carefully: NACL rules are evaluated in order, from lowest to highest rule number. Place most specific rules first.
- Separate Public and Private Subnets: Use different NACLs for public subnets (e.g., ELBs) and private subnets (e.g., app servers, databases).
- Regularly review and update NACLs as part of your network security audits to ensure they align with your security posture.
Securing Traffic Within Your VPC
To establish robust internal processes for securing traffic within your VPC, here’s a checklist of recommended actions:
Use Security Groups to Restrict Traffic Between the Internet and the VPC:
For every public-facing resource, define strict security group rules that allow traffic only from specific IPs and only on required ports.Implement Security Groups to Restrict Traffic Within the VPC:
For internal communication, set up security groups that restrict access to only necessary services. For example, only allow application servers to communicate with databases, and enforce that other services cannot access the database directly.Leverage NACLs to Restrict Inbound and Outbound Traffic at the Subnet Level:
Apply NACLs to restrict traffic at the subnet level, especially between public and private subnets. Ensure that only trusted sources are able to communicate with sensitive resources like databases.
By configuring Security Groups and NACLs properly, you can ensure that both external and internal traffic is tightly controlled, minimising the potential attack surface and reducing exposure to threats. Regular audits and continual updates to these configurations are essential to maintaining a secure and scalable Cloud infrastructure.

Through our AWS Well-Architected Framework (WAF) reviews, we help organisations strengthen their infrastructure by embedding resilience, operational excellence, and automated best practices into every layer of their Cloud environment.
As an AWS Advanced Tier Partner, we can also help unlock AWS funding programmes to subsidise your review, making it easier to identify risks, strengthen recovery processes, and build customer trust before an incident ever occurs.
To set up a free AWS WAF consultation with us, visit our information page, or check out our AWS Marketplace listing below.
