hashicorp / terraform-provider-google

Terraform Provider for Google Cloud Platform
https://registry.terraform.io/providers/hashicorp/google/latest/docs
Mozilla Public License 2.0
2.32k stars 1.73k forks source link

google_firestore_field fails for a wildcard '*' field id (but is supported via Firebase JSON API) #19598

Open dyremeen opened 1 week ago

dyremeen commented 1 week ago

Community Note

Terraform Version & Provider Version(s)

Terraform v1.9.5 on darwin_arm64

Affected Resource(s)

google_firestore_field

Terraform Configuration

variable "project_id" {}

terraform {
  required_version = ">= 1.7.4"
  required_providers {
    google-beta = {
      source  = "hashicorp/google-beta"
      version = "6.4.0"
    }
  }
}

resource "google_firestore_database" "default" {
  provider    = google-beta
  project     = var.project_id
  name        = "testdb"
  location_id = "europe-west1"
  type        = "FIRESTORE_NATIVE"
}

resource "google_firestore_field" "wildcard_exemption" {
  provider   = google-beta
  project    = google_firestore_database.default.project
  database   = google_firestore_database.default.name
  collection = "testcollection"
  field      = "*"
  index_config {}
}

Debug Output

The following is believed to be the relevant pieces from the debug output.

---[ REQUEST ]---------------------------------------
PATCH /v1/projects/PROJECT_ID/databases/testdb/collectionGroups/testcollection/fields/*?alt=json HTTP/1.1
Host: firestore.googleapis.com
User-Agent: Terraform/1.9.5 (+https://www.terraform.io) Terraform-Plugin-SDK/2.33.0 terraform-provider-google-beta/6.4.0
Content-Length: 36
Content-Type: application/json
Accept-Encoding: gzip

{
 "indexConfig": {},
 "ttlConfig": null
}

---[ RESPONSE ]--------------------------------------
{
  "error": {
    "code": 400,
    "message": "Updating ttl other than single field level is not supported: UpdateFieldConfigurationRequest{ref=SingleFieldRef{referenceType=ReferenceType{kind=testcollection}}, indexingMode=IndexingMode{enable=[]}, expirationMode=DISABLE, validateOnly=false}",
    "status": "INVALID_ARGUMENT"
  }
}

Expected Behavior

The resource is expected to be created successfully, since it is possible to do this with the gcloud CLI or the Firestore JSON API when including an update mask.

The equivalent gcloud CLI command below succeeds:

gcloud firestore indexes fields update '*' \
  --collection-group=testcollection \
  --database=testdb \
  --disable-indexes \
  --verbosity=debug --log-http

Calling the JSON API directly also works. Note the use of updateMask=indexConfig

export PROJECT_ID="..."
gcurl -X PATCH --data '{"indexConfig": {}}' \
  "https://firestore.googleapis.com/v1/projects/$PROJECT_ID/databases/testdb/collectionGroups/testcollection/fields/*?alt=json&updateMask=indexConfig"

From the debug output the only difference seems to be the update mask.

Actual Behavior

Terraform apply fails with an upstream API error:

Error creating Field: googleapi: Error 400: Updating ttl other than single field level is not supported: UpdateFieldConfigurationRequest{ref=SingleFieldRef{referenceType=ReferenceType{kind=testcollection}}, indexingMode=IndexingMode{enable=[]}, expirationMode=DISABLE, validateOnly=false}

Steps to reproduce

  1. terraform apply

Important Factoids

No response

References

17163

b/370113410

ggtisc commented 1 week ago

Hi @dyremeen!

Do you have an official source specifying that it is possible to use the argument field like this?

dyremeen commented 1 week ago

Thanks for the response, @ggtisc!

The only specific example I've seen is for the Google Cloud console (https://cloud.google.com/firestore/docs/query-data/indexing), but, I think the API documentation for projects.databases.collectionGroups.fields.patch pretty much confirms the approach.

The intro in the doc mentions the use of the update mask:

... Currently, field updates apply only to single field index configuration. However, calls to FirestoreAdmin.UpdateField should provide a field mask to avoid changing any configuration that the caller isn't aware of. The field mask should be specified as: { paths: "indexConfig" }.

Then, for the parameter field.name the doc says:

A field path may be a simple field name, e.g. address or a path to fields within mapValue , e.g. address.city, or a special field path. The only valid special field is *, which represents any field.

ggtisc commented 1 week ago

Possible inconsistency for the field argument of the google_firestore_field. According to the user it is possible to create the resource with a value of "*"through CLI or cloud console, but not in terraform.