# Cloud Storage Buckets

> zop.dev manages Cloud Storage buckets via its provisioner API's bucket resource type with 4 controls: storage_class, versioning, access_control, and prevent_public_access. Bucket names are globally unique and location is permanent. Moving a bucket's region means a new bucket and a copy of every object.

Source: https://zop.dev/integrations/provision/gcp/cloud-storage-buckets
Updated: 2026-08-19

---

Cloud Storage provides durable object storage on GCP. zop.dev manages buckets through its provisioner API with safe-by-default access controls.

## Buckets through the provisioner's bucket type

Cloud Storage buckets via the provisioner API's bucket resource type.

## Storage class, versioning, and access control

```text
storage_class, versioning, access_control, prevent_public_access.
```

## Go handles GCS because the module is AWS-only

The Terraform object-storage module is AWS-only; on GCP, buckets are handled by the Go provisioner (and five GCS buckets are created by the observability stack).

## Safe by default, public by exception

`prevent_public_access` is the setting that matters most and costs least. With it enforced, no
ACL mistake, no over-broad IAM binding, no copy-pasted policy can make objects world-readable.
That is the platform-level guarantee that the classic leaked-bucket incident cannot happen here.
Combined with `access_control`, the posture is: private is the invariant, and anything meant
to be public (static assets, downloads) belongs in a bucket explicitly designed for it, not in
an exception to a data bucket's policy.

## Versioning keeps what you deleted

Turning on `versioning` changes what deletion means: overwritten and deleted objects persist
as noncurrent versions, recoverable at will, and billed at full storage rates until removed.
A bucket with versioning and no lifecycle rules retains every version of every object forever,
which for frequently-rewritten data means storage costs several multiples of the visible data
size. Versioning is the right default for anything valuable; pairing it with lifecycle
expiration of old versions is what keeps it from becoming a silent cost multiplier.

## Name and location are forever

Bucket names are globally unique across all of Google Cloud (the name is a claim in a shared
namespace), and a bucket's location is fixed at creation. There is no move operation: changing
region means creating a second bucket and copying every object across, paying egress on the
way. `storage_class` sets the default cost/access trade for new objects and is the one big
setting that can evolve later. Name and location deserve the naming-scheme treatment; class
can be revisited.

## Why this is not Terraform

The Terraform object-storage module is AWS-only; on GCP, buckets are the Go provisioner's job,
except for the 5 GCS buckets the observability stack creates for its own components, which
arrive through that stack's provisioning rather than this resource type.
