-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Add Observability Folder Settings Resource #16542
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
rileykarson
merged 28 commits into
GoogleCloudPlatform:main
from
leowonderful:observability-folder-settings-resource
Mar 4, 2026
Merged
Changes from all commits
Commits
Show all changes
28 commits
Select commit
Hold shift + click to select a range
4107b3a
Add datasource for observability folder settings
leowonderful 7e22557
Add required wait to test
leowonderful 0011be5
remove retry logic from datasource
leowonderful 07a0ec0
Add Observability Folder Settings resource
leowonderful 586ab72
reflect beta, not ga
leowonderful ca7f7c7
Test formatting fixes
leowonderful 5a35816
make tests beta-only
leowonderful 768777e
fully make tests beta-only
leowonderful 23ec614
stop using autogen async
leowonderful 309d58f
format and add version guards
leowonderful 69be1ac
guard the entire import block
leowonderful d76e4d7
add docs
leowonderful eda2f96
reflect beta-only in datasource doc
leowonderful 4a06d7a
backlink to resource
leowonderful dcfb264
just use a shared pre_create and pre_update for all observability set…
leowonderful 2fcae96
actually just use unique pre_[create, update]
leowonderful 33f530c
version guard datasource and remove custom operation
leowonderful 667e225
add sleep for propagation
leowonderful 1cf8a27
More descriptive fmt.Error
leowonderful da4f729
Make datasource more robust and accept empty string masks
leowonderful 3fc060b
stop re-setting obj during mask construction
leowonderful 9774cc4
Add new guide to datasource docs
leowonderful 8d24055
format examples correctly, use `update_mask`
leowonderful 2fd215f
Merge branch 'main' into observability-folder-settings-resource
leowonderful 879efeb
Fix "too many arguments" by custom defining Wait operation
leowonderful 28596ae
use `include_project` so we can get rid of the custom operation code
leowonderful 9dfcdb7
also do include_project for org settings
leowonderful 1d941ed
Merge branch 'main' into observability-folder-settings-resource
leowonderful File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| # Copyright 2026 Google Inc. | ||
| # 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. | ||
|
|
||
| --- | ||
| name: 'FolderSettings' | ||
| description: Manages Cloud Observability settings for a folder. | ||
| min_version: 'beta' | ||
|
|
||
| base_url: 'folders/{{folder}}/locations/{{location}}/settings' | ||
| self_link: 'folders/{{folder}}/locations/{{location}}/settings' | ||
| create_url: 'folders/{{folder}}/locations/{{location}}/settings' | ||
| create_verb: 'PATCH' | ||
| update_url: 'folders/{{folder}}/locations/{{location}}/settings' | ||
| update_verb: 'PATCH' | ||
| exclude_delete: true | ||
| autogen_async: true | ||
| update_mask: true | ||
|
|
||
| custom_code: | ||
| pre_create: templates/terraform/pre_create/observability_folder_settings.go.tmpl | ||
| import_format: | ||
| - 'folders/{{folder}}/locations/{{location}}/settings' | ||
|
|
||
| async: | ||
| include_project: true | ||
| operation: | ||
| timeouts: | ||
| insert_minutes: 10 | ||
| update_minutes: 10 | ||
| base_url: '{{op_id}}' | ||
| result: | ||
| resource_inside_response: true | ||
|
|
||
| examples: | ||
| - name: "observability_folder_settings_basic" | ||
| config_path: "templates/terraform/examples/observability_folder_settings_basic.tf.tmpl" | ||
| primary_resource_id: "primary" | ||
| external_providers: ["time"] | ||
| vars: | ||
| location: "us" | ||
| kms_key_name: "example-key" | ||
| folder_name: "tf-test-folder" | ||
| test_env_vars: | ||
| org_id: 'ORG_ID' | ||
| test_vars_overrides: | ||
| kms_key_name: 'acctest.BootstrapKMSKeyInLocation(t, "us").CryptoKey.Name' | ||
| - name: "observability_folder_settings_basic_global" | ||
| config_path: "templates/terraform/examples/observability_folder_settings_basic_global.tf.tmpl" | ||
| primary_resource_id: "primary_global" | ||
| external_providers: ["time"] | ||
| vars: | ||
| location: "global" | ||
| test_env_vars: | ||
| org_id: 'ORG_ID' | ||
|
|
||
| parameters: | ||
| - name: 'location' | ||
| type: String | ||
| description: 'The location of the settings.' | ||
| url_param_only: true | ||
| required: true | ||
| immutable: true | ||
| - name: 'folder' | ||
| type: String | ||
| description: 'The folder ID.' | ||
| url_param_only: true | ||
| required: true | ||
| immutable: true | ||
|
|
||
| properties: | ||
| - name: 'defaultStorageLocation' | ||
| type: String | ||
| description: 'The default storage location for new resources, e.g. buckets. Only valid for global location.' | ||
| - name: 'kmsKeyName' | ||
| type: String | ||
| description: 'The default Cloud KMS key to use for new resources. Only valid for regional locations.' | ||
| - name: 'name' | ||
| type: String | ||
| description: 'The resource name of the settings.' | ||
| output: true | ||
| - name: 'serviceAccountId' | ||
| type: String | ||
| description: 'The service account used by Cloud Observability for this folder.' | ||
| output: true |
41 changes: 41 additions & 0 deletions
41
mmv1/templates/terraform/examples/observability_folder_settings_basic.tf.tmpl
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| resource "google_folder" "test_folder" { | ||
| provider = "google-beta" | ||
| display_name = "tf-test-%{random_suffix}" | ||
| parent = "organizations/{{index $.TestEnvVars "org_id"}}" | ||
| deletion_protection = false | ||
| } | ||
|
|
||
| # Wait for the folder to be created and recognized by the Observability API | ||
| resource "time_sleep" "wait_for_settings_propagation" { | ||
| create_duration = "90s" | ||
| depends_on = [google_folder.test_folder] | ||
| } | ||
|
|
||
| data "google_observability_folder_settings" "settings_data" { | ||
| provider = "google-beta" | ||
| folder = google_folder.test_folder.folder_id | ||
| location = "us" | ||
| depends_on = [time_sleep.wait_for_settings_propagation] | ||
| } | ||
|
|
||
| # Add a delay to allow the service account to propagate | ||
| resource "time_sleep" "wait_for_sa_propagation" { | ||
| create_duration = "90s" | ||
| depends_on = [data.google_observability_folder_settings.settings_data] | ||
| } | ||
|
|
||
| resource "google_kms_crypto_key_iam_member" "iam" { | ||
| provider = "google-beta" | ||
| crypto_key_id = "{{index $.Vars "kms_key_name"}}" | ||
| role = "roles/cloudkms.cryptoKeyEncrypterDecrypter" | ||
| member = "serviceAccount:${data.google_observability_folder_settings.settings_data.service_account_id}" | ||
| depends_on = [time_sleep.wait_for_sa_propagation] | ||
| } | ||
|
|
||
| resource "google_observability_folder_settings" "primary" { | ||
| provider = "google-beta" | ||
| location = "us" | ||
| folder = google_folder.test_folder.folder_id | ||
| kms_key_name = "{{index $.Vars "kms_key_name"}}" | ||
| depends_on = [google_kms_crypto_key_iam_member.iam] | ||
| } |
27 changes: 27 additions & 0 deletions
27
mmv1/templates/terraform/examples/observability_folder_settings_basic_global.tf.tmpl
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| resource "google_folder" "test_folder" { | ||
| provider = "google-beta" | ||
| display_name = "tf-test-%{random_suffix}" | ||
| parent = "organizations/{{index $.TestEnvVars "org_id"}}" | ||
| deletion_protection = false | ||
| } | ||
|
|
||
| # Wait for the folder to be created and recognized by the Observability API | ||
| resource "time_sleep" "wait_for_folder" { | ||
| create_duration = "90s" | ||
| depends_on = [google_folder.test_folder] | ||
| } | ||
|
|
||
| data "google_observability_folder_settings" "settings_data" { | ||
| provider = "google-beta" | ||
| folder = google_folder.test_folder.folder_id | ||
| location = "global" | ||
| depends_on = [time_sleep.wait_for_folder] | ||
| } | ||
|
|
||
| resource "google_observability_folder_settings" "primary_global" { | ||
| provider = "google-beta" | ||
| location = "global" | ||
| folder = google_folder.test_folder.folder_id | ||
| default_storage_location = "us" | ||
| depends_on = [data.google_observability_folder_settings.settings_data] | ||
| } |
14 changes: 14 additions & 0 deletions
14
mmv1/templates/terraform/pre_create/observability_folder_settings.go.tmpl
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| var masks []string | ||
| if !d.GetRawConfig().GetAttr("default_storage_location").IsNull() { | ||
| masks = append(masks, "defaultStorageLocation") | ||
| } | ||
| if !d.GetRawConfig().GetAttr("kms_key_name").IsNull() { | ||
| masks = append(masks, "kmsKeyName") | ||
| } | ||
|
|
||
| if len(masks) > 0 { | ||
| url, err = transport_tpg.AddQueryParams(url, map[string]string{"updateMask": strings.Join(masks, ",")}) | ||
| if err != nil { | ||
| return err | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
39 changes: 39 additions & 0 deletions
39
..._party/terraform/services/observability/data_source_observability_folder_settings.go.tmpl
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| package observability | ||
|
|
||
| {{ if ne $.TargetVersionName "ga" -}} | ||
| import ( | ||
| "fmt" | ||
|
|
||
| "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
| "github.com/hashicorp/terraform-provider-google/google/tpgresource" | ||
| ) | ||
|
|
||
| func DataSourceObservabilityFolderSettings() *schema.Resource { | ||
| dsSchema := tpgresource.DatasourceSchemaFromResourceSchema(ResourceObservabilityFolderSettings().Schema) | ||
|
|
||
| tpgresource.AddRequiredFieldsToSchema(dsSchema, "folder") | ||
| tpgresource.AddRequiredFieldsToSchema(dsSchema, "location") | ||
|
|
||
| return &schema.Resource{ | ||
| Read: dataSourceObservabilityFolderSettingsRead, | ||
| Schema: dsSchema, | ||
| } | ||
| } | ||
|
|
||
| func dataSourceObservabilityFolderSettingsRead(d *schema.ResourceData, meta interface{}) error { | ||
| folder := d.Get("folder").(string) | ||
| location := d.Get("location").(string) | ||
|
|
||
| id := fmt.Sprintf("folders/%s/locations/%s/settings", folder, location) | ||
| d.SetId(id) | ||
|
|
||
| err := resourceObservabilityFolderSettingsRead(d, meta) | ||
| if err != nil { | ||
| return nil | ||
| } | ||
| if d.Id() == "" { | ||
| return fmt.Errorf("%s not found", id) | ||
| } | ||
| return nil | ||
| } | ||
| {{- end }} |
72 changes: 72 additions & 0 deletions
72
...y/terraform/services/observability/data_source_observability_folder_settings_test.go.tmpl
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,72 @@ | ||
| package observability_test | ||
|
|
||
| {{ if ne $.TargetVersionName "ga" -}} | ||
| import ( | ||
| "testing" | ||
|
|
||
| "github.com/hashicorp/terraform-plugin-testing/helper/resource" | ||
| "github.com/hashicorp/terraform-provider-google/google/acctest" | ||
| "github.com/hashicorp/terraform-provider-google/google/envvar" | ||
| ) | ||
|
|
||
| func TestAccObservabilityFolderSettings_datasource(t *testing.T) { | ||
| t.Parallel() | ||
|
|
||
| orgId := envvar.GetTestOrgFromEnv(t) | ||
| folderDisplayName := "tf-test-" + acctest.RandString(t, 10) | ||
|
|
||
| context := map[string]interface{}{ | ||
| "org_id": orgId, | ||
| "folder_display_name": folderDisplayName, | ||
| "location": "us", | ||
| } | ||
| dataResourceName := "data.google_observability_folder_settings.settings" | ||
|
|
||
| acctest.VcrTest(t, resource.TestCase{ | ||
| PreCheck: func() { acctest.AccTestPreCheck(t) }, | ||
| ProtoV5ProviderFactories: acctest.ProtoV5ProviderBetaFactories(t), | ||
| ExternalProviders: map[string]resource.ExternalProvider{ | ||
| "time": {}, | ||
| }, | ||
| Steps: []resource.TestStep{ | ||
| { | ||
| Config: testAccObservabilityFolderSettings_datasource(context), | ||
| Check: resource.ComposeTestCheckFunc( | ||
| acctest.CheckDataSourceStateMatchesResourceState(dataResourceName, "google_observability_folder_settings.settings"), | ||
| ), | ||
| }, | ||
| }, | ||
| }) | ||
| } | ||
|
|
||
| func testAccObservabilityFolderSettings_datasource(context map[string]interface{}) string { | ||
| return acctest.Nprintf(` | ||
| resource "google_folder" "test" { | ||
| provider = google-beta | ||
| display_name = "%{folder_display_name}" | ||
| parent = "organizations/%{org_id}" | ||
| deletion_protection = false | ||
| } | ||
|
|
||
| resource "time_sleep" "wait_for_folder" { | ||
| create_duration = "90s" | ||
| depends_on = [google_folder.test] | ||
| } | ||
|
|
||
| resource "google_observability_folder_settings" "settings" { | ||
| provider = google-beta | ||
| folder = google_folder.test.folder_id | ||
| location = "%{location}" | ||
| kms_key_name = "" | ||
| depends_on = [time_sleep.wait_for_folder] | ||
| } | ||
|
|
||
| data "google_observability_folder_settings" "settings" { | ||
| provider = google-beta | ||
| folder = google_folder.test.folder_id | ||
| location = "%{location}" | ||
| depends_on = [time_sleep.wait_for_folder] | ||
| } | ||
| `, context) | ||
| } | ||
| {{- end }} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Checking for explicit set-ness in config will guard against nulling these values out, but will also create a permadiff because Terraform expects the values out to be null/zero if unset. Can you walk through why we want to guard on being set here vs just setting both values in a fixed update mask?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are two reasons, the first is that we never allow users to update both resource fields (
kmsKeyNameanddefaultStorageLocation). The second is because I want to allow setting a field to"".Very briefly:
kmsKeyNameif the Settings is in theglobalregion.defaultStorageLocationif the Settings is not in theglobalregion.You can set either one of these fields in a Settings resource, but not both. When I used the default fixed update mask the API would complain that both fields were included as update masks, this is why I needed to make a custom
pre_createandpre_updatein the first place.Second, I wanted the explicit set-ness check of
...IsNull()to allow explicit clears by setting a field to the empty string"". Originally I just had this check asGetOkbut this didn't work because it treated""as being unset.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no pre_update in this change- just confirming, are you seeing the results you expect w/o one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I'll note there's no pre_update atm, but it does appear to work as intended.