Use security groups as the primary control around workloads. Reach for a network ACL when the requirement is explicitly subnet-wide, needs an IP-based deny rule, or calls for an additional coarse-grained guardrail.
“Security group or network ACL?” looks like a vocabulary question. In an architecture, it is a boundary question.
A security group follows the resource it is associated with, typically through an elastic network interface. A network ACL is associated with a subnet and evaluates traffic entering or leaving that subnet. Once you start with that boundary, the rest of the decision becomes much easier.
The four differences that matter
| Decision | Security group | Network ACL |
|---|---|---|
| Boundary | Associated resource or network interface | Every resource in an associated subnet |
| Connection tracking | Stateful | Stateless |
| Rule types | Allow rules only | Allow and deny rules |
| Evaluation | All applicable rules are considered | Lowest-numbered matching rule wins |
AWS recommends using security groups as the primary mechanism for VPC network access and using network ACLs when a coarse-grained, stateless layer is useful. That is a better design rule than treating the two controls as interchangeable firewalls.
Why stateful changes the answer
Suppose a web server’s security group permits inbound HTTPS on TCP port 443. Because the security group is stateful, response traffic for that allowed connection can leave automatically. You do not need to create a second rule for the client’s temporary return port.
A network ACL does not remember the connection. If its inbound rules admit a request, its outbound rules must also admit the response. For TCP clients, that often means accounting for ephemeral ports. A design can look correct in one direction and still fail on the return path.
Scenario: allow only the load balancer
Your application instances should accept HTTPS only from an Application Load Balancer. Use a security-group rule whose source is the load balancer’s security group. That relationship follows the workloads as addresses and instances change.
Scenario: block one hostile CIDR across a subnet
The requirement is a subnet-wide explicit deny for a known source range. A network ACL fits because it can apply a deny rule to every resource in the subnet. Make sure the deny has a lower rule number than a broader allow rule, because the first match wins.
Why “network ACL for more security” is incomplete
Adding another control does not automatically improve a design. A custom network ACL can break health checks, return traffic, and service connectivity if its inbound and outbound rules do not work as a pair.
A network ACL is useful as defense in depth when the subnet really needs a common guardrail. It is less useful when it merely duplicates every security-group rule and creates a second rule set that can drift.
The decision sequence I use
- Identify the boundary. Is the rule about a workload, a tier, or every resource in a subnet?
- Look for an explicit deny. Security groups do not have deny rules; network ACLs do.
- Check return traffic. A stateless control requires a valid rule in both directions.
- Check how the source is expressed. A security-group reference often survives scaling better than a list of instance IP addresses.
- Prefer the smallest control that satisfies the requirement. Do not add subnet-wide complexity to solve a workload-specific problem.
The memorable shorthand—security groups are stateful, network ACLs are stateless—is true. The architectural skill is recognizing why that fact changes the design in front of you.
Official AWS references
KEEP PRACTICING THE DECISION
Learn the concept, then test the edge case.
The Solutions Architect Associate course in TutorialRepo combines guided lessons, scenario questions, review, and course-aware explanations.