Skip to content

Commit 6d67e34

Browse files
authored
Add Resource v1 SCC Findings Export to BQ Folder Config (GoogleCloudPlatform#11587)
1 parent a2ca90e commit 6d67e34

File tree

3 files changed

+303
-0
lines changed

3 files changed

+303
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
# Copyright 2024 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+
--- !ruby/object:Api::Resource
15+
name: 'FolderSccBigQueryExport'
16+
base_url: folders/{{folder}}/bigQueryExports
17+
self_link: folders/{{folder}}/bigQueryExports/{{big_query_export_id}}
18+
create_url: folders/{{folder}}/bigQueryExports?bigQueryExportId={{big_query_export_id}}
19+
update_verb: :PATCH
20+
update_mask: true
21+
import_format:
22+
- 'folders/{{folder}}/bigQueryExports/{{big_query_export_id}}'
23+
description: |
24+
A Cloud Security Command Center (Cloud SCC) Big Query Export Config.
25+
It represents exporting Security Command Center data, including assets, findings, and security marks
26+
to a BigQuery instance.
27+
28+
-> **Note:** In order to use Cloud SCC resources, your organization must be enrolled
29+
in [SCC Standard/Premium](https://cloud.google.com/security-command-center/docs/quickstart-security-command-center).
30+
Without doing so, you may run into errors during resource creation.
31+
references: !ruby/object:Api::Resource::ReferenceLinks
32+
guides:
33+
'Official Documentation': 'https://cloud.google.com/security-command-center/docs/how-to-analyze-findings-in-big-query'
34+
api: 'https://cloud.google.com/security-command-center/docs/reference/rest/v1/folders.bigQueryExports'
35+
examples:
36+
- !ruby/object:Provider::Terraform::Examples
37+
name: 'scc_folder_big_query_export_config_basic'
38+
primary_resource_id: 'custom_big_query_export_config'
39+
skip_test: true
40+
vars:
41+
big_query_export_id: 'my-export'
42+
dataset: 'my-dataset'
43+
dataset_id: 'my_dataset_id'
44+
name: 'my-export'
45+
folder_display_name: "folder-name"
46+
test_env_vars:
47+
org_id: :ORG_ID
48+
project: :PROJECT_NAME
49+
50+
parameters:
51+
- !ruby/object:Api::Type::String
52+
name: folder
53+
required: true
54+
immutable: true
55+
url_param_only: true
56+
description: |
57+
The folder where Cloud Security Command Center Big Query Export
58+
Config lives in.
59+
- !ruby/object:Api::Type::String
60+
name: bigQueryExportId
61+
required: true
62+
immutable: true
63+
url_param_only: true
64+
description: |
65+
This must be unique within the organization.
66+
properties:
67+
- !ruby/object:Api::Type::String
68+
name: name
69+
output: true
70+
description: |
71+
The resource name of this export, in the format
72+
`projects/{{project}}/bigQueryExports/{{big_query_export_id}}`.
73+
This field is provided in responses, and is ignored when provided in create requests.
74+
- !ruby/object:Api::Type::String
75+
name: description
76+
required: true
77+
description: |
78+
The description of the export (max of 1024 characters).
79+
validation: !ruby/object:Provider::Terraform::Validation
80+
function: 'validation.StringLenBetween(0, 1024)'
81+
- !ruby/object:Api::Type::String
82+
name: dataset
83+
required: true
84+
description: |
85+
The dataset to write findings' updates to.
86+
Its format is "projects/[projectId]/datasets/[bigquery_dataset_id]".
87+
BigQuery Dataset unique ID must contain only letters (a-z, A-Z), numbers (0-9), or underscores (_).
88+
- !ruby/object:Api::Type::String
89+
name: createTime
90+
output: true
91+
description: |
92+
The time at which the BigQuery export was created.
93+
A timestamp in RFC3339 UTC "Zulu" format, with nanosecond resolution and up to nine fractional digits.
94+
Examples: "2014-10-02T15:01:23Z" and "2014-10-02T15:01:23.045123456Z".
95+
- !ruby/object:Api::Type::String
96+
name: updateTime
97+
output: true
98+
description: |
99+
The most recent time at which the BigQuery export was updated.
100+
A timestamp in RFC3339 UTC "Zulu" format, with nanosecond resolution and up to nine fractional digits.
101+
Examples: "2014-10-02T15:01:23Z" and "2014-10-02T15:01:23.045123456Z".
102+
- !ruby/object:Api::Type::String
103+
name: mostRecentEditor
104+
output: true
105+
description: |
106+
Email address of the user who last edited the BigQuery export.
107+
- !ruby/object:Api::Type::String
108+
name: principal
109+
output: true
110+
description: |
111+
The service account that needs permission to create table and upload data to the BigQuery dataset.
112+
- !ruby/object:Api::Type::String
113+
name: filter
114+
required: true
115+
send_empty_value: true
116+
description: |
117+
Expression that defines the filter to apply across create/update
118+
events of findings. The
119+
expression is a list of zero or more restrictions combined via
120+
logical operators AND and OR. Parentheses are supported, and OR
121+
has higher precedence than AND.
122+
123+
Restrictions have the form <field> <operator> <value> and may have
124+
a - character in front of them to indicate negation. The fields
125+
map to those defined in the corresponding resource.
126+
127+
The supported operators are:
128+
129+
* = for all value types.
130+
* >, <, >=, <= for integer values.
131+
* :, meaning substring matching, for strings.
132+
133+
The supported value types are:
134+
135+
* string literals in quotes.
136+
* integer literals without quotes.
137+
* boolean literals true and false without quotes.
138+
139+
See
140+
[Filtering notifications](https://cloud.google.com/security-command-center/docs/how-to-api-filter-notifications)
141+
for information on how to write a filter.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
resource "google_folder" "folder" {
2+
parent = "organizations/<%= ctx[:test_env_vars]['org_id'] %>"
3+
display_name = "<%= ctx[:vars]['folder_display_name'] %>"
4+
5+
deletion_protection = false
6+
}
7+
8+
resource "google_bigquery_dataset" "default" {
9+
dataset_id = "<%= ctx[:vars]['dataset_id'] %>"
10+
friendly_name = "test"
11+
description = "This is a test description"
12+
location = "US"
13+
default_table_expiration_ms = 3600000
14+
default_partition_expiration_ms = null
15+
16+
labels = {
17+
env = "default"
18+
}
19+
20+
lifecycle {
21+
ignore_changes = [default_partition_expiration_ms]
22+
}
23+
}
24+
25+
resource "google_scc_folder_scc_big_query_export" "<%= ctx[:primary_resource_id] %>" {
26+
big_query_export_id = "<%= ctx[:vars]['big_query_export_id'] %>"
27+
folder = google_folder.folder.folder_id
28+
dataset = google_bigquery_dataset.default.id
29+
description = "Cloud Security Command Center Findings Big Query Export Config"
30+
filter = "state=\"ACTIVE\" AND NOT mute=\"MUTED\""
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
package securitycenter_test
2+
3+
import (
4+
"testing"
5+
6+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
7+
"github.com/hashicorp/terraform-plugin-testing/plancheck"
8+
"github.com/hashicorp/terraform-provider-google/google/acctest"
9+
"github.com/hashicorp/terraform-provider-google/google/envvar"
10+
)
11+
12+
func TestAccSecurityCenterFolderBigQueryExportConfig_update(t *testing.T) {
13+
t.Parallel()
14+
15+
randomSuffix := acctest.RandString(t, 10)
16+
dataset_id := "tf_test_" + randomSuffix
17+
dataset_id2 := dataset_id + "2"
18+
orgID := envvar.GetTestOrgFromEnv(t)
19+
20+
context := map[string]interface{}{
21+
"org_id": orgID,
22+
"random_suffix": randomSuffix,
23+
"dataset_id": dataset_id,
24+
"dataset_id2": dataset_id2,
25+
"big_query_export_id": "tf-test-export-" + randomSuffix,
26+
"folder_name": "tf-test-folder-name-" + randomSuffix,
27+
}
28+
29+
acctest.VcrTest(t, resource.TestCase{
30+
PreCheck: func() { acctest.AccTestPreCheck(t) },
31+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
32+
ExternalProviders: map[string]resource.ExternalProvider{
33+
"time": {},
34+
},
35+
Steps: []resource.TestStep{
36+
{
37+
Config: testAccSecurityCenterFolderBigQueryExportConfig_basic(context),
38+
},
39+
{
40+
ResourceName: "google_scc_folder_scc_big_query_export.default",
41+
ImportState: true,
42+
ImportStateVerify: true,
43+
ImportStateVerifyIgnore: []string{"update_time"},
44+
},
45+
{
46+
Config: testAccSecurityCenterFolderBigQueryExportConfig_update(context),
47+
ConfigPlanChecks: resource.ConfigPlanChecks{
48+
PreApply: []plancheck.PlanCheck{
49+
plancheck.ExpectResourceAction("google_scc_folder_scc_big_query_export.default", plancheck.ResourceActionUpdate),
50+
},
51+
},
52+
},
53+
{
54+
ResourceName: "google_scc_folder_scc_big_query_export.default",
55+
ImportState: true,
56+
ImportStateVerify: true,
57+
ImportStateVerifyIgnore: []string{"update_time"},
58+
},
59+
},
60+
})
61+
}
62+
63+
func testAccSecurityCenterFolderBigQueryExportConfig_basic(context map[string]interface{}) string {
64+
return acctest.Nprintf(`
65+
resource "google_folder" "folder" {
66+
parent = "organizations/%{org_id}"
67+
display_name = "%{folder_name}"
68+
deletion_protection = false
69+
}
70+
resource "google_bigquery_dataset" "default" {
71+
dataset_id = "%{dataset_id}"
72+
friendly_name = "test"
73+
description = "This is a test description"
74+
location = "US"
75+
default_table_expiration_ms = 3600000
76+
default_partition_expiration_ms = null
77+
labels = {
78+
env = "default"
79+
}
80+
lifecycle {
81+
ignore_changes = [default_partition_expiration_ms]
82+
}
83+
}
84+
resource "time_sleep" "wait_1_minute" {
85+
depends_on = [google_bigquery_dataset.default]
86+
create_duration = "3m"
87+
}
88+
resource "google_scc_folder_scc_big_query_export" "default" {
89+
big_query_export_id = "%{big_query_export_id}"
90+
folder = google_folder.folder.folder_id
91+
dataset = google_bigquery_dataset.default.id
92+
description = "Cloud Security Command Center Findings Big Query Export Config"
93+
filter = "state=\"ACTIVE\" AND NOT mute=\"MUTED\""
94+
95+
depends_on = [time_sleep.wait_1_minute]
96+
}
97+
98+
`, context)
99+
}
100+
101+
func testAccSecurityCenterFolderBigQueryExportConfig_update(context map[string]interface{}) string {
102+
return acctest.Nprintf(`
103+
resource "google_folder" "folder" {
104+
parent = "organizations/%{org_id}"
105+
display_name = "%{folder_name}"
106+
deletion_protection = false
107+
}
108+
resource "google_bigquery_dataset" "default" {
109+
dataset_id = "%{dataset_id2}"
110+
friendly_name = "test"
111+
description = "This is a test description"
112+
location = "US"
113+
default_table_expiration_ms = 3600000
114+
default_partition_expiration_ms = null
115+
labels = {
116+
env = "default"
117+
}
118+
lifecycle {
119+
ignore_changes = [default_partition_expiration_ms]
120+
}
121+
}
122+
resource "google_scc_folder_scc_big_query_export" "default" {
123+
big_query_export_id = "%{big_query_export_id}"
124+
folder = google_folder.folder.folder_id
125+
dataset = google_bigquery_dataset.default.id
126+
description = "SCC Findings Big Query Export Update"
127+
filter = ""
128+
}
129+
130+
`, context)
131+
}

0 commit comments

Comments
 (0)