Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion terraform/environments/production/r2.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@

resource "cloudflare_r2_bucket" "media" {
account_id = var.cloudflare_account_id
name = "open-inspect-media-${local.name_suffix}"
name = var.r2_media_bucket_name != "" ? var.r2_media_bucket_name : "open-inspect-media-${local.name_suffix}"
location = var.r2_media_location
}
Comment thread
ColeMurray marked this conversation as resolved.
30 changes: 30 additions & 0 deletions terraform/environments/production/terraform.tfvars.example
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,36 @@ deployment_name = ""
# Path to project root (relative to this directory)
project_root = "../../../"

# Override the R2 media bucket name (optional)
# Defaults to "open-inspect-media-<deployment_name>" when left empty.
# Set this when the bucket must be pre-created out-of-band — for example, when
# the Cloudflare API token used by Terraform doesn't have permission to create
# R2 buckets and an admin had to provision one with a specific name.
#
# Manual setup requirements (when an admin pre-creates the bucket):
# - Must live in the same Cloudflare account as the Workers (cloudflare_account_id).
# - Private bucket — do NOT enable public access. The control-plane Worker
# reads/writes objects through its binding; clients never hit R2 directly.
# - No CORS rules or lifecycle policies are required.
# - Location should match r2_media_location (default ENAM).
#
# Create with wrangler (equivalent to what Terraform would do):
# wrangler r2 bucket create <bucket-name> --location ENAM
# Or create via the Cloudflare dashboard: R2 -> Create bucket (Standard storage class).
#
# After manual creation, import the bucket so Terraform manages the binding without
# trying to recreate it:
# terraform import cloudflare_r2_bucket.media <cloudflare_account_id>/<bucket-name>
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
#
# Worker runtime needs (granted automatically through the binding, listed for reference):
# - R2 object-level: Read, Write, Delete on this bucket only.
# The Terraform/Cloudflare API token does NOT need object-level R2 permissions —
# it only manages the bucket resource and the Worker binding. Required token scopes:
# - Workers R2 Storage: Edit (only needed when Terraform creates/manages the bucket;
# if the bucket is pre-created and imported, drop to Read or omit)
# - Workers Scripts: Edit (to attach the MEDIA_BUCKET binding to the Worker)
# r2_media_bucket_name = ""

# =============================================================================
# Initial Deployment Flags
# =============================================================================
Expand Down
6 changes: 6 additions & 0 deletions terraform/environments/production/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,12 @@ variable "r2_media_location" {
default = "ENAM"
}

variable "r2_media_bucket_name" {
description = "Override the R2 media bucket name. Leave empty to use the default 'open-inspect-media-<deployment_name>'. Set this when the bucket must be pre-created out-of-band (e.g. when the Terraform credentials cannot create R2 buckets)."
type = string
default = ""
}

# =============================================================================
# Access Control
# =============================================================================
Expand Down
Loading