Skip to content
Back to main site

Service Networking

Model private service access connections to local Compute Engine networks and reserved peering ranges.

Plan: Free10 of 29 methods implemented, 6 failed in testing2Known differences

Control plane only. Several DNS, subnet-allocation and network-configuration methods failed or weren't implemented in Vera 1.2.0 preview.

Example checked on Vera 1.2.2, 8 November 2026. Each coverage note names its own evidence and date.

Start Vera as in Get started, then run this in a terminal of its own. It uses Google Cloud’s address on your machine: if you published another host port, use that one.

Terminal window
export VERA_ENDPOINT="http://localhost:8081"

Requests go to $VERA_ENDPOINT/_gcp/servicenetworking/v1/. Use v1: in Vera 1.2.0 preview, v1beta connection lists and operation reads answered 500. A connection’s network names the consumer network by its project’s number and its Compute Engine network name, as projects/PROJECT_NUMBER/global/networks/NETWORK.

Use REST for this service. gcloud 585.0.0 has no endpoint override for Service Networking, so its gcloud services vpc-peerings commands go to Google Cloud rather than the emulator, and fail there without credentials. The REST requests below need no credentials.

Create a custom VPC network and an internal range reserved for peering, connect them to private service access, inspect the connection and remove everything. This is configuration only: no packets travel between networks. It needs curl and Python 3 (python3), which copies values from one response into the next request.

The example uses the first active project that Cloud Resource Manager lists, such as the one Vera starts with. If you’ve deleted that, create a local project first. The network and range names must be unused.

Terminal window
CRM="$VERA_ENDPOINT/_gcp/cloudresourcemanager/v1"
PROJECT_ID=$(curl --fail --silent --show-error "$CRM/projects" | \
python3 -c 'import json,sys; print(next(p["projectId"] for p in json.load(sys.stdin)["projects"] if p.get("lifecycleState")=="ACTIVE"))')
PROJECT_NUMBER=$(curl --fail --silent --show-error "$CRM/projects/$PROJECT_ID" | \
python3 -c 'import json,sys; print(json.load(sys.stdin)["projectNumber"])')
COMPUTE="$VERA_ENDPOINT/compute/v1/projects/$PROJECT_ID/global"
SERVICE="$VERA_ENDPOINT/_gcp/servicenetworking/v1/services/servicenetworking.googleapis.com"
NETWORK="projects/$PROJECT_NUMBER/global/networks/example-private-services"
curl --fail --silent --show-error -X POST "$COMPUTE/networks" \
-H 'Content-Type: application/json' \
-d '{"name":"example-private-services","autoCreateSubnetworks":false}'
curl --fail --silent --show-error -X POST "$COMPUTE/addresses" \
-H 'Content-Type: application/json' \
-d '{"name":"example-peering-range","purpose":"VPC_PEERING","addressType":"INTERNAL","prefixLength":16,"network":"projects/'"$PROJECT_ID"'/global/networks/example-private-services"}'
curl --fail --silent --show-error -X POST "$SERVICE/connections" \
-H 'Content-Type: application/json' \
-d '{"network":"'"$NETWORK"'","reservedPeeringRanges":["example-peering-range"]}' \
-o connection-operation.json
OPERATION=$(python3 -c 'import json; print(json.load(open("connection-operation.json"))["name"])')
curl --fail --silent --show-error "$VERA_ENDPOINT/_gcp/servicenetworking/v1/$OPERATION"
curl --fail --silent --show-error --get "$SERVICE/connections" \
--data-urlencode "network=$NETWORK"

Creating the connection returns an operation with done: false, saved to connection-operation.json. In testing of Vera 1.2.0 preview, polling it found it done: true the first time. Its name differs on every run.

The last request lists the network’s connections. These are selected fields. PROJECT_NUMBER stands for your project’s number.

Response (selected fields)
{
"connections": [
{
"network": "projects/PROJECT_NUMBER/global/networks/example-private-services",
"peering": "servicenetworking-googleapis-com",
"reservedPeeringRanges": ["example-peering-range"],
"service": "services/servicenetworking.googleapis.com"
}
]
}

Delete the connection before its range and network. Its delete method is a POST to the connection’s name, with no :deleteConnection suffix. It returns an operation to poll, and afterward the network lists no connections. Then delete the range and the network, and remove the saved operations:

Terminal window
curl --fail --silent --show-error -X POST "$SERVICE/connections/-" \
-H 'Content-Type: application/json' \
-d '{"consumerNetwork":"'"$NETWORK"'"}' -o delete-operation.json
OPERATION=$(python3 -c 'import json; print(json.load(open("delete-operation.json"))["name"])')
curl --fail --silent --show-error "$VERA_ENDPOINT/_gcp/servicenetworking/v1/$OPERATION"
curl --fail --silent --show-error -X DELETE "$COMPUTE/addresses/example-peering-range"
curl --fail --silent --show-error -X DELETE "$COMPUTE/networks/example-private-services"
rm connection-operation.json delete-operation.json
  • Private service access connections: create, list, update and delete, referring to an existing Compute Engine network and its INTERNAL VPC_PEERING address ranges.
  • Operations for changes: get, list, cancel and delete. Changes take effect at once, and their operations finish when polled.
  • VPC Service Controls to enable and disable on a connection’s network, named with a project ID: a project number is refused. Nothing is enforced, and the example leaves this out.

