Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
6 changes: 5 additions & 1 deletion examples/braintrust-data-plane/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,11 @@ module "braintrust-data-plane" {

### Advanced configuration
# gcs_additional_allowed_origins = []
# Optional GCS access logging for the managed buckets. Point these at an existing log bucket.
# Create a dedicated GCS access log bucket and send both bucket logs to it.
# gcs_brainstore_logging_config = {}
# gcs_api_logging_config = {}
#
# Optional GCS access logging with existing log buckets.
# gcs_brainstore_logging_config = {
# log_bucket = "my-access-logs-bucket"
# log_object_prefix = "brainstore/"
Expand Down
4 changes: 4 additions & 0 deletions examples/braintrust-data-plane/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ output "brainstore_bucket_name" {
value = module.braintrust-data-plane.brainstore_bucket_name
}

output "access_log_bucket_name" {
value = module.braintrust-data-plane.access_log_bucket_name
}

output "braintrust_service_account" {
value = module.braintrust-data-plane.braintrust_service_account
}
Expand Down
80 changes: 76 additions & 4 deletions modules/storage/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ locals {
common_labels = merge(var.custom_labels, {
braintrustdeploymentname = var.deployment_name
})

create_access_log_bucket = (
var.gcs_brainstore_logging_config == null ? false : var.gcs_brainstore_logging_config.log_bucket == null
) || (
var.gcs_api_logging_config == null ? false : var.gcs_api_logging_config.log_bucket == null
)
}

data "google_project" "current" {}
Expand All @@ -28,6 +34,56 @@ resource "random_id" "gcs_suffix" {
byte_length = 4
}

#----------------------------------------------------------------------------------------------
# Google cloud storage (GCS) bucket - access logs
#----------------------------------------------------------------------------------------------
resource "google_storage_bucket" "access_logs" {
count = local.create_access_log_bucket ? 1 : 0

name = "${var.deployment_name}-access-logs-${random_id.gcs_suffix.hex}"
location = data.google_client_config.current.region
storage_class = var.gcs_storage_class
uniform_bucket_level_access = true
force_destroy = var.gcs_force_destroy
public_access_prevention = "enforced"

versioning {
enabled = var.gcs_versioning_enabled
}

soft_delete_policy {
retention_duration_seconds = var.gcs_soft_delete_retention_days * 86400
}

dynamic "encryption" {
for_each = var.gcs_kms_cmek_id != null ? ["encryption"] : []

content {
default_kms_key_name = var.gcs_kms_cmek_id
}
}

labels = local.common_labels

lifecycle {
ignore_changes = [
name,
]
}

depends_on = [
google_kms_crypto_key_iam_member.gcp_project_gcs_cmek
]
}

resource "google_storage_bucket_iam_member" "access_log_writer" {
count = local.create_access_log_bucket ? 1 : 0

bucket = google_storage_bucket.access_logs[0].name
role = "roles/storage.objectCreator"
member = "group:cloud-storage-analytics@google.com"
}

#----------------------------------------------------------------------------------------------
# Google cloud storage (GCS) bucket - Brainstore
#----------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -103,7 +159,14 @@ resource "google_storage_bucket" "brainstore" {
}

