Skip to content

Commit f1d10a0

Browse files
ron-galmelinath
authored andcommitted
Add support for Materialized Views (GoogleCloudPlatform#13251)
Co-authored-by: Stephen Lewis (Burrows) <[email protected]>
1 parent d5fa61a commit f1d10a0

File tree

3 files changed

+206
-0
lines changed

3 files changed

+206
-0
lines changed
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Copyright 2025 Google Inc.
2+
# Licensed under the Apache License, Version 2.0 (the "License");
3+
# you may not use this file except in compliance with the License.
4+
# You may obtain a copy of the License at
5+
#
6+
# http://www.apache.org/licenses/LICENSE-2.0
7+
#
8+
# Unless required by applicable law or agreed to in writing, software
9+
# distributed under the License is distributed on an "AS IS" BASIS,
10+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
# See the License for the specific language governing permissions and
12+
# limitations under the License.
13+
14+
---
15+
name: 'MaterializedView'
16+
kind: 'bigtable#materializedView'
17+
description: |
18+
A materialized view object that can be referenced in SQL queries.
19+
references:
20+
guides:
21+
api: 'https://cloud.google.com/bigtable/docs/reference/admin/rest/v2/projects.instances.materializedViews'
22+
docs:
23+
id_format: 'projects/{{project}}/instances/{{instance}}/materializedViews/{{materialized_view_id}}'
24+
base_url: 'projects/{{project}}/instances/{{instance}}/materializedViews?materializedViewId={{materialized_view_id}}'
25+
self_link: 'projects/{{project}}/instances/{{instance}}/materializedViews/{{materialized_view_id}}'
26+
create_url: 'projects/{{project}}/instances/{{instance}}/materializedViews?materializedViewId={{materialized_view_id}}'
27+
update_url: 'projects/{{project}}/instances/{{instance}}/materializedViews/{{materialized_view_id}}'
28+
update_verb: 'PATCH'
29+
update_mask: true
30+
delete_url: 'projects/{{project}}/instances/{{instance}}/materializedViews/{{materialized_view_id}}'
31+
import_format:
32+
- 'projects/{{project}}/instances/{{instance}}/materializedViews/{{materialized_view_id}}'
33+
timeouts:
34+
insert_minutes: 120
35+
update_minutes: 20
36+
delete_minutes: 20
37+
exclude_sweeper: true
38+
examples:
39+
- name: 'bigtable_materialized_view'
40+
primary_resource_id: 'materialized_view'
41+
vars:
42+
instance_name: 'bt-instance'
43+
table_name: 'bt-table'
44+
materialized_view_name: 'bt-materialized-view'
45+
deletion_protection: 'true'
46+
test_vars_overrides:
47+
'deletion_protection': 'false'
48+
oics_vars_overrides:
49+
'deletion_protection': 'false'
50+
# bigtable instance does not use the shared HTTP client, this test creates an instance
51+
skip_vcr: true
52+
parameters:
53+
- name: 'materializedViewId'
54+
type: String
55+
description:
56+
'The unique name of the materialized view in the form
57+
`[_a-zA-Z0-9][-_.a-zA-Z0-9]*`.'
58+
url_param_only: true
59+
required: true
60+
immutable: true
61+
- name: 'instance'
62+
type: String
63+
description: 'The name of the instance to create the materialized view within.'
64+
url_param_only: true
65+
immutable: true
66+
diff_suppress_func: 'tpgresource.CompareResourceNames'
67+
properties:
68+
- name: 'name'
69+
type: String
70+
description:
71+
'The unique name of the requested materialized view. Values are of the form
72+
`projects/<project>/instances/<instance>/materializedViews/<materializedViewId>`.'
73+
output: true
74+
- name: 'query'
75+
type: String
76+
description:
77+
'The materialized view''s select query.'
78+
required: true
79+
immutable: true
80+
- name: 'deletionProtection'
81+
type: Boolean
82+
description:
83+
'Set to true to make the MaterializedView protected against deletion.'
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
resource "google_bigtable_instance" "instance" {
2+
name = "{{index $.Vars "instance_name"}}"
3+
cluster {
4+
cluster_id = "cluster-1"
5+
zone = "us-east1-b"
6+
num_nodes = 3
7+
storage_type = "HDD"
8+
}
9+
10+
deletion_protection = {{index $.Vars "deletion_protection"}}
11+
}
12+
13+
resource "google_bigtable_table" "table" {
14+
name = "{{index $.Vars "table_name"}}"
15+
instance_name = google_bigtable_instance.instance.name
16+
17+
column_family {
18+
family = "CF"
19+
}
20+
}
21+
22+
resource "google_bigtable_materialized_view" "{{$.PrimaryResourceId}}" {
23+
materialized_view_id = "{{index $.Vars "materialized_view_name"}}"
24+
instance = google_bigtable_instance.instance.name
25+
deletion_protection = false
26+
query = <<EOT
27+
SELECT _key, COUNT(CF['col1']) as Count
28+
FROM ` + "`{{index $.Vars "table_name"}}`" + `
29+
GROUP BY _key
30+
EOT
31+
32+
depends_on = [
33+
google_bigtable_table.table
34+
]
35+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package bigtable_test
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/hashicorp/terraform-plugin-testing/plancheck"
8+
9+
"github.com/hashicorp/terraform-provider-google/google/acctest"
10+
11+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
12+
)
13+
14+
func TestAccBigtableMaterializedView_deletionProtection(t *testing.T) {
15+
// bigtable instance does not use the shared HTTP client, this test creates an instance
16+
acctest.SkipIfVcr(t)
17+
t.Parallel()
18+
19+
instanceName := fmt.Sprintf("tf-test-%s", acctest.RandString(t, 10))
20+
tableName := fmt.Sprintf("tf-test-%s", acctest.RandString(t, 10))
21+
mvName := fmt.Sprintf("tf-test-%s", acctest.RandString(t, 10))
22+
23+
acctest.VcrTest(t, resource.TestCase{
24+
PreCheck: func() { acctest.AccTestPreCheck(t) },
25+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
26+
Steps: []resource.TestStep{
27+
{
28+
Config: testAccBigtableMaterializedView_deletionProtection(instanceName, tableName, mvName, true),
29+
},
30+
{
31+
ResourceName: "google_bigtable_materialized_view.materialized_view",
32+
ImportState: true,
33+
ImportStateVerify: true,
34+
},
35+
{
36+
Config: testAccBigtableMaterializedView_deletionProtection(instanceName, tableName, mvName, false),
37+
ConfigPlanChecks: resource.ConfigPlanChecks{
38+
PreApply: []plancheck.PlanCheck{
39+
plancheck.ExpectResourceAction("google_bigtable_materialized_view.materialized_view", plancheck.ResourceActionUpdate),
40+
},
41+
},
42+
},
43+
{
44+
ResourceName: "google_bigtable_materialized_view.materialized_view",
45+
ImportState: true,
46+
ImportStateVerify: true,
47+
},
48+
},
49+
})
50+
}
51+
52+
func testAccBigtableMaterializedView_deletionProtection(instanceName, tableName, mvName string, deletion_protection bool) string {
53+
return fmt.Sprintf(`
54+
resource "google_bigtable_instance" "instance" {
55+
name = "%s"
56+
cluster {
57+
cluster_id = "%s-c"
58+
zone = "us-east1-b"
59+
}
60+
61+
deletion_protection = false
62+
}
63+
64+
resource "google_bigtable_table" "table" {
65+
name = "%s"
66+
instance_name = google_bigtable_instance.instance.id
67+
68+
column_family {
69+
family = "CF"
70+
}
71+
}
72+
73+
resource "google_bigtable_materialized_view" "materialized_view" {
74+
materialized_view_id = "%s"
75+
instance = google_bigtable_instance.instance.name
76+
deletion_protection = %v
77+
query = <<EOT
78+
SELECT _key, COUNT(CF['col']) as Count
79+
FROM %s
80+
GROUP BY _key
81+
EOT
82+
83+
depends_on = [
84+
google_bigtable_table.table
85+
]
86+
}
87+
`, instanceName, instanceName, tableName, mvName, deletion_protection, fmt.Sprintf("`%s`", tableName))
88+
}

0 commit comments

Comments
 (0)