Provision a GCS bucket the Terraform way
Hand-writing google_storage_bucket HCL means remembering the right nested blocks for versioning, lifecycle, and access control. This builder assembles a correct, opinionated resource — secure defaults on, plus an optional IAM binding — that you can drop straight into your Terraform configuration.
How it works
The generated google_storage_bucket resource declares the bucket name, project, location, and storage_class. It sets uniform_bucket_level_access = true so permissions are governed entirely by IAM rather than legacy per-object ACLs, and enforces public_access_prevention to block accidental public exposure.
A versioning block keeps prior object generations, and an optional lifecycle_rule applies an action once objects reach a given age. Choosing Delete removes old objects, while choosing a storage class (Nearline, Coldline, Archive) emits a SetStorageClass action that tiers data down to cheaper storage. If you enable the IAM binding, a separate google_storage_bucket_iam_member grants a role to a member without overwriting other bindings.
Choosing a storage class
GCS offers four storage classes suited to different access patterns:
| Class | Minimum storage duration | Retrieval cost | Good for |
|---|---|---|---|
| Standard | None | None | Frequently accessed data, websites, CI artifacts |
| Nearline | 30 days | Per-GB | Backups accessed less than once a month |
| Coldline | 90 days | Per-GB (higher) | Disaster recovery, accessed less than once a quarter |
| Archive | 365 days | Per-GB (highest) | Long-term compliance archives |
The lifecycle SetStorageClass action lets Terraform automatically tier objects down as they age — for example, move to Nearline after 30 days and Coldline after 90. This is the standard cost-optimisation pattern for storage buckets that hold logs or infrequently accessed files.
IAM: additive vs authoritative
GCS has three Terraform resource types for bucket permissions:
google_storage_bucket_iam_member— adds one member/role pair; other bindings are untouched. Use this.google_storage_bucket_iam_binding— sets the complete list of members for one role; overwrites other members in that role.google_storage_bucket_iam_policy— replaces the entire IAM policy; can accidentally remove permissions managed outside Terraform.
The builder uses iam_member (additive) to avoid overwriting permissions set by the console or other automation. Switch only if you need authoritative control and understand the implications.
Tips and notes
force_destroyis set tofalseso Terraform will refuse to delete a non-empty bucket — flip it totrueonly for disposable buckets.- Combine versioning with a lifecycle rule targeting
numNewerVersionsorageon noncurrent versions to prevent unbounded storage growth. - Bucket names are global across all GCP projects; prefix them with your org or project name to avoid
409 conflicterrors on apply. - The
locationfield accepts multi-region values (US,EU,ASIA) for higher availability, or specific regions (us-central1,europe-west1) for lower latency and cost.