Terraform fails to create a Pub/Sub topic because it already exists in Google Cloud but isn't tracked in your state. This happens when topics are created manually or by other processes.
Google Cloud Pub/Sub enforces unique topic names within a GCP project. When Terraform attempts to create a topic with a name that already exists in Google Cloud, the provider returns an "AlreadyExists" error code (GRPC code 6). This indicates that Terraform is trying to create a resource that has already been created, either manually through the GCP Console, the gcloud CLI, or through another automation tool. The issue occurs because Terraform's state file doesn't know about the existing topic, so it tries to create it fresh, triggering a conflict.
Check if the Pub/Sub topic actually exists in your GCP project using the gcloud CLI:
gcloud pubsub topics list --project=YOUR_PROJECT_IDOr check the GCP Console under Pub/Sub > Topics. If you see the topic listed, it exists in Google Cloud but Terraform doesn't know about it.
Use terraform import to register the existing topic with Terraform so it can manage it going forward:
terraform import google_pubsub_topic.my_topic projects/YOUR_PROJECT_ID/topics/YOUR_TOPIC_NAMEReplace:
- my_topic: Your Terraform resource identifier (the name after google_pubsub_topic.)
- YOUR_PROJECT_ID: Your GCP project ID
- YOUR_TOPIC_NAME: The actual Pub/Sub topic name
Example:
terraform import google_pubsub_topic.events projects/my-gcp-project/topics/order-eventsAfter successful import, Terraform will add the topic to your state file and stop trying to create it.
Make sure your HCL configuration matches the actual topic settings. Import brings in the resource, but you need to ensure your .tf file reflects reality:
resource "google_pubsub_topic" "my_topic" {
name = "YOUR_TOPIC_NAME"
project = "YOUR_PROJECT_ID"
# Add any other existing settings here
message_retention_duration = "86400s" # If applicable
labels = {
environment = "production"
}
}Run terraform plan to verify there are no drift differences between your config and the actual topic.
If you're using the terraform-google-modules/pubsub module, you can reference an existing topic without recreating it:
module "pubsub" {
source = "terraform-google-modules/pubsub/google"
version = "~> 8.3"
topic = "existing-topic-name"
project_id = "my-project"
create_topic = false # Don't create, just reference existing
}This allows the module to work with a pre-existing topic instead of trying to create one.
If the existing topic is not important or is in a development environment, you can delete it and let Terraform manage it cleanly:
# Using gcloud CLI
gcloud pubsub topics delete YOUR_TOPIC_NAME --project=YOUR_PROJECT_ID
# Or delete via GCP Console under Pub/Sub > TopicsThen run:
terraform applyTerraform will create a fresh topic that it fully manages. Only use this approach in development/test environments, not production.
To avoid conflicts in team environments:
1. Use a remote backend with state locking (Cloud Storage, Terraform Cloud):
terraform {
backend "gcs" {
bucket = "my-terraform-state"
prefix = "pubsub"
}
}2. Always run `terraform plan` before apply to catch conflicts early:
terraform plan -out=tfplan
terraform apply tfplan3. Communicate with your team before creating resources manually—keep all infrastructure in Terraform.
4. Use `for_each` or `count` carefully to avoid duplicate resource names in your configuration.
When dealing with immutable Pub/Sub topic fields like schema_settings, note that Google Cloud doesn't allow in-place updates to these fields. If you need to modify schema_settings, you must use terraform replace to force a destroy and recreate operation: terraform apply -replace=google_pubsub_topic.example. This is a Google Cloud API limitation, not a Terraform issue. In production environments with active subscriptions, coordinate with your team before replacing topics as it may disrupt message delivery.
Error: Error installing helm release: cannot re-use a name that is still in use
How to fix "release name in use" error in Terraform with Helm
Error: Error creating GKE Cluster: BadRequest
BadRequest error creating GKE cluster in Terraform
Error: External program failed to produce valid JSON
External program failed to produce valid JSON
Error: Unsupported argument in child module call
How to fix "Unsupported argument in child module call" in Terraform
Error: network is unreachable
How to fix "network is unreachable" in Terraform