A Perimeter that Enforces rather than Rehearses
spec is the dry-run configuration and status is the enforced one - two blocks of the same shape, and a perimeter with only a spec is evaluated on every request, logs violations, and blocks nothing. Empty restricted_services is the other way to have none: the perimeter exists, covers the projects, and governs no API.
Verification
Static-verifiedPassed: validated and lint-clean (provider-schema-validated for AWS/Azure/GCP; Terraform-language lint elsewhere).
Conformance
- Static validation (fmt · validate · tflint)
- No applicable security policies for this provider
- Plan tests (mocked: validation rules · outputs)
Provenance
- SHA-256 checksum
- Signature (pending)
Functional
- Live test pending (no cloud run yet)
Last verified 2026-09-13 · how we verify
Use it from the registry
terraform · opentofumodule "service_perimeter" {
source = "www.iac-bazaar.com/iac-bazaar/gcp-service-perimeter/gcp"
version = "1.0.0"
}Needs a registry token from /account/tokens. The module itself is free; the account is what identifies you. Full setup: registry docs.
Inputs & outputs
Create a free account to read this module's contract
The declared contract - every input name, type, default and description, plus every output - is shown to signed-in accounts, not to anonymous visitors.
A free account sees the contract of every module in the catalogue. There is no subscription and nothing to buy - the modules are free to download, and they run under Vizier.
Documentation
gcp-service-perimeter
A VPC Service Controls perimeter that enforces rather than rehearses. Works with
Terraform and OpenTofu (>= 1.6), google provider >= 6.0, < 7.0.
spec is the dry run and status is the enforced configuration. They are
two separate blocks holding the same shape, and use_explicit_dry_run_spec
decides which one is real. A perimeter with only a spec appears in the
console, is evaluated on every request, writes violations to the audit log - and
blocks nothing at all. This is the most confusable control in Google Cloud,
because a dry-run perimeter is genuinely useful and looks identical to an
enforcing one everywhere except in which block is populated. This module writes
to one or the other, never both, so the difference is one variable.
A perimeter with no restricted_services protects nothing. The list names
the APIs the boundary applies to. Empty means the perimeter exists, contains the
projects, and governs no API - which reads in every inventory as "perimeter:
yes". A precondition refuses it.
Access levels are the hole you cut on purpose. An attached access level lets
callers matching it reach the restricted services from outside; one matching a
broad IP range defeats the perimeter while leaving it looking configured.
external_access_levels is an output for exactly that review.
Without vpc_accessible_services, workloads inside can reach any Google
API. The perimeter stops data leaving to projects outside it; it does not by
itself stop a compromised VM inside from calling an API you never intended to
expose.
This module does not model ingress and egress policies, and that matters. With none of them and no access levels, only resources inside the perimeter can reach the restricted services - correct, very restrictive, and it will stop your CI dead. A precondition makes you say you understand that before it applies.
Smaller things: the perimeter name accepts underscores only, unlike almost
everywhere else in Google Cloud; and protected_projects takes numeric project
numbers, not ids, with an API error that does not explain the difference -
so the module checks the shape first.
Verification
Static validation runs tofu fmt, init, validate, tflint and checkov.
This module has not yet had a live test, so it is published as statically
validated with its live test pending and does not carry the live-tested mark.
Usage code & full reference need an account
The complete copy-paste usage, the full input/output reference, and operational notes are free with an account - shown here and bundled in the download. Sign in and this section fills in.
- Usage
Related modules
gcp-cloud-armor
A global Cloud Armor WAF policy with preconfigured OWASP SQLi and XSS rules enforcing by default, an optional per-client rate limit, and custom IP allow/deny rules - attachable to many backends.
gcp-workload-identity-federation
attribute_condition is optional, and the issuer is not yours - so omitting it on a GitHub Actions provider trusts every workflow in every repository belonging to anyone on GitHub. It works perfectly in testing, because your workflow is one of the ones it admits. Refused here, along with a wildcard principalSet.
gcp-binary-authorization
DRYRUN_AUDIT_LOG_ONLY admits the image and writes a line about it while the console shows the policy as configured. ALWAYS_ALLOW is the other way to have nothing: a valid, enforced policy that admits everything. Both have to be right, so one output reports over both.
gcp-service-accounts-iam
Service accounts with least-privilege project/resource IAM and optional Workload Identity Federation for keyless CI/CD (GitHub Actions).