add firestore terraform

Assists people who want to self-host and need particular firestore config
This commit is contained in:
talksik
2026-08-01 07:02:00 -07:00
parent 591da5dd7b
commit 3fa380ac76
2 changed files with 128 additions and 0 deletions
+19
View File
@@ -0,0 +1,19 @@
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Per-human membership mirror maintained by Orion's service account.
// Locked from clients so the membership list cannot leak or be mutated.
match /humans/{humanId} {
allow read, write: if false;
}
// Particles: caller must be a current member of the network in the path.
// get() on the mirror is cached across rule evaluations within a single
// request, so this costs 1 billed read per request regardless of query size.
match /networks/{networkId}/children/{particleId=**} {
allow read, write: if request.auth != null
&& networkId in get(/databases/$(database)/documents/humans/$(request.auth.uid)).data.networks;
}
}
}
+109
View File
@@ -0,0 +1,109 @@
resource "google_firebase_project" "default" {
provider = google-beta
project = var.project_id
depends_on = [module.project-services]
}
# Provisions the Firestore database instance.
resource "google_firestore_database" "firestore" {
provider = google-beta
project = google_firebase_project.default.project
name = "(default)"
# See available locations: https://firebase.google.com/docs/firestore/locations
location_id = var.location
# "FIRESTORE_NATIVE" is required to use Firestore with Firebase SDKs, authentication, and Firebase Security Rules.
type = "FIRESTORE_NATIVE"
concurrency_mode = "OPTIMISTIC"
}
resource "google_firebaserules_ruleset" "default" {
provider = google-beta
project = google_firestore_database.firestore.project
source {
files {
name = "firestore.rules"
# Write security rules in a local file named "firestore.rules".
# Learn more: https://firebase.google.com/docs/firestore/security/get-started
content = file("firestore.rules")
}
}
}
resource "google_firebaserules_release" "firestore" {
provider = google-beta
name = "cloud.firestore"
ruleset_name = google_firebaserules_ruleset.default.name
project = google_firestore_database.firestore.project
}
resource "google_firebase_web_app" "llink" {
provider = google-beta
project = google_firebase_project.default.project
display_name = "Llink app"
}
data "google_firebase_web_app_config" "llink" {
provider = google-beta
project = var.project_id
web_app_id = google_firebase_web_app.llink.app_id
}
// Below indices support the new structure where all subcollections (including network root particles) live under a collection of name "children"
// instead of having `network/n_xxx/particles/p_yyy/children` where the top level subcollection of particles has a distinct name
// Collection index for particles in a single subcollection
resource "google_firestore_index" "list_particles_index" {
project = var.project_id
collection = "children"
query_scope = "COLLECTION"
fields {
field_path = "visible_to"
array_config = "CONTAINS"
}
fields {
field_path = "status"
order = "ASCENDING"
}
fields {
field_path = "last_child_created_at"
order = "DESCENDING"
}
fields {
field_path = "__name__"
order = "DESCENDING"
}
depends_on = [google_firestore_database.firestore]
}
// Collection group index for particles across all subcollections
resource "google_firestore_field" "particle_children_created_at" {
database = google_firestore_database.firestore.name
project = var.project_id
collection = "children"
field = "created_at"
index_config {
indexes {
order = "DESCENDING"
query_scope = "COLLECTION_GROUP"
}
indexes {
order = "ASCENDING"
query_scope = "COLLECTION_GROUP"
}
indexes {
order = "DESCENDING"
query_scope = "COLLECTION"
}
indexes {
order = "ASCENDING"
query_scope = "COLLECTION"
}
}
}