The main limits are below. A few more apply to every service, and the API coverage notes cover smaller differences.

  • No connectivity. Connections are configuration records: there’s no VPC peering, packet routing, DNS forwarding or service access.
  • REST only. gcloud 585.0.0 can’t point Service Networking at the emulator, as above.
  • Some methods aren’t implemented. searchRange, validate, roles.add and addSubnetwork answer 501 to otherwise valid requests.
  • No DNS zones or record sets. Their methods answer 501. Adding a DNS zone fails its name checks before that: a plain zone name is refused for lacking a service prefix, and a prefixed one for not being a bare ID.
  • Peered DNS domains fail. In Vera 1.2.0 preview, creating, listing and deleting them answered 500.
  • Network configuration fails. Reading or updating a network’s consumer configuration, and reading its VPC Service Controls, fail for an existing network: with a project number, a 400 says the network doesn’t exist, and with a project ID, the request answers 500. Don’t rely on a VPC Service Controls or network configuration workflow.
  • Found in Vera 1.2.0 preview. These failures haven’t been rechecked on Vera 1.2.0-rc.3.

Every method in Google Cloud's published v1 API (discovery document, revision 20261028), and whether the emulator implements it. Known differences are from testing on 5 November 2026. Notes marked Local observation without a build or date are from Vera 1.2.0 preview, on 5 November 2026. What the statuses mean

operations

4 of 4 implemented
MethodStatusNotes
cancelImplementedLocal observation: operations are local records of connection changes, not Google Cloud jobs.
deleteImplementedLocal observation: operations are local records of connection changes, not Google Cloud jobs.
getImplementedLocal observation: a connection's create and delete operations reported done: false, then done: true on the first poll. The change itself had already taken effect.
listImplementedLocal observation: operations are local records of connection changes, not Google Cloud jobs.

services

2 of 5 implemented · 2 known differences
MethodStatusNotes
addSubnetworkNot implementedLocal observation: answered 501 to an otherwise valid request.
disableVpcServiceControlsKnown differenceLocal observation: accepted a consumer network named by project ID, and refused one named by project number. Nothing is enforced.
enableVpcServiceControlsKnown differenceLocal observation: accepted a consumer network named by project ID, and refused one named by project number. Nothing is enforced.
searchRangeNot implementedLocal observation: answered 501 to an otherwise valid request.
validateNot implementedLocal observation: answered 501 to an otherwise valid request.

services.connections

4 of 4 implemented
MethodStatusNotes
createImplementedLocal observation: needs an existing Compute Engine network, named by project number, and an INTERNAL VPC_PEERING address range. The connection is a record: no peering is made.
deleteConnectionImplementedLocal observation: a POST to the connection's name, with no :deleteConnection suffix, as the published API defines it. Delete the connection before its address range and network.
listImplemented
patchImplementedLocal observation: updates the connection's record only: no peering changes.

services.dnsRecordSets

0 of 5 implemented
MethodStatusNotes
addNot implementedLocal observation: answered 501 to an otherwise valid request.
getNot implementedLocal observation: answered 501 to an otherwise valid request.
listNot implementedLocal observation: answered 501 to an otherwise valid request.
removeNot implementedLocal observation: answered 501 to an otherwise valid request.
updateNot implementedLocal observation: answered 501 to an otherwise valid request.

services.dnsZones

0 of 2 implemented
MethodStatusNotes
addNot implementedLocal observation: a plain zone name was refused for lacking a service prefix, and a prefixed one for not being a bare ID, so no request got past the name checks. Source inspection: the handler behind them is a stub.
removeNot implementedLocal observation: answered 501 after its name checks, which also refused ordinary zone names.

services.projects.global.networks

0 of 3 implemented · 3 failed in testing
MethodStatusNotes
getFailed in testingLocal observation: for an existing network, a project number answered 400, saying the network doesn't exist, and a project ID answered 500.
getVpcServiceControlsFailed in testingLocal observation: for an existing network, a project number answered 400, saying the network doesn't exist, and a project ID answered 500.
updateConsumerConfigFailed in testingLocal observation: for an existing network, a project number answered 400, saying the network doesn't exist, and a project ID answered 500.

services.projects.global.networks.dnsZones

0 of 2 implemented
MethodStatusNotes
getNot implementedLocal observation: answered 501 to an otherwise valid request.
listNot implementedLocal observation: answered 501 to an otherwise valid request.

services.projects.global.networks.peeredDnsDomains

0 of 3 implemented · 3 failed in testing
MethodStatusNotes
createFailed in testingLocal observation: answered 500, a runtime error, in Vera 1.2.0 preview.
deleteFailed in testingLocal observation: answered 500, a runtime error, in Vera 1.2.0 preview.
listFailed in testingLocal observation: answered 500, a runtime error, in Vera 1.2.0 preview.

services.roles

0 of 1 implemented
MethodStatusNotes
addNot implementedLocal observation: answered 501 to an otherwise valid request.