Most engineers think…
Most engineers hear "GCP firewall" and "Cloud Armor" and assume they're two names for the same thing — or that turning on Cloud Armor means you can skip writing firewall rules.
Wrong — and that gap is exactly how breaches spread. They operate at different layers and on different traffic. Cloud Armor is an L7 web-application firewall + DDoS service that sits at the edge, on the external Application Load Balancer, and inspects the content of HTTP requests (it can read a SQLi payload). VPC firewall rules are L3-L4, attached to the VPC network, and control which workloads can talk to which — including the east-west, VM-to-VM traffic Cloud Armor never even sees. Cloud Armor stops the web attack at the front door; the VPC firewall stops the attacker walking sideways once they're inside. You need both.
① Two layers of GCP network defence
Picture Sneha, an L1 cloud-security engineer at Flipkart, on her first on-call week. Two alerts land within the hour. The first: a burst of SQL-injection requests hammering the public checkout site. The second, later: one of the web servers behind that site has started probing TCP 5432 on the database subnet — a host that should never initiate database connections directly. Same incident, but the two problems live at two completely different layers, and Google Cloud hands her a different tool for each.
The first is a north-south, application-layer problem: bad HTTP coming from the internet into the app. The right guard is Cloud Armor — a WAF that runs in Google's edge, attached to the external Application Load Balancer. It reads the request itself and can recognise a SQLi or XSS string before it ever touches a server.
The second is an east-west, network-layer problem: one internal workload talking to another it shouldn't. The right guard is the VPC firewall — stateful L3-L4 rules attached to the VPC network. The firewall doesn't know or care what HTTP is; it decides whether the web tier is even allowed to open a connection to the database tier. Cloud Armor never sees that VM-to-VM traffic at all.
Here's the shape to hold in your head. The VPC firewall is built into every VPC and is always on: it has an implied deny-ingress rule so nothing reaches a VM unless a rule you wrote says yes. Cloud Armor is opt-in: you create a security policy and attach it to your load balancer's backend service. One protects the perimeter of your app; the other segments the inside.
Edge vs inside, in one tap each
Tap each card — this is the mental split every GCP network question (and interview) tests.
L7 WAF + DDoS on the external Application LB. Reads the HTTP request. So: it stops SQLi/XSS/bots before any VM is touched.
L3-L4 stateful rules on the VPC. Matches IP/port/protocol per target. So: it decides which workloads may talk — east-west containment.
Cloud Armor = north-south (internet↔app). Firewall = mostly east-west (VM↔VM). So: a breach needs you to win on both axes.
Firewall: ingress denied, egress allowed, by implied rules. Cloud Armor: opt-in, attach a policy. So: the firewall is already guarding; Armor you must switch on.
Think of a Mumbai housing society. Cloud Armor is the main gate with the security guard and the visitor register: every outsider is screened at the boundary, and a known troublemaker (a SQLi bot) is turned away before they even enter the compound. The VPC firewall is the lock on each individual flat door: even a person already inside the compound can't just walk into your flat. A delivery boy (the web tier) might be allowed up to the 4th floor (the db tier) only for a specific reason. Screen at the gate and lock the doors — relying on one alone is how trouble spreads.
Rahul at Infosys says: "We put a Cloud Armor policy on our load balancer, so we don't really need VPC firewall rules between our app and database tiers, right?" What's the correct response?
Pause & Predict
Predict: an attacker fully compromises one web-tier VM that's behind Cloud Armor. Cloud Armor is doing its job at the edge. Why might the VPC firewall still be the thing that saves you? Type your guess.
② VPC firewall done right
Let's make the VPC firewall second nature, because most production incidents are a firewall rule that was too broad or in the wrong order. Three facts anchor everything. One: rules have a priority from 0 to 65535 — lower number wins, and the first matching rule stops the search (first hit, not best fit). Two: firewall rules are stateful — allow the inbound and the return traffic is automatically allowed; you rarely write the reply rule. Three: every VPC ships with two implied rules you can't delete — deny-ingress and allow-egress, both at priority 65535.
That third fact has a sharp edge. Ingress is denied by default — good. But egress is allowed by default. So a freshly compromised VM can, out of the box, phone home to a command-and-control server or exfiltrate data outbound, and no rule stops it. Mature teams therefore add deny-by-default egress: a low-priority deny to 0.0.0.0/0, then narrow allow rules above it for exactly the destinations the workload needs.
Now the rule that separates juniors from people who get hired: target by tag or service account, not by source IP. A network tag like web is convenient but it's just a string any editor can stick on a VM. A service account is an IAM-controlled identity — it says what the VM is, and only IAM admins can change it. For production least-privilege, prefer --target-service-accounts. Either way, the rule then follows the workload, not a fragile IP that changes when the VM is recreated.
gcloud compute firewall-rules create allow-web-to-db \ --network=prod-vpc \ --direction=INGRESS \ --action=ALLOW \ --rules=tcp:5432 \ --source-service-accounts=web-sa@my-proj.iam.gserviceaccount.com \ --target-service-accounts=db-sa@my-proj.iam.gserviceaccount.com \ --priority=1100
Creating firewall...done. NAME NETWORK DIRECTION PRIORITY ALLOW DENY DISABLED allow-web-to-db prod-vpc INGRESS 1100 tcp:5432 False sourceServiceAccounts: web-sa@my-proj.iam.gserviceaccount.com targetServiceAccounts: db-sa@my-proj.iam.gserviceaccount.com
Symptom: you created an allow tcp:443 rule, the VM still refuses connections. Two classic causes. (1) A higher-priority deny rule (lower number) matches first — remember first hit, not best fit; check with gcloud compute firewall-rules list --sort-by=priority. (2) Your rule's target tag/SA doesn't actually match the VM — the rule exists but applies to nothing. Also: a hierarchical firewall policy at the org or folder level can deny above your project's rules entirely, and you may not even see it from inside the project.
That last point scales up to org-wide guardrails. A hierarchical firewall policy is attached at the organisation or folder level and is evaluated before any project's own rules, so a security team can mandate, say, "deny inbound RDP 3389 from the internet everywhere, no exceptions" across the whole org. There are also global and regional network firewall policies for consistent rule sets within a VPC. Note one gotcha: hierarchical policies can't target by instance network tag — they target VPC networks and service accounts.
Aditya at TCS must allow only the app tier to reach the cache tier on TCP 6379, in a way that survives VMs being recreated and can't be loosened by a developer with instance-edit rights. Best targeting?
Pause & Predict
Predict: your VPC has only an 'allow tcp:443 from 0.0.0.0/0 to tag:web' rule and the two implied rules. A compromised web VM tries to curl a malware host on the internet over port 443 outbound. Does the firewall stop it? Why or why not? Type your guess.
deny to 0.0.0.0/0 on egress, then allow only the specific destinations (e.g. your package mirror, Google APIs) the workload genuinely needs.③ Cloud Armor — the edge WAF & DDoS layer
Now the front gate. A Cloud Armor security policy is an ordered list of rules — each with a priority, a match condition, and an action — that you attach to a load-balancer backend service. When a request hits the external Application Load Balancer, Cloud Armor evaluates it top-down (again lowest priority number first) and the first matching rule's action wins. At the very bottom sits a default rule at priority 2147483647 — set to allow out of the box, which you typically keep as the catch-all.
The star feature is the preconfigured WAF rules. Instead of hand-writing attack signatures, you reference a named expression. evaluatePreconfiguredExpr('sqli-v33-stable') turns on the whole SQL-injection rule set; evaluatePreconfiguredExpr('xss-v33-stable') the cross-site-scripting set. These are built on the OWASP Core Rule Set and cover most of the OWASP Top 10 — SQLi, XSS, local/remote file inclusion, remote code execution and more.
Each preconfigured rule has a sensitivity level (1-4). Higher sensitivity catches more attacks but raises false positives; lower sensitivity uses only high-confidence signatures. You can also tune a rule to exclude specific OWASP rule IDs that trip on your legitimate traffic (e.g. a field that legitimately contains characters the WAF reads as XSS). The skill here is balance: too tight and you block real customers; too loose and you miss the attack.
Beyond signatures, Cloud Armor brings volumetric and behavioural defences. Rate-limiting gives you two actions: throttle (slow a noisy client down to a request rate) and rate-based-ban (temporarily ban a client that blows past the limit). You can key the limit on source IP, an HTTP header, or a JA4 fingerprint. Bot management can challenge suspected bots, and geo-based rules (origin.region_code == 'IN') and named IP/address lists let you allow or deny whole countries or known-good/bad IP ranges in one place.
The smartest layer is Adaptive Protection — machine learning that watches each backend service for anomalous Layer-7 traffic in real time. When it spots an HTTP flood, it does three things: alerts you, generates a signature describing the attack, and suggests a custom rule you can deploy with one click. This is what stands between you and an L7 DDoS that no static signature would have caught — and Google's edge has used exactly these mechanisms to absorb record floods peaking above 398 million requests/second (the HTTP/2 Rapid Reset class, CVE-2023-44487).
# 1) policy + attach to the backend service
gcloud compute security-policies create web-policy --description "edge WAF for checkout"
gcloud compute backend-services update checkout-bes --global --security-policy web-policy
# 2) block SQL injection using the OWASP preconfigured rule (preview, watch logs first)
gcloud compute security-policies rules create 1000 \
--security-policy web-policy \
--expression "evaluatePreconfiguredExpr('sqli-v33-stable')" \
--action deny-403 --preview
# 3) rate-based ban: >100 req/min from one IP gets a 10-min 429
gcloud compute security-policies rules create 1200 \
--security-policy web-policy --src-ip-ranges "*" \
--action rate-based-ban --rate-limit-threshold-count 100 \
--rate-limit-threshold-interval-sec 60 --ban-duration-sec 600 \
--conform-action allow --exceed-action deny-429 --enforce-on-key IPCreated [.../securityPolicies/web-policy].
Updated [.../backendServices/checkout-bes].
Created rule [1000] (preview) action: deny-403 expr: evaluatePreconfiguredExpr('sqli-v33-stable')
Created rule [1200] action: rate-based-ban key: IP threshold: 100/60s ban: 600sA new WAF rule deployed straight to enforce can block paying customers on day one. So deploy it with --preview first: Cloud Armor evaluates the rule and logs what it would have blocked without actually blocking anything. Watch the request logs (Logging → resource.type=http_load_balancer, field enforcedSecurityPolicy / previewSecurityPolicy) for a few days. If only real attacks would have been blocked, flip it to enforce with rules update 1000 --security-policy web-policy --no-preview. Never enforce a fresh signature blind.
Priya at PhonePe needs to block obvious SQL-injection attempts to the public API but is terrified of breaking a legitimate field that contains SQL-like text. What's the safe rollout?
Pause & Predict
Predict: an attacker launches an HTTP flood that mimics real traffic — valid URLs, varied IPs, no obvious SQLi or XSS. Your preconfigured OWASP rules see nothing wrong. Which Cloud Armor feature is designed for exactly this, and what does it hand you? Type your guess.
④ Putting it together — block an SQLi flood + a bad bot
Time to wire both layers into one defence. The design pattern you'll see on the job: Cloud Armor at the edge for L7 and DDoS on the public Application Load Balancer, and VPC firewall rules inside for east-west segmentation between every tier. Cloud Armor stops the attack arriving; the firewall stops it spreading. Let's walk a real incident through both.
▶ Watch one malicious request hit the stack
A bot from a flagged ASN sends a SQL-injection payload to the Flipkart checkout API, then a flood of lookalike requests. Follow what each layer does. Press Play for the healthy path, then Break it to see the failure.
Karthik at ICICI faces this
Karthik, an L2 engineer, gets paged: the public banking portal is slow and the WAF dashboard shows a spike of SQLi-pattern requests plus a flood of near-identical GETs from a handful of ASNs in one region the bank doesn't serve.
Two overlapping attacks: an injection probe (L7 content) and a volumetric bot flood (L7 volume) from a specific geography. A single control won't cleanly handle both — he needs layered Cloud Armor rules, ordered by priority.
He opens the Cloud Armor policy and confirms the SQLi rule is enforcing (not preview), checks Adaptive Protection alerts for the flood signature, and reads the geo field origin.region_code in the LB logs.
Google Cloud Console → Network Security → Cloud Armor policies → web-policy → Rules / Adaptive ProtectionKeep sqli-v33-stable enforcing (deny-403); add a rate-based-ban keyed on IP for the flood; add a geo deny rule for the non-served region (origin.region_code == 'XX' → deny-403) at a higher priority; deploy Adaptive Protection's suggested signature for the residual.
LB latency returns to baseline; enforcedSecurityPolicy logs show deny-403 on the SQLi and geo rules and 429s on the rate-banned IPs; legitimate Indian customer traffic is unaffected.
Two gotchas bite everyone once. (1) Ordering: Cloud Armor (and the VPC firewall) is first-match-by-priority — if a broad allow sits at a lower priority number than your deny, the deny never runs. Always put specific deny/ban rules at lower numbers than broad allows. (2) The preview trap: a rule left in --preview looks active on the dashboard but only logs — it blocks nothing. If 'my WAF rule isn't blocking the attack,' check it isn't still in preview before anything else.
For your certification path, this lesson lands squarely on the Professional Cloud Security Engineer blueprint — specifically the "configure network security" domain (roughly 20-25% of the exam), which calls out VPC firewall rules, Cloud Armor, DDoS protection and configuring web application firewalls by name. A favourite exam (and interview) trap is exactly the myth we opened with: knowing that Cloud Armor is L7-at-the-edge and the VPC firewall is L3-L4-east-west, and that you need both, answers a surprising share of the network-security questions outright.
Cold, in 30 seconds: where does each control attach (Cloud Armor → external Application LB backend service; VPC firewall → the VPC network); the default posture (ingress denied, egress allowed via implied rules at 65535); how to target least-privilege (by service account, not IP); the two rate-limit actions (throttle, rate-based-ban); and why you always preview before enforce. If you can say all five without notes, you're ready for the next lesson and the network-security exam domain.
An interviewer asks Meera: "Walk me through defending a public GCP web app against both a SQL-injection campaign and an HTTP flood, while containing a possible breach." Which answer is strongest?
🤖 Ask the AI Tutor
Tap any question — instant, scoped to this lesson. No login, no waiting.
Pre-curated from GCP docs + community Q&A, scoped to this lesson. For a live prod issue, paste your export into chat.techclick.in.
📝 Wrap-up assessment — six more
You've answered 4 inline. Six left. 70% (7 of 10) marks the lesson complete on your profile. Tap Submit all answers at the end.
🧠 In your own words
Type one line: In one line, why does a Cloud Armor policy on your load balancer not remove the need for VPC firewall rules between your tiers? Then compare to the expert version.
🗣 Teach a friend
Best way to lock it in — explain it in one line to a teammate. Tap to generate a paste-ready summary.
📖 Glossary
- VPC firewall rule
- Stateful L3-L4 rule attached to a VPC network; allows/denies traffic to target VMs by priority, protocol, port and source.
- Cloud Armor
- Google's edge WAF + DDoS service. A security policy attaches to an external Application Load Balancer backend service and inspects L7 HTTP.
- Priority
- Integer 0-65535 on a firewall rule; lower number wins and the first matching rule stops the search (first hit, not best fit). Default is 1000.
- Implied rules
- Two undeletable VPC rules at priority 65535: deny-ingress (block inbound unless allowed) and allow-egress (permit all outbound unless denied).
- Network tag
- Arbitrary string label on a VM used to target firewall rules. Convenient but any instance-editor can change it — weaker for security.
- Target service account
- The IAM identity a VM runs as, used to target firewall rules. Controlled by IAM, so it's the stronger least-privilege target.
- Hierarchical firewall policy
- Firewall policy at the org or folder level, evaluated before per-project VPC rules — central guardrails projects can't override. Targets networks/SAs, not tags.
- Security policy
- A named Cloud Armor policy — an ordered list of allow/deny/throttle rules with a default rule at priority 2147483647 (allow).
- Preconfigured WAF rule
- Ready-made Cloud Armor rule based on the OWASP CRS, enabled via an expression like evaluatePreconfiguredExpr('sqli-v33-stable').
- Rate-based ban
- Cloud Armor action that temporarily bans a client (by IP/header/JA4) once it exceeds a request-rate threshold; throttle just slows it.
- Adaptive Protection
- Cloud Armor ML that detects anomalous L7 traffic per backend service, alerts, and suggests a custom WAF rule to block an L7 DDoS.
- Preview mode
- Deploys a Cloud Armor rule that is evaluated and logged but not enforced — so you can spot false positives before blocking real traffic.
📚 Sources
- Google Cloud — "VPC firewall rules overview" (priority 0-65535 lowest-number-wins, stateful rules, implied deny-ingress + allow-egress at 65535, default-network rules default-allow-ssh/rdp/icmp/internal, targeting by network tag vs service account). cloud.google.com/firewall/docs/firewalls
- Google Cloud — "Create and manage security policies" + "Cloud Armor preconfigured WAF rules overview" (gcloud compute security-policies create/rules create, --action allow|deny-403/404/502|throttle|rate-based-ban, --preview, attach via backend-services update --security-policy, default rule priority 2147483647, evaluatePreconfiguredExpr('sqli-v33-stable')/'xss-v33-stable', OWASP CRS sensitivity 1-4). cloud.google.com/armor/docs/configure-security-policies · cloud.google.com/armor/docs/waf-rules
- Google Cloud Community / r/googlecloud — practitioner threads on 'firewall rule not working' (first-hit priority, target tag/SA mismatch, hierarchical policy denying above the project) and Cloud Armor preview-vs-enforce confusion. cloud.google.com/firewall/docs/using-firewalls · reddit.com/r/googlecloud
- Google Cloud Blog — "Google Cloud mitigated largest DDoS attack, peaking above 398 million rps" (HTTP/2 Rapid Reset, CVE-2023-44487; Cloud Armor always-on L7 DDoS + Adaptive Protection) and Cloud Armor release notes: hierarchical security policies GA (Oct 2025), JA4 rate-limiting key GA (June 2025). cloud.google.com/blog/products/identity-security/google-cloud-mitigated-largest-ddos-attack-peaking-above-398-million-rps · cloud.google.com/armor/docs/release-notes
- Google Cloud — "Google Cloud Armor Adaptive Protection overview" (ML per-backend-service L7 DDoS detection, alert + generated signature + suggested custom rule). cloud.google.com/armor/docs/adaptive-protection-overview
- Google Professional Cloud Security Engineer — certification exam guide, 'Configure network security' domain (VPC design, firewall rules, Cloud Armor, DDoS protection, web application firewalls). cloud.google.com/learn/certification/guides/cloud-security-engineer
What's next?
You've layered the network controls — but a too-broad firewall rule or an unenforced WAF rule is exactly the kind of misconfiguration you'd rather have flagged for you. Next we shift from configuring devices to automating fleets of them: how Ansible drives network changes repeatably, so your guardrails are code, not clicks.