This check flags GCP Cloud Functions that are not connected to a VPC through Serverless VPC Access. Without it, your functions cannot reach private resources securely and lose access to controls like firewall rules and egress filtering. Fix it by creating a Serverless VPC Access connector and attaching it to the function with --vpc-connector.
Cloud Functions are great for gluing systems together without managing servers. The downside is that, by default, they run in a Google-managed network with no direct line into your private VPC. If a function needs to talk to a Cloud SQL instance over a private IP, a Memorystore Redis cluster, or an internal service running on a Compute Engine VM, that traffic either fails or gets routed over the public internet. Serverless VPC Access fixes both problems by giving the function a path into your VPC.
This check, functions_novpcaccess, looks for any Cloud Function that has no VPC connector attached. It is a signal that the function is either operating in an over-exposed way or relying on public endpoints it should not need.
What this check detects
Lensix inspects each Cloud Function in your GCP projects and reports any function where the VPC connector setting is empty. In practice that means the function has no vpcConnector field set and is not using Serverless VPC Access.
A function in this state can only reach resources that are exposed on public IP addresses. It cannot reach anything that lives behind a private IP inside your VPC, and any outbound traffic leaves through Google's default egress path rather than through your network where you control routing and firewalls.
Note: Serverless VPC Access works by provisioning a connector, which is a small managed pool of instances that bridges the serverless environment and your VPC subnet. Traffic from the function is routed through the connector into the VPC using internal IP addresses from a dedicated /28 range.
Why it matters
The risk here is twofold: data exposure and loss of network control.
Private resources get reached over the public internet
Say your function needs to query a Cloud SQL database. Without a VPC connector, you are pushed toward enabling a public IP on that database and connecting over the internet. That public IP is now a target. Even with authorized networks and SSL enforced, you have widened the attack surface of a system that should never have been reachable from outside your network in the first place.
You lose firewall and egress controls
When function traffic flows through your VPC, it is subject to your firewall rules, VPC Service Controls perimeters, and egress routing. You can force outbound traffic through Cloud NAT with a known static IP, which is often required when calling third-party APIs that allowlist IPs. Without a connector, you give all of that up. Function egress comes from a shifting pool of Google-owned addresses you cannot pin down.
Warning: A function with no VPC connector and unrestricted egress is a quiet exfiltration path. If the function code is compromised through a vulnerable dependency, an attacker can reach any public endpoint with no network-layer obstacle. Routing egress through your VPC lets you apply firewall egress rules and detect anomalous outbound traffic.
Compliance implications
Frameworks like PCI DSS and HIPAA expect sensitive workloads to operate inside controlled network boundaries. A serverless function that touches cardholder data or PHI but routes around your VPC controls is hard to defend in an audit.
How to fix it
Fixing this is a two-step process: create a Serverless VPC Access connector, then attach it to the function.
Step 1: Enable the API
gcloud services enable vpcaccess.googleapis.com --project=YOUR_PROJECT_ID
Step 2: Create a connector
Pick an unused /28 CIDR range that does not overlap with any existing subnet in your VPC. The connector needs that range exclusively.
gcloud compute networks vpc-access connectors create my-connector \
--project=YOUR_PROJECT_ID \
--region=us-central1 \
--network=default \
--range=10.8.0.0/28 \
--min-instances=2 \
--max-instances=3 \
--machine-type=e2-micro
Warning: A connector runs at least two always-on instances, so it carries an ongoing cost even when idle. Keep min-instances low for low-traffic functions, and share a single connector across multiple functions in the same VPC and region instead of creating one per function.
Step 3: Attach the connector to your function
For a Gen 2 function:
gcloud functions deploy my-function \
--gen2 \
--region=us-central1 \
--vpc-connector=my-connector \
--egress-settings=private-ranges-only
The --egress-settings flag controls what goes through the connector:
private-ranges-onlyroutes only requests to RFC 1918 private IPs through the VPC. Public traffic still uses the default path.all-trafficroutes everything through the VPC, which is what you want if you need a static egress IP via Cloud NAT or full firewall control.
Tip: If your goal is a fixed outbound IP for a partner's allowlist, set --egress-settings=all-traffic and pair the connector subnet with a Cloud Router and Cloud NAT configured with a reserved static address. The function's outbound traffic will then consistently originate from that IP.
Console steps
If you prefer the console:
- Open the function in Cloud Functions and click Edit.
- Expand Runtime, build, connections and security settings.
- Under the Connections tab, set Egress settings and choose your VPC connector (or create one inline).
- Click Next, then Deploy.
Terraform
If you manage infrastructure as code, define both the connector and the function binding:
resource "google_vpc_access_connector" "connector" {
name = "my-connector"
region = "us-central1"
network = "default"
ip_cidr_range = "10.8.0.0/28"
min_instances = 2
max_instances = 3
}
resource "google_cloudfunctions2_function" "fn" {
name = "my-function"
location = "us-central1"
service_config {
vpc_connector = google_vpc_access_connector.connector.id
vpc_connector_egress_settings = "PRIVATE_RANGES_ONLY"
# ... other service config
}
# ... build config
}
Danger: Switching an existing function to all-traffic egress changes its outbound source IP. If anything downstream allowlists the function's current addresses, that traffic will start getting rejected. Verify the new egress IP and update allowlists before flipping the setting on a production function.
How to prevent it from happening again
One-off fixes do not hold up. New functions get deployed by different teams, and the default is no connector. Put a gate in front of deployments.
Policy as code with Terraform
If you use Terraform, an OPA or Conftest policy can reject any function resource that lacks a connector:
deny[msg] {
resource := input.resource_changes[_]
resource.type == "google_cloudfunctions2_function"
not resource.change.after.service_config[_].vpc_connector
msg := sprintf("Function '%s' has no VPC connector", [resource.change.after.name])
}
Organization policy
GCP does not have a built-in org policy constraint that mandates a VPC connector, so enforcement is best done in CI/CD plus continuous scanning. Run the Lensix functions_novpcaccess check on a schedule so any function that slips through the deployment gate is caught and surfaced quickly.
Tip: Standardize on a small number of shared connectors, one per VPC and region, and bake their IDs into a reusable Terraform module. Teams deploying functions reference the module instead of deciding network settings themselves, which makes the secure path the default path.
Best practices
- Use private IPs for backend services. Once a connector is in place, disable public IPs on Cloud SQL and other backends and connect over the private path.
- Set egress deliberately. Use
private-ranges-onlyfor functions that only touch internal resources, andall-trafficwhen you need full egress control or a static NAT IP. - Add VPC firewall egress rules. Once function traffic enters your VPC, write deny-by-default egress rules so a compromised function cannot reach arbitrary destinations.
- Combine with VPC Service Controls. For functions handling sensitive data, place the resources inside a service perimeter to block data movement outside the boundary.
- Right-size the connector. Match
min-instancesandmachine-typeto actual throughput. Oversized connectors waste money, undersized ones throttle traffic under load. - Audit regularly. Connectors and functions drift over time. Continuous scanning keeps the gap between intended and actual state from widening.
Connecting your Cloud Functions to a VPC is a small configuration change with outsized security value. It pulls serverless traffic back under the same network controls you already apply to the rest of your infrastructure, and it removes the temptation to expose private backends to the public internet.

