google_storage_bucket provisiona um bucket no Cloud Storage. Nomes de bucket são globalmente únicos em todo o GCP (não só no projeto), então o padrão ${projeto}-${ambiente}-${finalidade} evita colisões.

Recurso principal

resource "google_storage_bucket" "lake_raw" {
  name          = "${local.prefixo}-lake-raw"
  location      = var.regiao
  storage_class = "STANDARD"
 
  # Bloqueia acesso público (obrigatório para dados internos)
  public_access_prevention = "enforced"
 
  # IAM unificado: sem ACLs por objeto
  uniform_bucket_level_access = true
 
  labels = local.labels
}

Parâmetros principais

location

Define onde os dados ficam fisicamente. Aceita regiões, multi-regiões e dual-regiões:

ValorTipoQuando usar
southamerica-east1Região (São Paulo)Dados com residência no Brasil, menor latência BR
us-central1RegiãoCargas internas sem restrição geográfica
USMulti-regiãoAlta disponibilidade sem preferência de região
ASIAMulti-regiãoWorkloads asiáticos
NAM4Dual-região (Iowa + Carolina do Norte)Redundância sem custo de multi-região completo

Multi-regiões custam mais por operação e replicam entre regiões automaticamente. Para data lakes que alimentam o BigQuery, prefira região única igual à do dataset; queries cross-region geram custo de egress.

storage_class

ClasseRetenção mínimaCusto de acessoQuando usar
STANDARDNenhumaNenhumDados acessados diariamente (raw, trusted)
NEARLINE30 diasSimDados acessados ~1x por mês
COLDLINE90 diasAltoDados acessados ~1x por trimestre
ARCHIVE365 diasMáximoBackups e arquivamento de longo prazo

Ao deletar um objeto antes do período mínimo, você paga pelo tempo restante. Combinar STANDARD com lifecycle rules é mais flexível do que definir a classe na criação.

versioning

versioning {
  enabled = true
}

Mantém todas as versões de cada objeto. Indispensável para buckets de Terraform state e dados críticos. O custo cresce com o volume de versões: combine sempre com lifecycle para limitar o histórico.

retention_policy

retention_policy {
  retention_period = 2592000  # 30 dias em segundos
  is_locked        = false    # true = imutável, nem o owner apaga antes do prazo
}

is_locked = true atende requisitos WORM (compliance, auditoria). Não pode ser desfeito via Terraform após ativado: o terraform destroy falha e o desbloqueio exige intervenção manual no console.

Lifecycle rules

lifecycle_rule {
  action {
    type          = "SetStorageClass"
    storage_class = "NEARLINE"
  }
  condition {
    age = 30  # dias após upload
  }
}
 
lifecycle_rule {
  action {
    type = "Delete"
  }
  condition {
    age                = 365
    with_state         = "ARCHIVED"  # só versões não-correntes
    num_newer_versions = 3           # mantém as 3 mais recentes
  }
}

with_state aceita LIVE, ARCHIVED ou ANY. Múltiplas rules são avaliadas independentemente; objetos que satisfazem mais de uma recebem a ação da primeira regra correspondente.

IAM

resource "google_storage_bucket_iam_binding" "readers" {
  bucket = google_storage_bucket.lake_raw.name
  role   = "roles/storage.objectViewer"
 
  members = [
    "serviceAccount:${google_service_account.pipeline.email}",
    "group:[email protected]",
  ]
}

Roles principais:

RoleO que permite
roles/storage.objectViewerLeitura de objetos (não lista bucket)
roles/storage.objectCreatorUpload de objetos (sem leitura)
roles/storage.objectUserLeitura + escrita + delete de objetos
roles/storage.adminControle total do bucket e objetos

objectViewer não inclui list do bucket por padrão. Para permitir listagem, use roles/storage.legacyBucketReader em conjunto, ou objectUser.

Bucket de Terraform state

O bucket que armazena o .tfstate precisa de configuração mais restritiva:

resource "google_storage_bucket" "tfstate" {
  name          = "${local.prefixo}-tfstate"
  location      = var.regiao
  storage_class = "STANDARD"
 
  public_access_prevention    = "enforced"
  uniform_bucket_level_access = true
 
  versioning {
    enabled = true  # obrigatório: permite rollback de state corrompido
  }
 
  lifecycle_rule {
    action { type = "Delete" }
    condition {
      age                = 90
      with_state         = "ARCHIVED"
      num_newer_versions = 10
    }
  }
}

O GCS tem locking nativo de state (ao contrário do S3, que precisa de DynamoDB separado). Nenhuma configuração extra é necessária no Terraform.

Quotas e limites relevantes

  • Nomes: 3 a 63 caracteres, só minúsculas, números e hífens; sem ponto ao usar HTTPS (conflito de certificado wildcard)
  • Tamanho máximo de objeto: 5 TB por arquivo
  • Operações de escrita por segundo por bucket: ~1.000 QPS antes do auto-scaling entrar; para ingestão em burst, use prefixos variados (ex.: UUID no início do path) para distribuir shards internos
  • Operações de leitura por segundo: ~5.000 QPS por prefixo antes do auto-scaling
  • Custo de egress: transferências entre regiões e para fora do GCP geram custo; manter bucket e BigQuery na mesma região evita egress

Conexões

Ver também: gcp-cloud-storage | terraform-gcp-ambientes | terraform-gcp-bigquery | terraform-cloud-gcp | gcp-boas-praticas | terraform-state