Skip to content

Commit

Permalink
Added firestore module (#2374)
Browse files Browse the repository at this point in the history
  • Loading branch information
apichick authored Jun 26, 2024
1 parent 3933a74 commit 00080cd
Show file tree
Hide file tree
Showing 11 changed files with 817 additions and 0 deletions.
173 changes: 173 additions & 0 deletions modules/firestore/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
# Firestore

This module allows to crete a firestore datatabase, fields, indexes and documents.

## Examples

### New database

```hcl
module "firestore" {
source = "./fabric/modules/firestore"
project_id = "my-project"
database = {
name = "my-database"
location_id = "nam5"
type = "FIRESTORE_NATIVE"
}
}
# tftest modules=1 resources=1 inventory=new-database.yaml
```

### New database with weekly backup

```hcl
module "firestore" {
source = "./fabric/modules/firestore"
project_id = "my-project"
database = {
name = "my-database"
location_id = "nam5"
type = "FIRESTORE_NATIVE"
}
backup_schedule = {
retention = "86400s"
weekly_recurrence = "MONDAY"
}
}
# tftest modules=1 resources=2 inventory=new-database-with-weekly-backup.yaml
```

### New database with document

```hcl
module "firestore" {
source = "./fabric/modules/firestore"
project_id = "my-project"
database = {
name = "my-database"
location_id = "nam5"
type = "FIRESTORE_NATIVE"
}
documents = {
my-doc-1 = {
collection = "my-coll"
document_id = "d3db1c14-e56d-4597-af1c-f95c2d2290c1"
fields = {
field1 = "value1"
field2 = "value2"
}
}
}
}
# tftest modules=1 resources=2 inventory=new-database-with-document.yaml
```

### Existing database with document

```hcl
module "firestore" {
source = "./fabric/modules/firestore"
project_id = "my-project"
database = {
name = "my-database"
}
database_create = false
documents = {
my-doc-1 = {
collection = "my-coll"
document_id = "d3db1c14-e56d-4597-af1c-f95c2d2290c1"
fields = {
field1 = "value1"
field2 = "value2"
}
}
}
}
# tftest modules=1 resources=1 inventory=existing-database-with-document.yaml
```

### New database with field

```hcl
module "firestore" {
source = "./fabric/modules/firestore"
project_id = "my-project"
database = {
name = "my-database"
location_id = "name5"
type = "FIRESTORE_NATIVE"
}
fields = {
my-field-in-my-coll = {
collection = "my-coll"
field = "my-field"
indexes = [
{
order = "ASCENDING"
query_scope = "COLLECTION_GROUP"
},
{
array_config = "CONTAINS"
}
]
}
}
}
# tftest modules=1 resources=2 inventory=new-database-with-field.yaml
```

### New database with index

```hcl
module "firestore" {
source = "./fabric/modules/firestore"
project_id = "my-project"
database = {
name = "my-database"
location_id = "name5"
type = "FIRESTORE_NATIVE"
}
indexes = {
my-index = {
collection = "my-coll"
fields = [
{
field_path = "name"
order = "ASCENDING"
},
{
field_path = "description"
order = "DESCENDING"
}
]
}
}
}
# tftest modules=1 resources=2 inventory=new-database-with-index.yaml
```
<!-- BEGIN TFDOC -->
## Variables

| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
| [database](variables.tf#L41) | Database attributes. | <code title="object&#40;&#123;&#10; app_engine_integration_mode &#61; optional&#40;string&#41;&#10; concurrency_mode &#61; optional&#40;string&#41;&#10; deletion_policy &#61; optional&#40;string&#41;&#10; delete_protection_state &#61; optional&#40;string&#41;&#10; kms_key_name &#61; optional&#40;string&#41;&#10; location_id &#61; optional&#40;string&#41;&#10; name &#61; string&#10; point_in_time_recovery_enablement &#61; optional&#40;string&#41;&#10; type &#61; optional&#40;string&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> || |
| [project_id](variables.tf#L228) | Project id. | <code>string</code> || |
| [backup_schedule](variables.tf#L17) | Backup schedule. | <code title="object&#40;&#123;&#10; retention &#61; string&#10; daily_recurrence &#61; optional&#40;bool, false&#41;&#10; weekly_recurrence &#61; optional&#40;string&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
| [database_create](variables.tf#L95) | Flag indicating whether the database should be created of not. | <code>string</code> | | <code>&#34;true&#34;</code> |
| [documents](variables.tf#L101) | Documents. | <code title="map&#40;object&#40;&#123;&#10; collection &#61; string&#10; document_id &#61; string&#10; fields &#61; any&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [fields](variables.tf#L112) | Fields. | <code title="map&#40;object&#40;&#123;&#10; collection &#61; string&#10; field &#61; string&#10; indexes &#61; optional&#40;list&#40;object&#40;&#123;&#10; query_scope &#61; optional&#40;string&#41;&#10; order &#61; optional&#40;string&#41;&#10; array_config &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#41;&#10; ttl_config &#61; optional&#40;bool, false&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [indexes](variables.tf#L164) | Indexes. | <code title="map&#40;object&#40;&#123;&#10; api_scope &#61; optional&#40;string&#41;&#10; collection &#61; string&#10; fields &#61; list&#40;object&#40;&#123;&#10; field_path &#61; optional&#40;string&#41;&#10; order &#61; optional&#40;string&#41;&#10; array_config &#61; optional&#40;string&#41;&#10; vector_config &#61; optional&#40;object&#40;&#123;&#10; dimension &#61; optional&#40;number&#41;&#10; flat &#61; optional&#40;bool&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#41;&#10; query_scope &#61; optional&#40;string&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |

## Outputs

| name | description | sensitive |
|---|---|:---:|
| [firestore_database](outputs.tf#L17) | Firestore database. | |
| [firestore_document_ids](outputs.tf#L22) | Firestore document ids. | |
| [firestore_documents](outputs.tf#L26) | Firestore documents. | |
| [firestore_field_ids](outputs.tf#L31) | Firestore field ids. | |
| [firestore_fields](outputs.tf#L36) | Firestore fields. | |
| [firestore_index_ids](outputs.tf#L41) | Firestore index ids. | |
| [firestore_indexes](outputs.tf#L46) | Firestore indexes. | |
<!-- END TFDOC -->
135 changes: 135 additions & 0 deletions modules/firestore/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

locals {
firestore_database_name = var.database_create ? google_firestore_database.firestore_database[0].name : var.database.name
}

resource "google_firestore_database" "firestore_database" {
count = var.database_create ? 1 : 0
provider = google-beta
project = var.project_id
name = var.database.name
location_id = var.database.location_id
type = var.database.type
concurrency_mode = var.database.concurrency_mode
app_engine_integration_mode = var.database.app_engine_integration_mode
point_in_time_recovery_enablement = var.database.point_in_time_recovery_enablement
delete_protection_state = var.database.delete_protection_state
deletion_policy = var.database.deletion_policy

dynamic "cmek_config" {
for_each = var.database.kms_key_name == null ? [] : [""]
content {
kms_key_name = var.database.kms_key_name
}
}
lifecycle {
precondition {
condition = var.database.type != null && contains(["DATASTORE_MODE", "FIRESTORE_NATIVE"], var.database.type)
error_message = "Invalid type. Possible values: DATASTORE_MODE, FIRESTORE_NATIVE"
}
precondition {
condition = var.database.location_id != null
error_message = "location_id must be set."
}
}
}

resource "google_firestore_backup_schedule" "firestore_backup_schedule" {
count = var.backup_schedule == null ? 0 : 1
project = var.project_id
database = local.firestore_database_name
retention = var.backup_schedule.retention

dynamic "daily_recurrence" {
for_each = var.backup_schedule.daily_recurrence ? [""] : []
content {

}
}

dynamic "weekly_recurrence" {
for_each = var.backup_schedule.weekly_recurrence == null ? [] : [""]
content {
day = var.backup_schedule.weekly_recurrence
}
}
}

resource "google_firestore_field" "firestore_fields" {
for_each = var.fields
project = var.project_id
database = local.firestore_database_name
collection = each.value.collection
field = each.value.field

dynamic "index_config" {
for_each = each.value.indexes == null ? [] : [""]
content {
dynamic "indexes" {
for_each = each.value.indexes
content {
query_scope = indexes.value.query_scope
order = indexes.value.order
array_config = indexes.value.array_config
}
}
}
}
dynamic "ttl_config" {
for_each = each.value.ttl_config ? [""] : []
content {

}
}
}

resource "google_firestore_document" "firestore_documents" {
for_each = var.documents
project = var.project_id
database = local.firestore_database_name
collection = each.value.collection
document_id = each.value.document_id
fields = jsonencode(each.value.fields)
}

resource "google_firestore_index" "firestore_indexes" {
for_each = var.indexes
project = var.project_id
database = local.firestore_database_name
collection = each.value.collection
dynamic "fields" {
for_each = each.value.fields
content {
field_path = fields.value.field_path
order = fields.value.order
array_config = fields.value.array_config
dynamic "vector_config" {
for_each = fields.value.vector_config == null ? [] : [""]
content {
dimension = fields.value.vector_config.dimension
dynamic "flat" {
for_each = fields.value.vector_config.flat ? [""] : []
content {

}
}
}
}
}
}
}
50 changes: 50 additions & 0 deletions modules/firestore/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

output "firestore_database" {
description = "Firestore database."
value = var.database_create ? google_firestore_database.firestore_database[0] : null
}

output "firestore_document_ids" {
description = "Firestore document ids."
value = [for v in google_firestore_document.firestore_documents : v.id]
}
output "firestore_documents" {
description = "Firestore documents."
value = google_firestore_document.firestore_documents
}

output "firestore_field_ids" {
description = "Firestore field ids."
value = [for v in google_firestore_field.firestore_fields : v.id]
}

output "firestore_fields" {
description = "Firestore fields."
value = google_firestore_field.firestore_fields
}

output "firestore_index_ids" {
description = "Firestore index ids."
value = { for k, v in google_firestore_index.firestore_indexes : k => v.id }
}

output "firestore_indexes" {
description = "Firestore indexes."
value = google_firestore_index.firestore_indexes
}

Loading

0 comments on commit 00080cd

Please sign in to comment.