This error occurs when Terraform attempts to create a Firestore database that already exists in your GCP project. The most common cause is that GCP automatically created a default Firestore database when you enabled related services. You can fix this by importing the existing database into Terraform state or using the existing database in your configuration.
When you deploy Firestore infrastructure using Terraform, the `google_firestore_database` resource attempts to create a new database instance. The "AlreadyExists" error means Terraform is trying to create a database with a name (usually "(default)") that already exists in your GCP project. This typically happens because: 1. **Google Cloud automatically provisioned a default database**: When you enable certain services (like Cloud Storage via `google_app_engine_application`), GCP automatically creates a default Firestore database instance as a side effect. 2. **Database was created outside of Terraform**: The database exists in GCP but not in your Terraform state file, causing Terraform to try creating a "new" one that already exists. 3. **State mismatch**: Your Terraform state file doesn't reflect the actual resources in GCP, causing a discrepancy. The error prevents your Terraform configuration from being applied because Terraform cannot create a resource that already exists in GCP.
The most straightforward solution is to import the existing database into your Terraform state. This tells Terraform that it now manages the existing resource.
First, find your GCP project ID and determine the database name (usually "(default)" for the default database):
# List all Firestore databases in your project
gcloud firestore databases list --project=MY_PROJECT_IDThen, import the database into your Terraform state:
terraform import google_firestore_database.default projects/MY_PROJECT_ID/databases/(default)If you have a differently named database resource in your Terraform config, adjust accordingly:
terraform import google_firestore_database.my_database projects/MY_PROJECT_ID/databases/my-database-nameAfter importing, verify the state was updated:
terraform state show google_firestore_database.defaultNow terraform plan and apply should work without trying to recreate the database.
If the database was created as a side effect of enabling google_app_engine_application, explicitly manage the dependency order in Terraform:
resource "google_project_service" "firestore" {
service = "firestore.googleapis.com"
disable_on_destroy = false
}
resource "google_app_engine_application" "app" {
depends_on = [google_project_service.firestore]
project = var.gcp_project_id
location_id = "us-central"
database_type = "CLOUD_FIRESTORE"
}
# This may conflict, so import the existing database instead
# resource "google_firestore_database" "default" {
# project = var.gcp_project_id
# name = "(default)"
# location_id = "us-central"
# type = "FIRESTORE_NATIVE"
# }By declaring google_project_service.firestore and using depends_on, you control when Firestore is enabled. However, App Engine may still auto-create the database, so importing (Step 1) is still the recommended approach.
Before importing, confirm the database exists and note its properties:
# Get detailed information about the default database
gcloud firestore databases describe --database=(default) --project=MY_PROJECT_IDThis shows:
- Database name (usually "(default)")
- Location (e.g., "us-central1")
- Type (e.g., "FIRESTORE_NATIVE" or "DATASTORE_MODE")
- Current status
Example output:
name: projects/my-project/databases/(default)
location: us-central1
type: FIRESTORE_NATIVE
createTime: '2023-01-15T10:30:00Z'Make sure your Terraform configuration matches these settings when you import the database.
If you have a google_firestore_database resource block in your Terraform configuration that conflicts with the existing database, you have two options:
Option A: Comment it out temporarily (for import)
# resource "google_firestore_database" "default" {
# project = var.gcp_project_id
# name = "(default)"
# location_id = "us-central"
# type = "FIRESTORE_NATIVE"
# }Run terraform import (Step 1), then uncomment it. The import command creates a matching state entry so the resource declaration matches the state.
Option B: Delete and recreate (advanced)
If you're in development and can afford downtime:
# Delete the database in GCP
gcloud firestore databases delete --database=(default) --project=MY_PROJECT_ID
# Now terraform apply will create it fresh
terraform applyWarning: Deleting a Firestore database is irreversible and deletes all data. Only use this in development environments.
If you prefer not to manage the Firestore database with Terraform, use a data source to reference the existing database:
# Reference the existing database without managing it
data "google_firestore_database" "default" {
project = var.gcp_project_id
database = "(default)"
}
output "firestore_database" {
value = data.google_firestore_database.default
}This approach:
- Reads the database properties from GCP
- Does NOT try to create or modify the database
- Allows you to reference it in other resources (e.g., indexes, security rules)
- Is useful when the database lifecycle is managed outside of Terraform
This is ideal if the database is shared across multiple Terraform configurations or managed by a different team.
If you're using both google_app_engine_application and google_firestore_database, the order matters:
resource "google_project_service" "appengine" {
service = "appengine.googleapis.com"
disable_on_destroy = false
}
resource "google_project_service" "firestore" {
service = "firestore.googleapis.com"
disable_on_destroy = false
}
resource "google_app_engine_application" "app" {
depends_on = [
google_project_service.appengine,
google_project_service.firestore,
]
project = var.gcp_project_id
location_id = "us-central"
database_type = "CLOUD_FIRESTORE"
}
# Import existing database instead of creating
# Or use data source (see Step 5)Important note: Even with proper depends_on, the App Engine application may auto-create the Firestore database as a side effect. The import approach (Step 1) is the most reliable fix.
### Understanding GCP Auto-Provisioning
When you create a google_app_engine_application resource with database_type = "CLOUD_FIRESTORE", Google Cloud automatically provisions a default Firestore database. This happens asynchronously and is not directly tracked by Terraform. If you then try to create a google_firestore_database resource for the same database, it fails because the database already exists.
This is a known limitation documented in the Terraform Google Provider GitHub issues (see sources).
### Database Location Locking
Once you create a Firestore database in a specific location (e.g., "us-central1"), you cannot change the location. The location is set at database creation time and is permanent. This is why it's critical to import the database with the correct configuration that matches the existing database in GCP.
### Datastore Mode vs Firestore Native
GCP supports two Firestore modes:
- FIRESTORE_NATIVE: Modern Firestore with Firebase SDKs, real-time listeners, and Firebase Security Rules
- DATASTORE_MODE: Legacy Datastore mode, not compatible with Firebase SDKs
When imported, the database will have the mode it was created with. Make sure your Terraform configuration matches the existing mode.
### Multi-Database Firestore (Advanced)
Firestore now supports multiple databases in a single project (in addition to the default database). If you're using named databases:
terraform import google_firestore_database.named_db projects/MY_PROJECT_ID/databases/my-custom-databaseThis allows you to have a default database (auto-provisioned) and custom databases (managed by Terraform).
### State File Considerations
After importing, ensure your Terraform state file is properly stored and backed up:
terraform {
backend "gcs" {
bucket = "my-terraform-state"
prefix = "firestore"
}
}Never lose your state file, as it tracks which GCP resources Terraform manages. If the state is lost, you'll encounter "AlreadyExists" errors again.
Error: Error rendering template: template not found
How to fix "template not found" error in Terraform
Error: Error generating private key
How to fix 'Error generating private key' in Terraform
Error creating Kubernetes Service: field is immutable
How to fix "field is immutable" errors in Terraform
Error: Error creating local file: open: permission denied
How to fix "Error creating local file: permission denied" in Terraform
Error: line endings have changed from CRLF to LF
Line endings have changed from CRLF to LF in Terraform