GCP Firewall Rules: VPC Firewall vs Firewall Policies, Explained Properly
โJust add a firewall ruleโ sounds simple until youโre staring at a project with forty rules across three different rule systems โ legacy VPC firewall rules, network firewall policies, and hierarchical firewall policies inherited from a folder or organization level โ trying to figure out why a specific packet is or isnโt getting through. GCPโs firewall model has genuinely grown more sophisticated over time, and understanding which system does what, and how they interact when more than one applies to the same traffic, is what separates confident troubleshooting from guessing.
This isnโt a single feature to learn โ itโs three related but distinct systems that compose together, and the composition rules are exactly the part that trips people up.
The Three Firewall Systems
โโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ System โ Scope and purpose โโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโคโ VPC Firewall Rules โ The original, per-VPC rule system โ โโ (legacy) โ still widely used, simple to reason about โโ Network Firewall Policy โ Newer, reusable rule sets attachable to โโ โ one or more VPCs โ supports rule reuse โโ โ across networks โโ Hierarchical Firewall Policyโ Attached at organization or folder level โโโ โ enforces rules across every project โโ โ beneath it, regardless of individual VPC โโ โ configuration โโโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโVPC Firewall Rules are the original system โ still perfectly valid, widely used, and the right starting point for most single-team environments. Network Firewall Policies solve a real limitation of legacy rules: reusability across multiple VPCs without duplicating rule definitions. Hierarchical Firewall Policies solve an organizational problem entirely โ enforcing baseline security rules (block a known-bad range, require specific protocols) across every project in an organization or folder, regardless of what individual project owners configure at the VPC level, similar in spirit to IAM Deny policies but for network traffic instead of API permissions.
Evaluation Order When Multiple Systems Apply
This is the part that actually matters for correct troubleshooting โ when hierarchical policies, network firewall policies, and VPC firewall rules could all theoretically apply to the same traffic, GCP evaluates them in a defined order:
Hierarchical policies evaluate first, top-down from organization to folder, before VPC-level rules get a chance โ this is deliberate, since the whole point of a hierarchical policy is to enforce a guardrail that individual project or VPC configuration canโt accidentally override. A hierarchical policy rule with goToNext: false (the default) stops evaluation entirely at that level; setting goToNext: true explicitly allows evaluation to continue down to lower levels for anything that rule doesnโt match โ worth knowing because itโs the mechanism for โenforce this specific guardrail, but otherwise defer to whatever the project has configured.โ
Creating a Hierarchical Firewall Policy
# Create a policy at the organization levelgcloud compute firewall-policies create \ --organization=123456789 \ --short-name=org-baseline-security \ --description="Organization-wide security baseline"
# Add a rule blocking a known-malicious range everywhere in the orggcloud compute firewall-policies rules create 1000 \ --firewall-policy=org-baseline-security \ --organization=123456789 \ --action=deny \ --direction=INGRESS \ --src-ip-ranges="198.51.100.0/24" \ --layer4-configs=all
# Attach the policy to the organization nodegcloud compute firewall-policies associations create \ --firewall-policy=org-baseline-security \ --organization=123456789Once attached, this rule applies to every VM in every VPC in every project under that organization โ no individual project owner can override it by adding a more permissive rule at the VPC level, because hierarchical policy evaluation happens first and, for a matching rule without goToNext, stops there.
Scoping Rules Precisely with Tags and Service Accounts
Whichever system youโre using, precise targeting is what keeps a growing rule set manageable rather than becoming an unreadable mess:
# Target by network taggcloud compute firewall-rules create allow-web-traffic \ --network=my-vpc \ --direction=INGRESS \ --action=ALLOW \ --rules=tcp:80,tcp:443 \ --target-tags=web-server \ --source-ranges=0.0.0.0/0
# Target by service account โ often the more robust choicegcloud compute firewall-rules create allow-db-access \ --network=my-vpc \ --direction=INGRESS \ --action=ALLOW \ --rules=tcp:5432 \ --target-service-accounts=db-workload@my-project.iam.gserviceaccount.com \ --source-service-accounts=api-workload@my-project.iam.gserviceaccount.comService-account-based targeting is generally more robust than tag-based targeting for security-sensitive rules โ tags are just metadata attached to an instance and anyone with edit permission on that instance can add or remove them, while a service account is tied to the actual workload identity and IAM-controlled. For genuinely sensitive traffic paths (database access, internal admin tools), scoping by service account rather than tag closes a gap where a tag could be added to an unintended instance, deliberately or by mistake, and inherit access it shouldnโt have.
Firewall Rules Logging: Seeing What Actually Happened
A rule that silently blocks traffic nobody expected it to block is one of the most frustrating debugging scenarios in networking โ you know traffic isnโt getting through, but not which rule, across three possible systems, is responsible. Firewall Rules Logging closes that gap by recording the actual decision for matched traffic:
gcloud compute firewall-rules update allow-web-traffic \ --enable-logging{ "connection": {"srcIP": "203.0.113.50", "destIP": "10.0.1.5", "destPort": 443}, "disposition": "ALLOWED", "rule_details": { "priority": 1000, "reference": "network:my-vpc/firewall:allow-web-traffic" }}The log entry names the exact rule, in the exact system, that made the decision โ which turns โwhy is this being blockedโ from a manual process of checking every rule across hierarchical, network, and VPC-level systems by hand into a direct lookup. Enabling logging on rules protecting genuinely important traffic paths, rather than only turning it on reactively during an active incident, means the answer is already sitting in Cloud Logging the moment you need it.
Implied Rules: The Ones You Never Explicitly Created
Every VPC has two implied rules that exist without any configuration on your part, and theyโre worth knowing explicitly because they explain default behavior that otherwise looks unexplained:
โโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโ Implied rule โ Direction โ Behavior โโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโคโ Implied allow egress โ Egress โ All outbound traffic allowedโโ โ โ unless explicitly denied โโ Implied deny ingress โ Ingress โ All inbound traffic denied โโ โ โ unless explicitly allowed โโโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโThese sit at the lowest possible priority, meaning any explicit rule you create โ allow or deny โ takes precedence over them. This is why a brand-new VM with zero custom firewall rules can reach the internet outbound (implied allow egress) but canโt be reached from anywhere inbound (implied deny ingress) until you explicitly create an allow rule โ a default posture thatโs deliberately secure-by-default rather than open-by-default.
Real-World Use Case: Organization-Wide Security Guardrails
A company with dozens of GCP projects, each managed with real autonomy by different application teams, wants to guarantee certain security baselines regardless of what any individual team configures โ no SSH exposed directly to the internet, no traffic from a specific list of known-malicious ranges, mandatory Cloud Armor-fronted traffic for anything public-facing. A hierarchical firewall policy attached at the organization level enforces these guardrails uniformly, while individual teams retain full control over their own VPC-level rules for everything the hierarchical policy doesnโt explicitly govern โ exactly the model of โcentral guardrails, local autonomyโ that scales to a large, multi-team organization without either bottlenecking every team through a central network admin or losing baseline security control entirely.
Best Practices
- Use hierarchical policies for genuine organization-wide guardrails, not routine application rules. Overusing them for rules that really belong at the VPC level creates unnecessary central bottlenecks and defeats the โlocal team autonomyโ half of the model.
- Prefer service-account targeting over tags for security-sensitive rules, reserving tags for broader, lower-sensitivity groupings like โweb-tierโ where the looser control is an acceptable trade-off for simplicity.
- Document the intended evaluation interaction explicitly when hierarchical and VPC-level rules both apply to related traffic โ a rule that appears permissive at the VPC level but is actually blocked by an organization policy is a common source of confused debugging without that context documented somewhere.
- Regularly audit for overly broad
0.0.0.0/0source ranges, especially on rules allowing anything beyond standard web ports โ a genuinely common finding in security reviews thatโs easy to introduce and easy to overlook.
Common Mistakes
Assuming a VPC-level allow rule guarantees traffic gets through. If a hierarchical policy denies it first, the VPC-level allow rule never gets evaluated at all โ this is consistently the most confusing debugging scenario for teams new to hierarchical policies.
Using tags for security-sensitive access control without understanding who can modify them. Anyone with instance-edit permission can add a tag, potentially granting that instance access a rule intended for a different, more trusted set of instances.
Not setting goToNext deliberately. Leaving it at the default (stop evaluation) when the actual intent was โenforce this specific case, defer everything else to lower levelsโ produces unexpected blocking behavior for traffic that should have fallen through to VPC-level rules.
Frequently Asked Questions
Can I see which specific rule, across all three systems, actually decided a packetโs fate? VPC Flow Logs combined with Firewall Rules Logging show which rule matched and made the allow/deny decision, which is the practical way to debug across a multi-system firewall setup rather than manually tracing evaluation order by hand.
Do hierarchical firewall policies cost extra? Theyโre included as part of GCPโs networking capabilities without a separate licensing fee, though โ as with most GCP services โ actual traffic processed still incurs standard network usage charges.
Can a folder-level policy override an organization-level one? No โ evaluation is strictly top-down (organization first, then folder, then VPC-level), and a matching organization-level rule without goToNext stops evaluation before a folder-level policy is even considered.
Is it possible to have conflicting rules that never get resolved? No โ evaluation always produces a deterministic outcome based on priority and evaluation order across the systems; what feels like โconflicting rulesโ is really just the evaluation order producing a result that doesnโt match what someone expected, not an actual unresolved conflict.
Do the implied allow-egress and deny-ingress rules show up when I list firewall rules? No โ theyโre not visible in the standard rule listing since theyโre not user-created objects, which is exactly why theyโre worth knowing about explicitly rather than discovering their existence only when troubleshooting unexpected default connectivity behavior.
A Final Note on Change Management
Firewall changes, across any of the three systems, deserve the same review discipline as application code deployments โ a firewall rule modified directly in the console under time pressure, without a second pair of eyes, is exactly the kind of change that occasionally opens something that shouldnโt be open, or closes something that breaks a dependency nobody remembered existed. Treating firewall configuration as version-controlled infrastructure (via Terraform or Deployment Manager, both of which support GCPโs firewall resource types) rather than console point-and-click changes gives you both a review step before the change takes effect and a clean audit trail afterward, which matters considerably more for network security controls than it might for a routine, low-stakes configuration change elsewhere.
Summary
GCPโs firewall model rewards understanding the evaluation order across hierarchical policies, network firewall policies, and legacy VPC firewall rules before you need to debug a confusing โwhy isnโt this traffic getting throughโ situation under time pressure. Hierarchical policies are the right tool for genuine organization-wide guardrails that shouldnโt be overridable by individual teams; VPC-level rules (via either legacy or network firewall policy) remain the right tool for everything else. Getting the targeting precise โ service accounts for sensitive paths, tags for broader groupings โ and understanding which system evaluates first is what keeps a growing rule set debuggable instead of becoming exactly the kind of tangled configuration that takes an afternoon to untangle during an actual incident, rather than the five-minute lookup it should have been all along.