dynamic "logging" {
for_each = var.gcs_brainstore_logging_config == null ? [] : [var.gcs_brainstore_logging_config]
for_each = var.gcs_brainstore_logging_config == null ? [] : [{
log_bucket = var.gcs_brainstore_logging_config.log_bucket == null ? (
google_storage_bucket.access_logs[0].name
) : var.gcs_brainstore_logging_config.log_bucket
log_object_prefix = var.gcs_brainstore_logging_config.log_bucket == null ? (
"brainstore"
) : var.gcs_brainstore_logging_config.log_object_prefix
}]

content {
log_bucket = logging.value.log_bucket
Expand All @@ -120,7 +183,8 @@ resource "google_storage_bucket" "brainstore" {
}

depends_on = [
google_kms_crypto_key_iam_member.gcp_project_gcs_cmek
google_kms_crypto_key_iam_member.gcp_project_gcs_cmek,
google_storage_bucket_iam_member.access_log_writer,
]
}

Expand Down Expand Up @@ -220,7 +284,14 @@ resource "google_storage_bucket" "api" {
}

dynamic "logging" {
for_each = var.gcs_api_logging_config == null ? [] : [var.gcs_api_logging_config]
for_each = var.gcs_api_logging_config == null ? [] : [{
log_bucket = var.gcs_api_logging_config.log_bucket == null ? (
google_storage_bucket.access_logs[0].name
) : var.gcs_api_logging_config.log_bucket
log_object_prefix = var.gcs_api_logging_config.log_bucket == null ? (
"api"
) : var.gcs_api_logging_config.log_object_prefix
}]

content {
log_bucket = logging.value.log_bucket
Expand All @@ -237,7 +308,8 @@ resource "google_storage_bucket" "api" {
}

depends_on = [
google_kms_crypto_key_iam_member.gcp_project_gcs_cmek
google_kms_crypto_key_iam_member.gcp_project_gcs_cmek,
google_storage_bucket_iam_member.access_log_writer,
]
}

Expand Down
3 changes: 3 additions & 0 deletions modules/storage/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ output "brainstore_bucket_self_link" {
value = google_storage_bucket.brainstore.self_link
}

output "access_log_bucket_name" {
value = try(google_storage_bucket.access_logs[0].name, null)
}

output "api_bucket_name" {
value = google_storage_bucket.api.name
Expand Down
20 changes: 12 additions & 8 deletions modules/storage/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -52,30 +52,34 @@ variable "gcs_additional_allowed_origins" {
}

variable "gcs_brainstore_logging_config" {
description = "Optional access logging configuration for the Brainstore GCS bucket."
description = "Optional Brainstore access log configuration. Omit log_bucket to create a dedicated bucket."
type = object({
log_bucket = string
log_bucket = optional(string)
log_object_prefix = optional(string)
})
default = null

validation {
condition = var.gcs_brainstore_logging_config == null ? true : trimspace(var.gcs_brainstore_logging_config.log_bucket) != ""
error_message = "`gcs_brainstore_logging_config.log_bucket` must be a non-empty bucket name."
condition = var.gcs_brainstore_logging_config == null ? true : (
var.gcs_brainstore_logging_config.log_bucket == null ? true : trimspace(var.gcs_brainstore_logging_config.log_bucket) != ""
)
error_message = "`gcs_brainstore_logging_config.log_bucket` must be null or a non-empty bucket name."
}
}

variable "gcs_api_logging_config" {
description = "Optional access logging configuration for the API GCS bucket."
description = "Optional API access log configuration. Omit log_bucket to use the dedicated bucket."
type = object({
log_bucket = string
log_bucket = optional(string)
log_object_prefix = optional(string)
})
default = null

validation {
condition = var.gcs_api_logging_config == null ? true : trimspace(var.gcs_api_logging_config.log_bucket) != ""
error_message = "`gcs_api_logging_config.log_bucket` must be a non-empty bucket name."
condition = var.gcs_api_logging_config == null ? true : (
var.gcs_api_logging_config.log_bucket == null ? true : trimspace(var.gcs_api_logging_config.log_bucket) != ""
)
error_message = "`gcs_api_logging_config.log_bucket` must be null or a non-empty bucket name."
}
}

Expand Down
5 changes: 5 additions & 0 deletions outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ output "brainstore_bucket_name" {
value = module.storage.brainstore_bucket_name
}

output "access_log_bucket_name" {
value = module.storage.access_log_bucket_name
description = "Dedicated GCS access log bucket, or null when the module does not manage one."
}

#----------------------------------------------------------------------------------------------
# Service account
#----------------------------------------------------------------------------------------------
Expand Down
20 changes: 12 additions & 8 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -274,30 +274,34 @@ variable "gcs_additional_allowed_origins" {
}

variable "gcs_brainstore_logging_config" {
description = "Optional access logging configuration for the Brainstore GCS bucket."
description = "Optional Brainstore access log configuration. Omit log_bucket to create a dedicated bucket."
type = object({
log_bucket = string
log_bucket = optional(string)
log_object_prefix = optional(string)
})
default = null

validation {
condition = var.gcs_brainstore_logging_config == null ? true : trimspace(var.gcs_brainstore_logging_config.log_bucket) != ""
error_message = "`gcs_brainstore_logging_config.log_bucket` must be a non-empty bucket name."
condition = var.gcs_brainstore_logging_config == null ? true : (
var.gcs_brainstore_logging_config.log_bucket == null ? true : trimspace(var.gcs_brainstore_logging_config.log_bucket) != ""
)
error_message = "`gcs_brainstore_logging_config.log_bucket` must be null or a non-empty bucket name."
}
}

variable "gcs_api_logging_config" {
description = "Optional access logging configuration for the API GCS bucket."
description = "Optional API access log configuration. Omit log_bucket to use the dedicated bucket."
type = object({
log_bucket = string
log_bucket = optional(string)
log_object_prefix = optional(string)
})
default = null

validation {
condition = var.gcs_api_logging_config == null ? true : trimspace(var.gcs_api_logging_config.log_bucket) != ""
error_message = "`gcs_api_logging_config.log_bucket` must be a non-empty bucket name."
condition = var.gcs_api_logging_config == null ? true : (
var.gcs_api_logging_config.log_bucket == null ? true : trimspace(var.gcs_api_logging_config.log_bucket) != ""
)
error_message = "`gcs_api_logging_config.log_bucket` must be null or a non-empty bucket name."
}
}

Expand Down
Loading