A single Web ACL rarely relies on just one rule. Real configurations combine an AWS Managed Rule Group for broad coverage with a handful of custom rules for app-specific logic - a blocked country, a suspicious header, a known bad query string pattern. This page shows how those pieces fit together in one Rules array, and how to package custom rules into a reusable Rule Group.
Build a Web ACL with two rules: a managed group for generic protection, and a custom ByteMatchStatement blocking a specific header value. Priority decides evaluation order.
Managed-group rules use OverrideAction, not Action - the group's own internal rules decide allow/block, and OverrideAction only lets you demote all of them to Count. Custom rules use Action directly. TextTransformations normalizes the input (here, lowercasing) before the match runs, which avoids simple case-based evasion.
Package custom rules into a RuleGroup so multiple Web ACLs can reference the same logic without copy-pasting it. This adds a SqliMatchStatement for basic SQL injection detection on a query parameter.
Capacity is a WAF-computed cost unit budget, not a request count - each statement type consumes a fixed number of capacity units, and you must estimate (or use CheckCapacity) a value high enough to hold your rules. A Web ACL references this group with a RuleGroupReferenceStatement { ARN: ruleGroupArn } instead of repeating the rules inline.
A rule's Statement can be a single match type, or a logical combinator (AndStatement, OrStatement, NotStatement) wrapping several. For example, "block SQLi-looking input, but only from outside North America" combines a SqliMatchStatement and a NotStatement around a GeoMatchStatement inside an AndStatement. This lets a handful of primitive statement types express fairly specific policies without a full custom rule language.
ManagedRuleGroupStatement accepts an optional ScopeDownStatement - a nested statement that limits which requests the managed group even evaluates. This is how you apply AWSManagedRulesCommonRuleSet only to /api/* paths, for instance, leaving static asset requests un-evaluated by that group to save capacity and avoid false positives.
Rules run in ascending Priority order, and the first rule with a terminating action (Block or explicit Allow) stops evaluation. Count is non-terminating - a counted rule logs a match but lets evaluation continue to the next rule. This is why teams stage new rules with Count before flipping them to Block: it exposes what a rule would have blocked without actually blocking it.
Inline rules (defined directly in a Web ACL's Rules array) are simplest when a rule is specific to one ACL. A RuleGroup is worth the extra object when the same logic (say, a company-wide blocklist of bad IPs or header patterns) needs to apply identically across several Web ACLs - update the group once, and every referencing ACL picks up the change.
Forgetting LockToken on update.UpdateWebACL and UpdateRuleGroup both require the current LockToken from a fresh GetWebACL/GetRuleGroup call; a stale token is rejected to prevent lost updates.
Confusing Action and OverrideAction. Custom rules use Action; rules that reference a managed group or rule group use OverrideAction. Using the wrong one is a validation error.
Underestimating Capacity. Adding rules to a RuleGroup after the fact can exceed the capacity you provisioned at creation; capacity is fixed at creation and cannot be raised later, only lowered implicitly by removing rules.
Skipping TextTransformations. A ByteMatchStatement without a transformation misses trivially obfuscated input (mixed case, URL encoding); most production rules include at least LOWERCASE or URL_DECODE.
Priority collisions. Two rules sharing the same Priority value are rejected outright - each must be unique within the ACL or RuleGroup.
Going straight to Block on new rules. Deploying an untested custom rule as Block risks blocking legitimate traffic; stage as Count first (see the logging page for how to read the results).
AWS Managed Rule Groups alone, with no custom rules, cover a large share of generic threats and are the lowest-maintenance option for teams without dedicated security engineering time.
Custom rules only, skipping managed groups, gives full control but means you own detecting every known attack pattern yourself - rarely worth it compared to layering on AWS's maintained groups.
AWS Firewall Manager centrally pushes a common Web ACL policy across many accounts and resources in an AWS Organization, useful once you have more than a handful of ACLs to keep consistent.
A third-party managed rule group from AWS Marketplace can supplement AWS's own groups for specialized coverage (a specific CMS, a specific compliance regime) referenced the same way via ManagedRuleGroupStatement with a different VendorName.
Most production Web ACLs land on a mix: one or two AWS Managed Rule Groups for baseline coverage, plus a small number of custom or shared-RuleGroup rules for anything specific to the application.
What is the difference between Action and OverrideAction?
Action is used on custom rules you define directly (Allow, Block, Count). OverrideAction is used on rules that reference a managed rule group or rule group, and can only demote the group's own actions to Count - it cannot force a block.
How do I combine multiple conditions in one rule?
Use a logical statement (AndStatement, OrStatement, NotStatement) that wraps two or more nested statements, such as an SQLi match combined with a geographic exclusion.
What does Capacity mean on a RuleGroup?
It is a fixed budget of WAF-computed cost units set at creation time. Each statement type consumes a certain number of units, and the total across all rules in the group cannot exceed the declared capacity.
Can I scope a managed rule group to only part of my traffic?
Yes, with a ScopeDownStatement nested inside the ManagedRuleGroupStatement, limiting evaluation to requests matching an additional condition like a URL path.
Why was my UpdateWebACL call rejected?
Most commonly a stale or missing LockToken. Call GetWebACL immediately before UpdateWebACL and pass the token it returns.
Should I test a new rule as Count before Block?
Yes, for anything not a well-tested AWS Managed Rule Group. Deploy as Count, review sampled requests or logs to confirm it only matches what you intend, then switch to Block.
When should I use a RuleGroup instead of inline rules?
When the same rules need to apply across more than one Web ACL. A RuleGroup is a single object you update once; every Web ACL referencing it picks up the change automatically.