From 7a51a8974277f5ff4ff1dd05b080908e512b4f76 Mon Sep 17 00:00:00 2001 From: megan07 Date: Wed, 13 Nov 2019 12:48:11 -0600 Subject: [PATCH] update upgrade guide (#2665) --- products/accesscontextmanager/api.yaml | 11 +- products/appengine/api.yaml | 3 + products/bigquery/api.yaml | 1 + products/bigtable/api.yaml | 10 +- products/binaryauthorization/api.yaml | 5 + products/cloudbuild/api.yaml | 6 +- products/cloudfunctions/api.yaml | 13 + products/cloudrun/api.yaml | 1 - products/cloudscheduler/api.yaml | 21 +- products/compute/api.yaml | 118 +-- products/dns/api.yaml | 1 + products/firestore/api.yaml | 2 + products/monitoring/api.yaml | 62 +- .../resources/resource_compute_instance.go | 71 -- ...resource_compute_instance_group_manager.go | 52 -- .../resource_compute_instance_template.go | 104 --- ...e_compute_region_instance_group_manager.go | 4 - .../resources/resource_storage_bucket.go | 33 - third_party/terraform/utils/utils.go.erb | 14 - .../guides/version_3_upgrade.html.markdown | 804 +++++++++++++++++- 20 files changed, 932 insertions(+), 404 deletions(-) diff --git a/products/accesscontextmanager/api.yaml b/products/accesscontextmanager/api.yaml index 51b84b5e480c..f763276b18bd 100644 --- a/products/accesscontextmanager/api.yaml +++ b/products/accesscontextmanager/api.yaml @@ -267,14 +267,15 @@ objects: Format: "major.minor.patch" such as "10.5.301", "9.2.1". - !ruby/object:Api::Type::Enum name: 'osType' + required: true description: | The operating system type of the device. values: - - :OS_UNSPECIFIED - - :DESKTOP_MAC - - :DESKTOP_WINDOWS - - :DESKTOP_LINUX - - :DESKTOP_CHROME_OS + - :OS_UNSPECIFIED + - :DESKTOP_MAC + - :DESKTOP_WINDOWS + - :DESKTOP_LINUX + - :DESKTOP_CHROME_OS - !ruby/object:Api::Resource name: 'ServicePerimeter' # This is an unusual API, so we need to use a few fields to map the methods diff --git a/products/appengine/api.yaml b/products/appengine/api.yaml index 6fec988cfe68..4f103a4a3781 100644 --- a/products/appengine/api.yaml +++ b/products/appengine/api.yaml @@ -332,16 +332,19 @@ objects: - :REDIRECT_HTTP_RESPONSE_CODE_307 - !ruby/object:Api::Type::NestedObject name: 'script' + # TODO (mbang): Exactly one of script, staticFiles, or apiEndpoint must be set description: | Executes a script to handle the requests that match this URL pattern. Only the auto value is supported for Node.js in the App Engine standard environment, for example "script:" "auto". properties: - !ruby/object:Api::Type::String name: 'scriptPath' + required: true description: | Path to the script from the application root directory. - !ruby/object:Api::Type::NestedObject name: 'staticFiles' + # TODO (mbang): Exactly one of script, staticFiles, or apiEndpoint must be set description: | Files served directly to the user for a given URL, such as images, CSS stylesheets, or JavaScript source files. Static file handlers describe which files in the application directory are static files, and which URLs serve them. properties: diff --git a/products/bigquery/api.yaml b/products/bigquery/api.yaml index e287a628f7eb..76a0d427aac5 100644 --- a/products/bigquery/api.yaml +++ b/products/bigquery/api.yaml @@ -52,6 +52,7 @@ objects: description: An email address of a Google Group to grant access to. - !ruby/object:Api::Type::String name: 'role' + required: true description: | Describes the rights granted to the user specified by the other member of the access object. Primitive, Predefined and custom diff --git a/products/bigtable/api.yaml b/products/bigtable/api.yaml index b5523a155a57..2d6420b49562 100644 --- a/products/bigtable/api.yaml +++ b/products/bigtable/api.yaml @@ -64,8 +64,9 @@ objects: Long form description of the use case for this app profile. - !ruby/object:Api::Type::Boolean name: 'multiClusterRoutingUseAny' - conflicts: - - singleClusterRouting + exactly_one_of: + - single_cluster_routing + - multi_cluster_routing_use_any description: | If true, read/write requests are routed to the nearest cluster in the instance, and will fail over to the nearest cluster that is available in the event of transient errors or delays. Clusters in a region are considered equidistant. Choosing this option sacrifices read-your-writes @@ -73,8 +74,9 @@ objects: input: true - !ruby/object:Api::Type::NestedObject name: 'singleClusterRouting' - conflicts: - - multiClusterRoutingUseAny + exactly_one_of: + - single_cluster_routing + - multi_cluster_routing_use_any description: | Use a single-cluster routing policy. input: true diff --git a/products/binaryauthorization/api.yaml b/products/binaryauthorization/api.yaml index acef119c7e20..f36d3ec143c3 100644 --- a/products/binaryauthorization/api.yaml +++ b/products/binaryauthorization/api.yaml @@ -96,6 +96,7 @@ objects: See the documentation on publicKey cases below for details. - !ruby/object:Api::Type::String name: asciiArmoredPgpPublicKey + # TODO (mbang): Exactly one of asciiArmoredPgpPublicKey or pkixPublicKey must be set description: | ASCII-armored representation of a PGP public key, as the entire output by the command @@ -108,6 +109,7 @@ objects: be overwritten by the API-calculated ID. - !ruby/object:Api::Type::NestedObject name: pkixPublicKey + # TODO (mbang): Exactly one of asciiArmoredPgpPublicKey or pkixPublicKey must be set description: | A raw PKIX SubjectPublicKeyInfo format public key. @@ -178,6 +180,7 @@ objects: properties: - !ruby/object:Api::Type::String name: namePattern + required: true description: | An image name pattern to whitelist, in the form `registry/path/to/image`. This supports a trailing * as a @@ -202,6 +205,7 @@ objects: properties: - !ruby/object:Api::Type::Enum name: evaluationMode + required: true description: How this admission rule will be evaluated. values: - :ALWAYS_ALLOW @@ -221,6 +225,7 @@ objects: item_type: Api::Type::String - !ruby/object:Api::Type::Enum name: enforcementMode + required: true description: | The action when a pod creation is denied by the admission rule. values: diff --git a/products/cloudbuild/api.yaml b/products/cloudbuild/api.yaml index b3b8a06cf0ea..838242d5f0e3 100644 --- a/products/cloudbuild/api.yaml +++ b/products/cloudbuild/api.yaml @@ -73,7 +73,8 @@ objects: Substitutions data for Build resource. - !ruby/object:Api::Type::String name: 'filename' - conflicts: + exactly_one_of: + - filename - build description: | Path, from the source root, to a file whose contents is used for the template. Either a filename or build template must be provided. @@ -219,6 +220,9 @@ objects: - github.0.push.0.tag - !ruby/object:Api::Type::NestedObject name: 'build' + exactly_one_of: + - filename + - build description: | Contents of the build template. Either a filename or build template must be provided. properties: diff --git a/products/cloudfunctions/api.yaml b/products/cloudfunctions/api.yaml index 5223ead029b5..30e58d0d8bb4 100644 --- a/products/cloudfunctions/api.yaml +++ b/products/cloudfunctions/api.yaml @@ -136,17 +136,30 @@ objects: description: | The Google Cloud Storage URL, starting with gs://, pointing to the zip archive which contains the function. + exactly_one_of: + - source_repository + - source_archive_url + - source_upload_url - !ruby/object:Api::Type::String name: 'sourceUploadUrl' description: | The Google Cloud Storage signed URL used for source uploading. + exactly_one_of: + - source_repository + - source_archive_url + - source_upload_url - !ruby/object:Api::Type::NestedObject name: 'sourceRepository' description: | The source repository where a function is hosted. + exactly_one_of: + - source_repository + - source_archive_url + - source_upload_url properties: - !ruby/object:Api::Type::String name: 'url' + required: true description: | The URL pointing to the hosted repository where the function is defined - !ruby/object:Api::Type::String diff --git a/products/cloudrun/api.yaml b/products/cloudrun/api.yaml index 7d2fb63c348d..7c536d37f3fc 100644 --- a/products/cloudrun/api.yaml +++ b/products/cloudrun/api.yaml @@ -272,7 +272,6 @@ objects: properties: - !ruby/object:Api::Type::NestedObject name: template - required: true description: |- template holds the latest specification for the Revision to be stamped out. The template references the container image, and may also diff --git a/products/cloudscheduler/api.yaml b/products/cloudscheduler/api.yaml index c8b75827259f..422b4e22f9bb 100644 --- a/products/cloudscheduler/api.yaml +++ b/products/cloudscheduler/api.yaml @@ -158,9 +158,10 @@ objects: If the job providers a Pub/Sub target the cron will publish a message to the provided topic input: true - conflicts: - - httpTarget - - appEngineHttpTarget + exactly_one_of: + - pubsub_target + - http_target + - app_engine_http_target properties: - !ruby/object:Api::Type::String name: topicName @@ -191,9 +192,10 @@ objects: If the job providers a App Engine HTTP target the cron will send a request to the service instance input: true - conflicts: - - pubsubTarget - - httpTarget + exactly_one_of: + - pubsub_target + - http_target + - app_engine_http_target properties: - !ruby/object:Api::Type::String name: httpMethod @@ -273,9 +275,10 @@ objects: If the job providers a http_target the cron will send a request to the targeted url input: true - conflicts: - - pubsubTarget - - appEngineHttpTarget + exactly_one_of: + - pubsub_target + - http_target + - app_engine_http_target properties: - !ruby/object:Api::Type::String name: uri diff --git a/products/compute/api.yaml b/products/compute/api.yaml index 97480c4bcb49..2e8fb6053046 100644 --- a/products/compute/api.yaml +++ b/products/compute/api.yaml @@ -2848,8 +2848,9 @@ objects: The list of ALLOW rules specified by this firewall. Each rule specifies a protocol and port-range tuple that describes a permitted connection. - conflicts: - - denied + exactly_one_of: + - allow + - deny item_type: !ruby/object:Api::Type::NestedObject properties: # IPProtocol has to be string, instead of Enum because user can @@ -2880,6 +2881,9 @@ objects: output: true - !ruby/object:Api::Type::Array name: 'denied' + exactly_one_of: + - allow + - deny description: | The list of DENY rules specified by this firewall. Each rule specifies a protocol and port-range tuple that describes a denied connection. @@ -4012,11 +4016,12 @@ objects: - :HTTP2 - !ruby/object:Api::Type::NestedObject name: 'httpHealthCheck' - conflicts: - - httpsHealthCheck - - http2HealthCheck - - tcpHealthCheck - - sslHealthCheck + exactly_one_of: + - http_health_check + - https_health_check + - http2_health_check + - tcp_health_check + - ssl_health_check properties: - !ruby/object:Api::Type::String name: 'host' @@ -4134,11 +4139,12 @@ objects: - :USE_SERVING_PORT - !ruby/object:Api::Type::NestedObject name: 'httpsHealthCheck' - conflicts: - - httpHealthCheck - - http2HealthCheck - - tcpHealthCheck - - sslHealthCheck + exactly_one_of: + - http_health_check + - https_health_check + - http2_health_check + - tcp_health_check + - ssl_health_check properties: - !ruby/object:Api::Type::String name: 'host' @@ -4256,11 +4262,12 @@ objects: - :USE_SERVING_PORT - !ruby/object:Api::Type::NestedObject name: 'tcpHealthCheck' - conflicts: - - httpHealthCheck - - http2HealthCheck - - httpsHealthCheck - - sslHealthCheck + exactly_one_of: + - http_health_check + - https_health_check + - http2_health_check + - tcp_health_check + - ssl_health_check properties: - !ruby/object:Api::Type::String name: 'request' @@ -4359,11 +4366,12 @@ objects: - :USE_SERVING_PORT - !ruby/object:Api::Type::NestedObject name: 'sslHealthCheck' - conflicts: - - httpHealthCheck - - http2HealthCheck - - httpsHealthCheck - - tcpHealthCheck + exactly_one_of: + - http_health_check + - https_health_check + - http2_health_check + - tcp_health_check + - ssl_health_check properties: - !ruby/object:Api::Type::String name: 'request' @@ -4462,11 +4470,12 @@ objects: - :USE_SERVING_PORT - !ruby/object:Api::Type::NestedObject name: 'http2HealthCheck' - conflicts: - - httpHealthCheck - - sslHealthCheck - - httpsHealthCheck - - tcpHealthCheck + exactly_one_of: + - http_health_check + - https_health_check + - http2_health_check + - tcp_health_check + - ssl_health_check properties: - !ruby/object:Api::Type::String name: 'host' @@ -8027,11 +8036,12 @@ objects: - :HTTP2 - !ruby/object:Api::Type::NestedObject name: 'httpHealthCheck' - conflicts: - - httpsHealthCheck - - http2HealthCheck - - tcpHealthCheck - - sslHealthCheck + exactly_one_of: + - http_health_check + - https_health_check + - http2_health_check + - tcp_health_check + - ssl_health_check properties: - !ruby/object:Api::Type::String name: 'host' @@ -8149,11 +8159,12 @@ objects: - :USE_SERVING_PORT - !ruby/object:Api::Type::NestedObject name: 'httpsHealthCheck' - conflicts: - - httpHealthCheck - - http2HealthCheck - - tcpHealthCheck - - sslHealthCheck + exactly_one_of: + - http_health_check + - https_health_check + - http2_health_check + - tcp_health_check + - ssl_health_check properties: - !ruby/object:Api::Type::String name: 'host' @@ -8271,11 +8282,12 @@ objects: - :USE_SERVING_PORT - !ruby/object:Api::Type::NestedObject name: 'tcpHealthCheck' - conflicts: - - httpHealthCheck - - http2HealthCheck - - httpsHealthCheck - - sslHealthCheck + exactly_one_of: + - http_health_check + - https_health_check + - http2_health_check + - tcp_health_check + - ssl_health_check properties: - !ruby/object:Api::Type::String name: 'request' @@ -8374,11 +8386,12 @@ objects: - :USE_SERVING_PORT - !ruby/object:Api::Type::NestedObject name: 'sslHealthCheck' - conflicts: - - httpHealthCheck - - http2HealthCheck - - httpsHealthCheck - - tcpHealthCheck + exactly_one_of: + - http_health_check + - https_health_check + - http2_health_check + - tcp_health_check + - ssl_health_check properties: - !ruby/object:Api::Type::String name: 'request' @@ -8477,11 +8490,12 @@ objects: - :USE_SERVING_PORT - !ruby/object:Api::Type::NestedObject name: 'http2HealthCheck' - conflicts: - - httpHealthCheck - - sslHealthCheck - - httpsHealthCheck - - tcpHealthCheck + exactly_one_of: + - http_health_check + - https_health_check + - http2_health_check + - tcp_health_check + - ssl_health_check properties: - !ruby/object:Api::Type::String name: 'host' diff --git a/products/dns/api.yaml b/products/dns/api.yaml index 6b2409e531fa..9635fd2e4ea3 100644 --- a/products/dns/api.yaml +++ b/products/dns/api.yaml @@ -329,6 +329,7 @@ objects: # are possible. - !ruby/object:Api::Type::String name: 'networkUrl' + required: true description: | The fully qualified URL of the VPC network to bind to. This should be formatted like diff --git a/products/firestore/api.yaml b/products/firestore/api.yaml index 17580d09dd90..960636bf52cd 100644 --- a/products/firestore/api.yaml +++ b/products/firestore/api.yaml @@ -95,6 +95,7 @@ objects: Name of the field. - !ruby/object:Api::Type::Enum name: 'order' + # TODO (mbang): Exactly one of order or arrayConfig must be set description: | Indicates that this field supports ordering by the specified order or comparing using =, <, <=, >, >=. Only one of `order` and `arrayConfig` can be specified. @@ -103,6 +104,7 @@ objects: - :DESCENDING - !ruby/object:Api::Type::Enum name: 'arrayConfig' + # TODO (mbang): Exactly one of order or arrayConfig must be set description: | Indicates that this field supports operations on arrayValues. Only one of `order` and `arrayConfig` can be specified. diff --git a/products/monitoring/api.yaml b/products/monitoring/api.yaml index bb5e84e87f1d..596a3a9eddb2 100644 --- a/products/monitoring/api.yaml +++ b/products/monitoring/api.yaml @@ -951,11 +951,19 @@ objects: - !ruby/object:Api::Type::NestedObject name: httpCheck description: Contains information needed to make an HTTP or HTTPS check. - conflicts: - - tcpCheck + exactly_one_of: + - http_check + - tcp_check properties: - !ruby/object:Api::Type::NestedObject name: authInfo + at_least_one_of: + - http_check.0.auth_info + - http_check.0.port + - http_check.0.headers + - http_check.0.path + - http_check.0.use_ssl + - http_check.0.mask_headers description: The authentication information. Optional when creating an HTTP check; defaults to empty. properties: @@ -969,11 +977,25 @@ objects: description: The username to authenticate. - !ruby/object:Api::Type::Integer name: port + at_least_one_of: + - http_check.0.auth_info + - http_check.0.port + - http_check.0.headers + - http_check.0.path + - http_check.0.use_ssl + - http_check.0.mask_headers description: The port to the page to run the check against. Will be combined with host (specified within the MonitoredResource) and path to construct the full URL. Optional (defaults to 80 without SSL, or 443 with SSL). - !ruby/object:Api::Type::KeyValuePairs name: headers + at_least_one_of: + - http_check.0.auth_info + - http_check.0.port + - http_check.0.headers + - http_check.0.path + - http_check.0.use_ssl + - http_check.0.mask_headers description: The list of headers to send as part of the uptime check request. If two headers have the same key and different values, they should be entered as a single header, with the value being a comma-separated list of all the @@ -983,12 +1005,26 @@ objects: headers allowed is 100. - !ruby/object:Api::Type::String name: path + at_least_one_of: + - http_check.0.auth_info + - http_check.0.port + - http_check.0.headers + - http_check.0.path + - http_check.0.use_ssl + - http_check.0.mask_headers default_value: "/" description: The path to the page to run the check against. Will be combined with the host (specified within the MonitoredResource) and port to construct the full URL. Optional (defaults to "/"). - !ruby/object:Api::Type::Boolean name: useSsl + at_least_one_of: + - http_check.0.auth_info + - http_check.0.port + - http_check.0.headers + - http_check.0.path + - http_check.0.use_ssl + - http_check.0.mask_headers description: If true, use HTTPS instead of HTTP to run the check. - !ruby/object:Api::Type::Boolean name: validateSsl @@ -997,6 +1033,13 @@ objects: is set to uptime_url. If useSsl is false, setting validateSsl to true has no effect. - !ruby/object:Api::Type::Boolean name: maskHeaders + at_least_one_of: + - http_check.0.auth_info + - http_check.0.port + - http_check.0.headers + - http_check.0.path + - http_check.0.use_ssl + - http_check.0.mask_headers description: Boolean specifying whether to encrypt the header information. Encryption should be specified for any headers related to authentication that you do not wish to be seen when retrieving the configuration. The server will @@ -1005,8 +1048,9 @@ objects: - !ruby/object:Api::Type::NestedObject name: tcpCheck description: Contains information needed to make a TCP check. - conflicts: - - httpCheck + exactly_one_of: + - http_check + - tcp_check properties: - !ruby/object:Api::Type::Integer name: port @@ -1017,8 +1061,9 @@ objects: name: resourceGroup input: true description: The group resource associated with the configuration. - conflicts: - - monitoredResource + exactly_one_of: + - monitored_resource + - resource_group properties: - !ruby/object:Api::Type::Enum name: resourceType @@ -1046,8 +1091,9 @@ objects: description: 'The monitored resource (https://cloud.google.com/monitoring/api/resources) associated with the configuration. The following monitored resource types are supported for uptime checks: uptime_url gce_instance gae_app aws_ec2_instance aws_elb_load_balancer' - conflicts: - - resourceGroup + exactly_one_of: + - monitored_resource + - resource_group properties: - !ruby/object:Api::Type::String name: type diff --git a/third_party/terraform/resources/resource_compute_instance.go b/third_party/terraform/resources/resource_compute_instance.go index 7fd43442bc14..a2354137ed4b 100644 --- a/third_party/terraform/resources/resource_compute_instance.go +++ b/third_party/terraform/resources/resource_compute_instance.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "log" - "sort" "strings" "time" @@ -57,74 +56,6 @@ var ( } ) -func resourceComputeInstanceAtLeastOneNetworkDiff(diff *schema.ResourceDiff, v interface{}) error { - atLeastOneOfList := []string{"network_interface.%d.network", "network_interface.%d.subnetwork"} - errorList := make([]string, 0) - - networkInterfaces := diff.Get("network_interface").([]interface{}) - if len(networkInterfaces) == 0 { - return nil - } - - for i := range networkInterfaces { - found := false - for _, atLeastOneOfKey := range atLeastOneOfList { - if val := diff.Get(fmt.Sprintf(atLeastOneOfKey, i)); val != "" { - found = true - } - } - - if found == false { - sort.Strings(atLeastOneOfList) - keyList := formatStringsInList(atLeastOneOfList, i) - errorList = append(errorList, fmt.Sprintf("network_interface: one of `%s` must be specified", strings.Join(keyList, ","))) - } - } - - if len(errorList) > 0 { - return fmt.Errorf(strings.Join(errorList, "\n\t* ")) - } - - return nil -} - -func resourceComputeInstanceAtLeastOneAccessConfigAttrDiff(diff *schema.ResourceDiff, v interface{}) error { - errorList := make([]string, 0) - - networkInterfaces := diff.Get("network_interface").([]interface{}) - if len(networkInterfaces) == 0 { - return nil - } - - for i := range networkInterfaces { - accessConfigs := diff.Get(fmt.Sprintf("network_interface.%d.access_config", i)).([]interface{}) - if len(accessConfigs) == 0 { - continue - } - - for j := range accessConfigs { - found := false - for _, atLeastOneOfKey := range accessConfigKeys { - if val := diff.Get(fmt.Sprintf(atLeastOneOfKey, i, j)); val != "" { - found = true - } - } - - if found == false { - sort.Strings(accessConfigKeys) - keyList := formatStringsInList(accessConfigKeys, i, j) - errorList = append(errorList, fmt.Sprintf("network_interface.%d.access_config: one of `%s` must be specified", i, strings.Join(keyList, ","))) - } - } - } - - if len(errorList) > 0 { - return fmt.Errorf(strings.Join(errorList, "\n\t* ")) - } - - return nil -} - func resourceComputeInstance() *schema.Resource { return &schema.Resource{ Create: resourceComputeInstanceCreate, @@ -664,8 +595,6 @@ func resourceComputeInstance() *schema.Resource { }, suppressEmptyGuestAcceleratorDiff, ), - resourceComputeInstanceAtLeastOneNetworkDiff, - resourceComputeInstanceAtLeastOneAccessConfigAttrDiff, ), } } diff --git a/third_party/terraform/resources/resource_compute_instance_group_manager.go b/third_party/terraform/resources/resource_compute_instance_group_manager.go index 9ab58915e2db..f5068640bbd3 100644 --- a/third_party/terraform/resources/resource_compute_instance_group_manager.go +++ b/third_party/terraform/resources/resource_compute_instance_group_manager.go @@ -3,11 +3,9 @@ package google import ( "fmt" "log" - "sort" "strings" "time" - "github.com/hashicorp/terraform-plugin-sdk/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/helper/validation" @@ -16,53 +14,6 @@ import ( "google.golang.org/api/compute/v1" ) -func resourceComputeInstanceGroupManagerExactlyOneTargetSizeDiff(diff *schema.ResourceDiff, v interface{}) error { - exactlyOneOfList := []string{"version.%d.target_size.%d.fixed", "version.%d.target_size.%d.percent"} - errorList := make([]string, 0) - versionBlocks := diff.Get("version").([]interface{}) - if len(versionBlocks) == 0 { - return nil - } - - for i := range versionBlocks { - targetBlocks := diff.Get(fmt.Sprintf("version.%d.target_size", i)).([]interface{}) - if len(targetBlocks) == 0 { - continue - } - - for j := range targetBlocks { - specified := make([]string, 0) - for _, exactlyOneOfKey := range exactlyOneOfList { - if val := diff.Get(fmt.Sprintf(exactlyOneOfKey, i, j)); val != 0 { - specified = append(specified, exactlyOneOfKey) - } - } - - if len(specified) == 1 { - continue - } - - sort.Strings(exactlyOneOfList) - keyList := formatStringsInList(exactlyOneOfList, i, j) - specified = formatStringsInList(specified, i, j) - - if len(specified) == 0 { - errorList = append(errorList, fmt.Sprintf("version.%d.target_size: one of `%s` must be specified", i, strings.Join(keyList, ","))) - } - - if len(specified) > 1 { - errorList = append(errorList, fmt.Sprintf("version.%d.target_size: only one of `%s` can be specified, but `%s` were specified", i, strings.Join(keyList, ","), strings.Join(specified, ","))) - } - } - } - - if len(errorList) > 0 { - return fmt.Errorf(strings.Join(errorList, "\n\t* ")) - } - - return nil -} - func resourceComputeInstanceGroupManager() *schema.Resource { return &schema.Resource{ Create: resourceComputeInstanceGroupManagerCreate, @@ -72,9 +23,6 @@ func resourceComputeInstanceGroupManager() *schema.Resource { Importer: &schema.ResourceImporter{ State: resourceInstanceGroupManagerStateImporter, }, - CustomizeDiff: customdiff.All( - resourceComputeInstanceGroupManagerExactlyOneTargetSizeDiff, - ), Timeouts: &schema.ResourceTimeout{ Create: schema.DefaultTimeout(5 * time.Minute), Update: schema.DefaultTimeout(5 * time.Minute), diff --git a/third_party/terraform/resources/resource_compute_instance_template.go b/third_party/terraform/resources/resource_compute_instance_template.go index 5886305730db..5a86f9497045 100644 --- a/third_party/terraform/resources/resource_compute_instance_template.go +++ b/third_party/terraform/resources/resource_compute_instance_template.go @@ -3,7 +3,6 @@ package google import ( "fmt" "reflect" - "sort" "strings" "github.com/hashicorp/errwrap" @@ -42,9 +41,6 @@ func resourceComputeInstanceTemplate() *schema.Resource { CustomizeDiff: customdiff.All( resourceComputeInstanceTemplateSourceImageCustomizeDiff, resourceComputeInstanceTemplateScratchDiskCustomizeDiff, - resourceComputeInstanceTemplateAtLeastOneDiskSourceDiff, - resourceComputeInstanceTemplateAtLeastOneNetworkDiff, - resourceComputeInstanceTemplateAtLeastOneAccessConfigAttrDiff, ), MigrateState: resourceComputeInstanceTemplateMigrateState, @@ -554,106 +550,6 @@ func resourceComputeInstanceTemplateSourceImageCustomizeDiff(diff *schema.Resour return nil } -func resourceComputeInstanceTemplateAtLeastOneDiskSourceDiff(diff *schema.ResourceDiff, v interface{}) error { - atLeastOneOfList := []string{"disk.%d.source_image", "disk.%d.source"} - errorList := make([]string, 0) - - disks := diff.Get("disk").([]interface{}) - if len(disks) == 0 { - return nil - } - - for i := range disks { - found := false - for _, atLeastOneOfKey := range atLeastOneOfList { - if val := diff.Get(fmt.Sprintf(atLeastOneOfKey, i)); val != "" { - found = true - } - } - - if found == false { - sort.Strings(atLeastOneOfList) - keyList := formatStringsInList(atLeastOneOfList, i) - errorList = append(errorList, fmt.Sprintf("disk: one of `%s` must be specified", strings.Join(keyList, ","))) - } - } - - if len(errorList) > 0 { - return fmt.Errorf(strings.Join(errorList, "\n\t* ")) - } - - return nil -} - -func resourceComputeInstanceTemplateAtLeastOneNetworkDiff(diff *schema.ResourceDiff, v interface{}) error { - atLeastOneOfList := []string{"network_interface.%d.network", "network_interface.%d.subnetwork"} - errorList := make([]string, 0) - - networkInterfaces := diff.Get("network_interface").([]interface{}) - if len(networkInterfaces) == 0 { - return nil - } - - for i := range networkInterfaces { - found := false - for _, atLeastOneOfKey := range atLeastOneOfList { - if val := diff.Get(fmt.Sprintf(atLeastOneOfKey, i)); val != "" { - found = true - } - } - - if found == false { - sort.Strings(atLeastOneOfList) - keyList := formatStringsInList(atLeastOneOfList, i) - errorList = append(errorList, fmt.Sprintf("network_interface: one of `%s` must be specified", strings.Join(keyList, ","))) - } - } - - if len(errorList) > 0 { - return fmt.Errorf(strings.Join(errorList, "\n\t* ")) - } - - return nil -} - -func resourceComputeInstanceTemplateAtLeastOneAccessConfigAttrDiff(diff *schema.ResourceDiff, v interface{}) error { - atLeastOneOfList := []string{"network_interface.%d.access_config.%d.nat_ip", "network_interface.%d.access_config.%d.network_tier"} - errorList := make([]string, 0) - - networkInterfaces := diff.Get("network_interface").([]interface{}) - if len(networkInterfaces) == 0 { - return nil - } - - for i := range networkInterfaces { - accessConfigs := diff.Get(fmt.Sprintf("network_interface.%d.access_config", i)).([]interface{}) - if len(accessConfigs) == 0 { - continue - } - - for j := range accessConfigs { - found := false - for _, atLeastOneOfKey := range atLeastOneOfList { - if val := diff.Get(fmt.Sprintf(atLeastOneOfKey, i, j)); val != "" { - found = true - } - } - - if found == false { - sort.Strings(atLeastOneOfList) - keyList := formatStringsInList(atLeastOneOfList, i, j) - errorList = append(errorList, fmt.Sprintf("network_interface.%d.access_config: one of `%s` must be specified", i, strings.Join(keyList, ","))) - } - } - } - - if len(errorList) > 0 { - return fmt.Errorf(strings.Join(errorList, "\n\t* ")) - } - - return nil -} - func resourceComputeInstanceTemplateScratchDiskCustomizeDiff(diff *schema.ResourceDiff, meta interface{}) error { // separate func to allow unit testing return resourceComputeInstanceTemplateScratchDiskCustomizeDiffFunc(diff) diff --git a/third_party/terraform/resources/resource_compute_region_instance_group_manager.go b/third_party/terraform/resources/resource_compute_region_instance_group_manager.go index 64aa0dcd9678..2f4cc6d72323 100644 --- a/third_party/terraform/resources/resource_compute_region_instance_group_manager.go +++ b/third_party/terraform/resources/resource_compute_region_instance_group_manager.go @@ -6,7 +6,6 @@ import ( "strings" "time" - "github.com/hashicorp/terraform-plugin-sdk/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/helper/hashcode" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" @@ -24,9 +23,6 @@ func resourceComputeRegionInstanceGroupManager() *schema.Resource { Importer: &schema.ResourceImporter{ State: resourceRegionInstanceGroupManagerStateImporter, }, - CustomizeDiff: customdiff.All( - resourceComputeInstanceGroupManagerExactlyOneTargetSizeDiff, - ), Timeouts: &schema.ResourceTimeout{ Create: schema.DefaultTimeout(5 * time.Minute), Update: schema.DefaultTimeout(5 * time.Minute), diff --git a/third_party/terraform/resources/resource_storage_bucket.go b/third_party/terraform/resources/resource_storage_bucket.go index 34ffa9ff98a4..c924fef91609 100644 --- a/third_party/terraform/resources/resource_storage_bucket.go +++ b/third_party/terraform/resources/resource_storage_bucket.go @@ -7,7 +7,6 @@ import ( "log" "math" "runtime" - "sort" "strconv" "strings" "time" @@ -23,37 +22,6 @@ import ( "google.golang.org/api/storage/v1" ) -func resourceStorageBucketAtLeastOneCorsAttrDiff(diff *schema.ResourceDiff, v interface{}) error { - atLeastOneOfList := []string{"cors.%d.origin", "cors.%d.method", "cors.%d.response_header", "cors.%d.max_age_seconds"} - errorList := make([]string, 0) - - corsBlocks := diff.Get("cors").([]interface{}) - if len(corsBlocks) == 0 { - return nil - } - - for i := range corsBlocks { - found := false - for _, atLeastOneOfKey := range atLeastOneOfList { - if val := diff.Get(fmt.Sprintf(atLeastOneOfKey, i)); val != "" { - found = true - } - } - - if found == false { - sort.Strings(atLeastOneOfList) - keyList := formatStringsInList(atLeastOneOfList, i) - errorList = append(errorList, fmt.Sprintf("cors: one of `%s` must be specified", strings.Join(keyList, ","))) - } - } - - if len(errorList) > 0 { - return fmt.Errorf(strings.Join(errorList, "\n\t* ")) - } - - return nil -} - func resourceStorageBucket() *schema.Resource { return &schema.Resource{ Create: resourceStorageBucketCreate, @@ -65,7 +33,6 @@ func resourceStorageBucket() *schema.Resource { }, CustomizeDiff: customdiff.All( customdiff.ForceNewIfChange("retention_policy.0.is_locked", isPolicyLocked), - resourceStorageBucketAtLeastOneCorsAttrDiff, ), Schema: map[string]*schema.Schema{ diff --git a/third_party/terraform/utils/utils.go.erb b/third_party/terraform/utils/utils.go.erb index 714ee92920eb..9b540cf3a6e2 100644 --- a/third_party/terraform/utils/utils.go.erb +++ b/third_party/terraform/utils/utils.go.erb @@ -576,17 +576,3 @@ func calcAddRemove(from []string, to []string) (add, remove []string) { } return add, remove } - -// Format all the strings in the list with the list of values -// The strings in listOfStrings must have the same formats. -// The values in values must be the correct type and order -// for the strings' formats. -func formatStringsInList(listOfStrings []string, values ...interface{}) []string { - result := make([]string, 0) - - for _, s := range listOfStrings { - result = append(result, fmt.Sprintf(s, values...)) - } - - return result -} diff --git a/third_party/terraform/website/docs/guides/version_3_upgrade.html.markdown b/third_party/terraform/website/docs/guides/version_3_upgrade.html.markdown index 90aea41e8938..816ccb585b36 100644 --- a/third_party/terraform/website/docs/guides/version_3_upgrade.html.markdown +++ b/third_party/terraform/website/docs/guides/version_3_upgrade.html.markdown @@ -55,25 +55,51 @@ so Terraform knows to manage them. - [Provider](#provider) - [ID Format Changes](#id-format-changes) - [Data Source: `google_container_engine_versions`](#data-source-google_container_engine_versions) +- [Resource: `google_access_context_manager_access_level`](#resource-google_access_context_manager_access_level) +- [Resource: `google_access_context_manager_service_perimeter`](#resource-google_access_context_manager_service_perimeter) - [Resource: `google_app_engine_application`](#resource-google_app_engine_application) +- [Resource: `google_app_engine_domain_mapping`](#resource-google_app_engine_domain_mapping) +- [Resource: `google_app_engine_standard_version`](#resource-google_app_engine_standard_version) +- [Resource: `google_bigquery_dataset`](#resource-google_bigquery_dataset) +- [Resource: `google_bigquery_table`](#resource-google_bigquery_table) +- [Resource: `google_bigtable_app_profile`](#resource-google_bigtable_app_profile) +- [Resource: `google_binary_authorization_policy`](#resource-google_binary_authorization_policy) +- [Resource: `google_cloudbuild_trigger`](#resource-google_cloudbuild_trigger) - [Resource: `google_cloudfunctions_function`](#resource-google_cloudfunctions_function) - [Resource: `google_cloudiot_registry`](#resource-google_cloudiot_registry) +- [Resource: `google_cloudscheduler_job`](#resource-google_cloudscheduler_job) - [Resource: `google_composer_environment`](#resource-google_composer_environment) +- [Resource: `google_compute_backend_bucket`](#resource-google_compute_backend_bucket) +- [Resource: `google_compute_backend_service`](#resource-google_compute_backend_service) +- [Resource: `google_compute_firewall`](#resource-google_compute_firewall) - [Resource: `google_compute_forwarding_rule`](#resource-google_compute_forwarding_rule) -- [Resource: `google_compute_global_forwarding_rule`](#resource-google_global_compute_forwarding_rule) +- [Resource: `google_compute_global_forwarding_rule`](#resource-google_compute_global_forwarding_rule) +- [Resource: `google_compute_health_check`](#resource-google_compute_health_check) +- [Resource: `google_compute_image`](#resource-google_compute_image) - [Resource: `google_compute_instance`](#resource-google_compute_instance) - [Resource: `google_compute_instance_template`](#resource-google_compute_instance_template) - [Resource: `google_compute_network`](#resource-google_compute_network) - [Resource: `google_compute_network_peering`](#resource-google_compute_network_peering) +- [Resource: `google_compute_node_template`](#resource-google_compute_node_template) +- [Resource: `google_compute_region_backend_service`](#resource-google_compute_region_backend_service) +- [Resource: `google_compute_region_health_check`](#resource-google_compute_region_health_check) - [Resource: `google_compute_region_instance_group_manager`](#resource-google_compute_region_instance_group_manager) +- [Resource: `google_compute_resource_policy`](#resource-google_compute_resource_policy) +- [Resource: `google_compute_route`](#resource-google_compute_route) +- [Resource: `google_compute_router`](#resource-google_compute_router) - [Resource: `google_compute_router_peer`](#resource-google_compute_router_peer) - [Resource: `google_compute_snapshot`](#resource-google_compute_snapshot) - [Resource: `google_compute_subnetwork`](#resource-google_compute_subnetwork) - [Resource: `google_container_cluster`](#resource-google_container_cluster) - [Resource: `google_container_node_pool`](#resource-google_container_node_pool) +- [Resource: `google_dataproc_autoscaling_policy`](#resource-google_dataproc_autoscaling_policy) - [Resource: `google_dataproc_cluster`](#resource-google_dataproc_cluster) - [Resource: `google_dataproc_job`](#resource-google_dataproc_job) - [Resource: `google_dns_managed_zone`](#resource-google_dns_managed_zone) +- [Resource: `google_dns_policy`](#resource-google_dns_policy) +- [Resource: `google_healthcare_hl7_v2_store`](#resource-google_healthcare_hl7_v2_store) +- [Resource: `google_logging_metric`](#resource-google_logging_metric) +- [Resource: `google_mlengine_model`](#resource-google_mlengine_model) - [Resource: `google_monitoring_alert_policy`](#resource-google_monitoring_alert_policy) - [Resource: `google_monitoring_uptime_check_config`](#resource-google_monitoring_uptime_check_config) - [Resource: `google_organization_policy`](#resource-google_organization_policy) @@ -81,10 +107,12 @@ so Terraform knows to manage them. - [Resource: `google_project_service`](#resource-google_project_service) - [Resource: `google_project_services`](#resource-google_project_services) - [Resource: `google_pubsub_subscription`](#resource-google_pubsub_subscription) +- [Resource: `google_security_scanner_scan_config`](#resource-google_security_scanner_scan_config) - [Resource: `google_service_account_key`](#resource-google_service_account_key) - [Resource: `google_sql_database_instance`](#resource-google_sql_database_instance) - [Resource: `google_storage_bucket`](#resource-google_storage_bucket) - [Resource: `google_storage_transfer_job`](#resource-google_storage_transfer_job) +- [Resource: `google_tpu_node`](#resource-google_tpu_node) @@ -175,12 +203,136 @@ a resource. Users who depended on particular ID formats in previous versions may Use `location` instead. +## Resource: `google_access_context_manager_access_level` + +### `os_type` is now required on block `google_access_context_manager_access_level.basic.conditions.device_policy.os_constraints` + +In an attempt to avoid allowing empty blocks in config files, `os_type` is now +required on the `basic.conditions.device_policy.os_constraints` block. + +## Resource: `google_access_context_manager_service_perimeter` + +### At least one of `resources`, `access_levels`, or `restricted_services` is now required on +`google_accesscontextmanager_service_perimeter.status` + +In an attempt to avoid allowing empty blocks in config files, at least one of `resources`, `access_levels`, +or `restricted_services` is now required on the `status` block. + ## Resource: `google_app_engine_application` ### `split_health_checks` is now required on block `google_app_engine_application.feature_settings` In an attempt to avoid allowing empty blocks in config files, `split_health_checks` is now -required on the `google_app_engine_application.feature_settings` block. +required on the `feature_settings` block. + +## Resource: `google_app_engine_domain_mapping` + +### `ssl_management_type` is now required on `google_app_engine_domain_mapping.ssl_settings` + +In an attempt to avoid allowing empty blocks in config files, `ssl_management_type` is now +required on the `ssl_settings` block. + +## Resource: `google_app_engine_standard_app_version` + +### At least one of `zip`, or `files` is now required on `google_app_engine_standard_app_version.deployment` + +In an attempt to avoid allowing empty blocks in config files, at least one of `zip`, or `files` +is now required on the `deployment` block. + +### `shell` is now required on `google_app_engine_standard_app_version.entrypoint` + +In an attempt to avoid allowing empty blocks in config files, `shell` is now +required on the `entrypoint` block. + +### `script_path` is now required on `google_app_engine_standard_app_version.handlers.script` + +In an attempt to avoid allowing empty blocks in config files, `script_path` is now +required on the `handlers.script` block. + +### `source_url` is now required on `google_app_engine_standard_app_version.deployment.files` +and `google_app_engine_standard_app_version.deployment.zip` + +In an attempt to avoid allowing empty blocks in config files, `shell` is now +required on the `deployment.files` and `deployment.zip` blocks. + +## Resource: `google_bigquery_dataset` + +### `role` is now required on `google_bigquery_dataset.access` + +In an attempt to avoid allowing empty blocks in config files, `role` is now +required on the `access` block. + +## Resource: `google_bigquery_table` + +### At least one of `range` or `skip_leading_rows` is now required on +`external_data_configuration.google_sheets_options` + +In an attempt to avoid allowing empty blocks in config files, at least one +of `range` or `skip_leading_rows` is now required on the +`external_data_configuration.google_sheets_options` block. + +## Resource: `google_bigtable_app_profile` + +### Exactly one of `single_cluster_routing` or `multi_cluster_routing_use_any` is now required on +`google_bigtable_app_profile` + +In attempt to be more consistent with the API, exactly one of `single_cluster_routing` or +`multi_cluster_routing_use_any` is now required on `google_bigtable_app_profile`. + +### `cluster_id` is now required on `google_bigtable_app_profile.single_cluster_routing` + +In an attempt to avoid allowing empty blocks in config files, `cluster_id` is now +required on the `single_cluster_routing` block. + +## Resource: `google_binary_authorization_policy` + +### `name_pattern` is now required on `google_binary_authorization_policy.admission_whitelist_patterns` + +In an attempt to avoid allowing empty blocks in config files, `name_pattern` is now +required on the `admission_whitelist_patterns` block. + +### `evaluation_mode` and `enforcement_mode` are now required on `google_binary_authorization_policy.cluster_admission_rules` + +In an attempt to avoid allowing empty blocks in config files, `evaluation_mode` and `enforcement_mode` are now +required on the `cluster_admission_rules` block. + +## Resource: `google_cloudbuild_trigger` + +### Exactly one of `filename` or `build` on `google_cloudbuild_trigger` + +In attempt to be more consistent with the API, exactly one of `filename` or `build` is now +required on `google_cloudbuild_trigger`. + +### Exactly one of `branch_name`, `tag_name` or `commit_sha` is now required on `google_cloudbuild_trigger.trigger_template` + +In an attempt to avoid allowing empty blocks in config files, exactly one +of `branch_name`, `tag_name` or `commit_sha` is now required on the +`trigger_template` block. + +### Exactly one of `pull_request` or `push` on `google_cloudbuild_trigger.github` + +In an attempt to avoid allowing empty blocks in config files, exactly one +of `pull_request` or `push` is now required on the `github` block. + +### Exactly one of `branch` or `tag_name` on `google_cloudbuild_trigger.github.push` + +In an attempt to avoid allowing empty blocks in config files, exactly one +of `branch` or `tag_name` is now required on the `github.push` block. + +### `steps` is now required on `google_cloudbuild_trigger.build`. + +In an attempt to avoid allowing empty blocks in config files, `steps` is now +required on the `build` block. + +### `name` is now required on `google_cloudbuild_trigger.build.steps` + +In an attempt to avoid allowing empty blocks in config files, `name` is now +required on the `build.steps` block. + +### `name` and `path` are now required on `google_cloudbuild_trigger.build.steps.volumes` + +In an attempt to avoid allowing empty blocks in config files, `name` and `path` are now +required on the `build.volumes` block. ## Resource: `google_cloudfunctions_function` @@ -224,28 +376,122 @@ resource "google_cloudiot_registry" "myregistry" { } } ``` +### `public_key_certificate` is now required on block `google_cloudiot_registry.credentials` + +In an attempt to avoid allowing empty blocks in config files, `public_key_certificate` is now +required on the `credentials` block. -### `event_notification_config` is now removed +## Resource: `google_cloudscheduler_job` -`event_notification_config` has been removed in favor of -`event_notification_configs` (plural). Please switch to using the plural field. +### Exactly one of `pubsub_target`, `http_target` or `app_engine_http_target` is required +on `google_cloudscheduler_job` -### `public_key_certificate` is now required on block `google_cloudiot_registry.credentials` +In attempt to be more consistent with the API, exactly one of `pubsub_target`, `http_target` +or `app_engine_http_target` is now required on `google_cloudscheduler_job`. -In an attempt to avoid allowing empty blocks in config files, `public_key_certificate` is now -required on the `google_cloudiot_registry.credentials` block. +### `service_account_email` is now required on `google_cloudscheduler_job.http_target.oauth_token` +and `google_cloudscheduler_job.http_target.oidc_token`. + +In an attempt to avoid allowing empty blocks in config files, `service_account_email` is now +required on the `http_target.oauth_token` and `http_target.oidc_token` blocks. + +### At least one of `retry_count`, `max_retry_duration`, `min_backoff_duration`, `max_backoff_duration`, +or `max_doublings` is now required on `google_cloud_scheduler_job.retry_config` + +In an attempt to avoid allowing empty blocks in config files, at least one of `retry_count`, +`max_retry_duration`, `min_backoff_duration`, `max_backoff_duration`, or `max_doublings` is +now required on the `retry_config` block. + +### At least one of `service`, `version`, or `instance` is now required on +`google_cloud_scheduler_job.app_engine_http_target.app_engine_routing` + +In an attempt to avoid allowing empty blocks in config files, at least one of `service`, +`version`, or `instance` is now required on the `app_engine_http_target.app_engine_routing` block. ## Resource: `google_composer_environment` +### At least one of `airflow_config_overrides`, `pypi_packages`, `env_variables`, `image_version`, +or `python_version` are now required on `google_composer_environment.config.software_config` + +In an attempt to avoid allowing empty blocks in config files, at least one of `airflow_config_overrides`, +`pypi_packages`, `env_variables`, `image_version`, or `python_version` is now required on the +`config.software_config` block. + ### `use_ip_aliases` is now required on block `google_composer_environment.ip_allocation_policy` Previously the default value of `use_ip_aliases` was `true`. In an attempt to avoid allowing empty blocks -in config files, `use_ip_aliases` is now required on the `google_composer_environment.ip_allocation_policy` block. +in config files, `use_ip_aliases` is now required on the `ip_allocation_policy` block. ### `enable_private_endpoint` is now required on block `google_composer_environment.private_environment_config` Previously the default value of `enable_private_endpoint` was `true`. In an attempt to avoid allowing empty blocks -in config files, `enable_private_endpoint` is now required on the `google_composer_environment.private_environment_config` block. +in config files, `enable_private_endpoint` is now required on the `private_environment_config` block. + +## Resource: `google_compute_backend_bucket` + +### `signed_url_cache_max_age_sec` is now required on `google_compute_backend_bucket.autoscaling_policy.cdn_policy` + +Previously the default value of `signed_url_cache_max_age_sec` was `3600`. In an attempt to avoid allowing empty +blocks in config files, `signed_url_cache_max_age_sec` is now required on the +`autoscaling_policy.cdn_policy` block. + +## Resource: `google_compute_backend_service` + +### At least one of `connect_timeout`, `max_requests_per_connection`, `max_connections`, +`max_pending_requests`, `max_requests`, or `max_retries` is now required on +`google_compute_backend_service.circuit_breakers` + +In an attempt to avoid allowing empty blocks in config files, at least one of `connect_timeout`, +`max_requests_per_connection`, `max_connections`, `max_pending_requests`, `max_requests`, +or `max_retries` is now required on the `circuit_breakers` block. + +### At least one of `ttl`, `name`, or `path` is now required on +`google_compute_backend_service.consistent_hash.http_cookie` + +In an attempt to avoid allowing empty blocks in config files, at least one of `ttl`, `name`, or `path` +is now required on the `consistent_hash.http_cookie` block. + +### At least one of `http_cookie`, `http_header_name`, or `minimum_ring_size` is now required on +`google_compute_backend_service.consistent_hash` + +In an attempt to avoid allowing empty blocks in config files, at least one of `http_cookie`, +`http_header_name`, or `minimum_ring_size` is now required on the `consistent_hash` block. + +### At least one of `cache_key_policy` or `signed_url_cache_max_age_sec` is now required on +`google_compute_backend_service.cdn_policy` + +In an attempt to avoid allowing empty blocks in config files, at least one of `cache_key_policy` or +`signed_url_cache_max_age_sec` is now required on the `cdn_policy` block. + +### At least one of `include_host`, `include_protocol`, `include_query_string`, `query_string_blacklist`, +or `query_string_whitelist` is now required on `google_compute_backend_service.cdn_policy.cache_key_policy` + +In an attempt to avoid allowing empty blocks in config files, at least one of `include_host`, +`include_protocol`, `include_query_string`, `query_string_blacklist`, or `query_string_whitelist` +is now required on the `cdn_policy.cache_key_policy` block. + +### At least one of `base_ejection_time`, `consecutive_errors`, `consecutive_gateway_failure`, +`enforcing_consecutive_errors`, `enforcing_consecutive_gateway_failure`, `enforcing_success_rate`, +`interval`, `max_ejection_percent`, `success_rate_minimum_hosts`, `success_rate_request_volume`, +or `success_rate_stdev_factor` is now required on `google_compute_backend_service.outlier_detection` + +In an attempt to avoid allowing empty blocks in config files, at least one of `base_ejection_time`, +`consecutive_errors`, `consecutive_gateway_failure`, `enforcing_consecutive_errors`, +`enforcing_consecutive_gateway_failure`, `enforcing_success_rate`, `interval`, `max_ejection_percent`, +`success_rate_minimum_hosts`, `success_rate_request_volume`, or `success_rate_stdev_factor` +is now required on the `outlier_detection` block. + +### At least one of `enable` or `sample_rate` is now required on `google_compute_backend_service.log_config` + +In an attempt to avoid allowing empty blocks in config files, at least one of `enable` or `sample_rate` +is now required on the `log_config` block. + +## Resource: `google_compute_firewall` + +### Exactly one of `allow` or `deny` is required on `google_compute_firewall` + +In attempt to be more consistent with the API, exactly one of `allowed` or `denied` +is now required on `google_compute_firewall`. ## Resource: `google_compute_forwarding_rule` @@ -301,16 +547,82 @@ resource "google_compute_forwarding_rule" "frule" { See [`google_compute_forwarding_rule`][#resource-google_compute_forwarding_rule]. +## Resource: `google_compute_health_check` + +### Exactly one of `http_health_check`, `https_health_check`, `http2_health_check`, +`tcp_health_check` or `ssl_health_check` is required on `google_compute_health_check` + +In attempt to be more consistent with the API, exactly one of `http_health_check`, `https_health_check`, +`http2_health_check`, `tcp_health_check` or `ssl_health_check` is now required on +`google_compute_health_check`. + +### At least one of `host`, `request_path`, `response`, `port`, `port_name`, `proxy_header`, or `port_specification` +is now required on `google_compute_health_check.http_health_check`, `google_compute_health_check.https_health_check` +and `google_compute_health_check.http2_health_check` + +In an attempt to avoid allowing empty blocks in config files, at least one of `host`, `request_path`, `response`, +`port`, `port_name`, `proxy_header`, or `port_specification` is now required on the +`http_health_check`, `https_health_check` and `http2_health_check` blocks. + +### At least one of `request`, `response`, `port`, `port_name`, `proxy_header`, or `port_specification` +is now required on `google_compute_health_check.ssl_health_check` and `google_compute_health_check.tcp_health_check` + +In an attempt to avoid allowing empty blocks in config files, at least one of `request`, `response`, `port`, `port_name`, +`proxy_header`, or `port_specification` is now required on the `ssl_health_check` and `tcp_health_check` blocks. + +## Resource: `google_compute_image` + +### `type` is now required on `google_compute_image.guest_os_features` + +In an attempt to avoid allowing empty blocks in config files, `type` is now required on the +`guest_os_features` block. ## Resource: `google_compute_instance` ### `interface` is now required on block `google_compute_instance.scratch_disk` Previously the default value of `interface` was `SCSI`. In an attempt to avoid allowing empty blocks -in config files, `interface` is now required on the `google_compute_instance.scratch_disk` block. +in config files, `interface` is now required on the `scratch_disk` block. + +### At least one of `auto_delete`, `device_name`, `disk_encryption_key_raw`, `kms_key_self_link`, +`initialize_params`, `mode` or `source` is now required on `google_compute_instance.boot_disk` + +In an attempt to avoid allowing empty blocks in config files, at least one of `auto_delete`, `device_name`, +`disk_encryption_key_raw`, `kms_key_self_link`, `initialize_params`, `mode` or `source` is now required on the +`boot_disk` block. + +### At least one of `size`, `type`, `image`, or `labels` are now required on +`google_compute_instance.boot_disk.initialize_params` + +In an attempt to avoid allowing empty blocks in config files, at least one of `size`, `type`, `image`, or `labels` +is now required on the `initialize_params` block. + +### At least one of `enable_secure_boot`, `enable_vtpm`, or `enable_integrity_monitoring` is now required +on `google_compute_instance.shielded_instance_config` + +In an attempt to avoid allowing empty blocks in config files, at least one of `enable_secure_boot`, `enable_vtpm`, +or `enable_integrity_monitoring` is now required on the `shielded_instance_config` block. + +### At least one of `on_host_maintenance`, `automatic_restart`, `preemptible`, or `node_affinities` +is now required on `google_compute_instance.scheduling` + +In an attempt to avoid allowing empty blocks in config files, at least one of `on_host_maintenance`, `automatic_restart`, +`preemptible`, or `node_affinities` is now required on the `scheduling` block. ## Resource: `google_compute_instance_template` +### At least one of `enable_secure_boot`, `enable_vtpm`, or `enable_integrity_monitoring` is now +required on `google_compute_instance_template.shielded_instance_config` + +In an attempt to avoid allowing empty blocks in config files, at least one of `enable_secure_boot`, `enable_vtpm`, or +`enable_integrity_monitoring` is now required on the `shielded_instance_config` block. + +### At least one of `on_host_maintenance`, `automatic_restart`, `preemptible`, or `node_affinities` is +now required on `google_compute_instance_template.scheduling` + +In an attempt to avoid allowing empty blocks in config files, at least one of `on_host_maintenance`, `automatic_restart`, +`preemptible`, or `node_affinities` is now required on the `scheduling` block. + ### Disks with invalid scratch disk configurations are now rejected The instance template API allows specifying invalid configurations in some cases, @@ -361,7 +673,7 @@ disk { ### `kms_key_self_link` is now required on block `google_compute_instance_template.disk_encryption_key` In an attempt to avoid allowing empty blocks in config files, `kms_key_self_link` is now -required on the `google_compute_instance_template.disk_encryption_key` block. +required on the `disk_encryption_key` block. ## Resource: `google_compute_network` @@ -377,6 +689,80 @@ using this field from Feb 1, 2020 onwards. `auto_create_routes` has been removed because it's redundant and not user-configurable. +## Resource: `google_compute_node_template` + +### At least one of `cpus` or `memory` is now required on `google_compute_node_template.node_type_flexibility` + +In an attempt to avoid allowing empty blocks in config files, at least one of `cpus` or `memory` +is now required on the `node_type_flexibility` block. + +## Resource: `google_compute_region_backend_service` + +### At least one of `connect_timeout`, `max_requests_per_connection`, `max_connections`, +`max_pending_requests`, `max_requests`, or `max_retries` is now required on +`google_compute_region_backend_service.circuit_breakers` + +In an attempt to avoid allowing empty blocks in config files, at least one of `connect_timeout`, +`max_requests_per_connection`, `max_connections`, `max_pending_requests`, `max_requests`, +or `max_retries` is now required on the `circuit_breakers` block. + +### At least one of `ttl`, `name`, or `path` is now required on +`google_compute_region_backend_service.consistent_hash.http_cookie` + +In an attempt to avoid allowing empty blocks in config files, at least one of `ttl`, `name`, or `path` +is now required on the `consistent_hash.http_cookie` block. + +### At least one of `http_cookie`, `http_header_name`, or `minimum_ring_size` is now required on +`google_compute_region_backend_service.consistent_hash` + +In an attempt to avoid allowing empty blocks in config files, at least one of `http_cookie`, +`http_header_name`, or `minimum_ring_size` is now required on the `consistent_hash` block. + +### At least one of `disable_connection_drain_on_failover`, `drop_traffic_if_unhealthy`, or +`failover_ratio` is now required on `google_compute_region_backend_service.failover_policy` + +In an attempt to avoid allowing empty blocks in config files, at least one of `disable_connection_drain_on_failover`, +`drop_traffic_if_unhealthy`, or `failover_ratio` is now required on the `failover_policy` block. + +### At least one of `base_ejection_time`, `consecutive_errors`, `consecutive_gateway_failure`, +`enforcing_consecutive_errors`, `enforcing_consecutive_gateway_failure`, `enforcing_success_rate`, +`interval`, `max_ejection_percent`, `success_rate_minimum_hosts`, `success_rate_request_volume`, +or `success_rate_stdev_factor` is now required on `google_compute_region_backend_service.outlier_detection` + +In an attempt to avoid allowing empty blocks in config files, at least one of `base_ejection_time`, +`consecutive_errors`, `consecutive_gateway_failure`, `enforcing_consecutive_errors`, +`enforcing_consecutive_gateway_failure`, `enforcing_success_rate`, `interval`, `max_ejection_percent`, +`success_rate_minimum_hosts`, `success_rate_request_volume`, or `success_rate_stdev_factor` +is now required on the `outlier_detection` block. + +### At least one of `enable` or `sample_rate` is now required on `google_compute_region_backend_service.log_config` + +In an attempt to avoid allowing empty blocks in config files, at least one of `enable` or `sample_rate` +is now required on the `log_config` block. + +## Resource: `google_compute_region_health_check` + +### Exactly one of `http_health_check`, `https_health_check`, `http2_health_check`, +`tcp_health_check` or `ssl_health_check` is required on `google_compute_health_check` + +In attempt to be more consistent with the API, exactly one of `http_health_check`, `https_health_check`, +`http2_health_check`, `tcp_health_check` or `ssl_health_check` is now required on the +`google_compute_region_health_check`. + +### At least one of `host`, `request_path`, `response`, `port`, `port_name`, `proxy_header`, or `port_specification` +is now required on `google_compute_region_health_check.http_health_check`, `google_compute_region_health_check.https_health_check` +and `google_compute_region_health_check.http2_health_check` + +In an attempt to avoid allowing empty blocks in config files, at least one of `host`, `request_path`, `response`, +`port`, `port_name`, `proxy_header`, or `port_specification` is now required on the +`http_health_check`, `https_health_check` and `http2_health_check` blocks. + +### At least one of `request`, `response`, `port`, `port_name`, `proxy_header`, or `port_specification` +is now required on `google_compute_region_health_check.ssl_health_check` and `google_compute_region_health_check.tcp_health_check` + +In an attempt to avoid allowing empty blocks in config files, at least one of `request`, `response`, `port`, `port_name`, +`proxy_header`, or `port_specification` is now required on the `ssl_health_check` and `tcp_health_check` blocks. + ## Resource: `google_compute_region_instance_group_manager` ### `update_strategy` no longer has any effect and is removed @@ -384,19 +770,51 @@ user-configurable. With `rolling_update_policy` removed, `update_strategy` has no effect anymore. Before updating, remove it from your config. +## Resource: `google_compute_resource_policy` + +### Exactly one of `hourly_schedule`, `daily_schedule` or `weekly_schedule` on +`google_compute_resource_policy.snapshot_schedule_policy.schedule` + +In an attempt to avoid allowing empty blocks in config files, exactly one +of `hourly_schedule`, `daily_schedule` or `weekly_schedule` is now required +on the `snapshot_schedule_policy.schedule` block. + +### At least one of `labels`, `storage_locations`, or `guest_flush` is now required on +`google_compute_resource_policy.snapshot_schedule_policy.snapshot_properties` + +In an attempt to avoid allowing empty blocks in config files, at least one of +`labels`, `storage_locations`, or `guest_flush` is now required on the +`snapshot_schedule_policy.snapshot_properties` block. + +## Resource: `google_compute_route` + +### Exactly one of `next_hop_gateway`, `next_hop_instance`, `next_hop_ip`, +`next_hop_vpn_tunnel` or `next_hop_ilb` is required on `google_compute_route` + +In attempt to be more consistent with the API, exactly one of `next_hop_gateway`, `next_hop_instance`, +`next_hop_ip`, `next_hop_vpn_tunnel` or `next_hop_ilb` is now required on the +`google_compute_route`. + +## Resource: `google_compute_router` + +### `range` is now required on `google_compute_router.bgp.advertised_ip_ranges` + +In an attempt to avoid allowing empty blocks in config files, `range` is now +required on the `bgp.advertised_ip_ranges` block. + ## Resource: `google_compute_router_peer` ### `range` is now required on block `google_compute_router_peer.advertised_ip_ranges` In an attempt to avoid allowing empty blocks in config files, `range` is now -required on the `google_compute_router_peer.advertised_ip_ranges` block. +required on the `advertised_ip_ranges` block. ## Resource: `google_compute_snapshot` ### `raw_key` is now required on block `google_compute_snapshot.source_disk_encryption_key` In an attempt to avoid allowing empty blocks in config files, `raw_key` is now -required on the `google_compute_snapshot.source_disk_encryption_key` block. +required on the `source_disk_encryption_key` block. ## Resource: `google_compute_subnetwork` @@ -406,6 +824,13 @@ required on the `google_compute_snapshot.source_disk_encryption_key` block. for flow logging. Enablement of flow logs is now controlled by whether `log_config` is defined or not instead of by the `enable_flow_logs` variable. Users with `enable_flow_logs = false` only need to remove the field. +### At least one of `aggregation_interval`, `flow_sampling`, or `metadata` is now required on +`google_compute_subnetwork.log_config` + +In an attempt to avoid allowing empty blocks in config files, at least one of +`aggregation_interval`, `flow_sampling`, or `metadata` is now required on the +`log_config` block. + ### Old Config @@ -589,12 +1014,6 @@ resource "google_container_cluster" "primary" { } ``` -### `logging_service` and `monitoring_service` defaults changed - -GKE Stackdriver Monitoring (the GKE-specific Stackdriver experience) is now -enabled at cluster creation by default, similar to the default in GKE `1.14` -through other tools. - ### `taint` field is now authoritative when set The `taint` field inside of `node_config` blocks on `google_container_cluster` @@ -618,30 +1037,49 @@ The `kubernetes_dashboard` addon is deprecated for clusters on GKE and will soon be removed. It is recommended to use alternative GCP Console dashboards. +### `channel` is now required on `google_container_cluster.release_channel` + +In an attempt to avoid allowing empty blocks in config files, `channel` is now +required on the `release_channel` block. + ### `cidr_blocks` is now required on block `google_container_cluster.master_authorized_networks_config` In an attempt to avoid allowing empty blocks in config files, `cidr_blocks` is now -required on the `google_container_cluster.master_authorized_networks_config` block. +required on the `master_authorized_networks_config` block. ### The `disabled` field is now required on the `addons_config` blocks for `http_load_balancing`, `horizontal_pod_autoscaling`, `istio_config`, `cloudrun_config` and `network_policy_config`. In an attempt to avoid allowing empty blocks in config files, `disabled` is now required on the different `google_container_cluster.addons_config` blocks. +### At least one of `http_load_balancing`, `horizontal_pod_autoscaling` , `network_policy_config`, +`cloudrun_config`, or `istio_config` is now required on `google_container_cluster.addons_config` + +In an attempt to avoid allowing empty blocks in config files, at least one of `http_load_balancing`, +`horizontal_pod_autoscaling` , `network_policy_config`, `cloudrun_config`, or `istio_config` is now required on the +`addons_config` block. + + +### At least one of `username`, `password` or `client_certificate_config` is now required on +`google_container_cluster.master_auth` + +In an attempt to avoid allowing empty blocks in config files, at least one of `username`, `password` +or `client_certificate_config` is now required on the `master_auth` block. + ### `enabled` is now required on block `google_container_cluster.vertical_pod_autoscaling` In an attempt to avoid allowing empty blocks in config files, `enabled` is now -required on the `google_container_cluster.vertical_pod_autoscaling` block. +required on the `vertical_pod_autoscaling` block. ### `enabled` is now required on block `google_container_cluster.network_policy` Previously the default value of `enabled` was `false`. In an attempt to avoid allowing empty blocks -in config files, `enabled` is now required on the `google_container_cluster.network_policy` block. +in config files, `enabled` is now required on the `network_policy` block. ### `enable_private_endpoint` is now required on block `google_container_cluster.private_cluster_config` In an attempt to avoid allowing empty blocks in config files, `enable_private_endpoint` is now -required on the `google_container_cluster.private_cluster_config` block. +required on the `private_cluster_config` block. ### `logging_service` and `monitoring_service` defaults changed @@ -676,7 +1114,7 @@ monitoring_service = "monitoring.googleapis.com/kubernetes" ### `use_ip_aliases` is now required on block `google_container_cluster.ip_allocation_policy` Previously the default value of `use_ip_aliases` was `true`. In an attempt to avoid allowing empty blocks -in config files, `use_ip_aliases` is now required on the `google_container_cluster.ip_allocation_policy` block. +in config files, `use_ip_aliases` is now required on the `ip_allocation_policy` block. ### `zone`, `region` and `additional_zones` are now removed @@ -689,39 +1127,198 @@ in config files, `use_ip_aliases` is now required on the `google_container_clust `zone` and `region` have been removed in favor of `location` +## Resource: `google_dataproc_autoscaling_policy` + +### At least one of `min_instances`, `max_instances`, or `weight` is now required on +`google_dataproc_autoscaling_policy.secondary_worker_config` + +In an attempt to avoid allowing empty blocks in config files, at least one of `min_instances`, +`max_instances`, or `weight` is now required on the `secondary_worker_config` +block. + ## Resource: `google_dataproc_cluster` +### At least one of `staging_bucket`, `gce_cluster_config`, `master_config`, `worker_config`, +`preemptible_worker_config`, `software_config`, `initialization_action` or `encryption_config` +is now required on `google_dataproc_cluster.cluster_config` + +In an attempt to avoid allowing empty blocks in config files, at least one of `staging_bucket`, +`gce_cluster_config`, `master_config`, `worker_config`, `preemptible_worker_config`, `software_config`, +`initialization_action` or `encryption_config` is now required on the +`cluster_config` block. + +### At least one of `image_version`, `override_properties` or `optional_components` is +now required on `google_dataproc_cluster.cluster_config.software_config` + +In an attempt to avoid allowing empty blocks in config files, at least one of `image_version`, +`override_properties` or `optional_components` is now required on the +`cluster_config.software_config` block. + +### At least one of `num_instances` or `disk_config` is now required on +`google_dataproc_cluster.cluster_config.preemptible_worker_config` + +In an attempt to avoid allowing empty blocks in config files, at least one of `num_instances` +or `disk_config` is now required on the `cluster_config.preemptible_worker_config` block. + +### At least one of `zone`, `network`, `subnetwork`, `tags`, `service_account`, `service_account_scopes`, +`internal_ip_only` or `metadata` is now required on `google_dataproc_cluster.cluster_config.gce_cluster_config` + +In an attempt to avoid allowing empty blocks in config files, at least one of `zone`, `network`, `subnetwork`, +`tags`, `service_account`, `service_account_scopes`, `internal_ip_only` or `metadata` is now required on the +`gce_cluster_config` block. + +### At least one of `num_instances`, `image_uri`, `machine_type`, `min_cpu_platform`, `disk_config`, or `accelerators` +is now required on `google_dataproc_cluster.cluster_config.master_config` and +`google_dataproc_cluster.cluster_config.worker_config` + +In an attempt to avoid allowing empty blocks in config files, at least one of `num_instances`, `image_uri`, +`machine_type`, `min_cpu_platform`, `disk_config`, or `accelerators` is now required on the +`cluster_config.master_config` and `cluster_config.worker_config` blocks. + +### At least one of `num_local_ssds`, `boot_disk_size_gb` or `boot_disk_type` is now required on +`google_dataproc_cluster.cluster_config.preemptible_worker_config.disk_config`, +`google_dataproc_cluster.cluster_config.master_config.disk_config` and +`google_dataproc_cluster.cluster_config.worker_config.disk_config` + +In an attempt to avoid allowing empty blocks in config files, at least one of `num_local_ssds`, `boot_disk_size_gb` +or `boot_disk_type` is now required on the `cluster_config.preemptible_worker_config.disk_config`, +`cluster_config.master_config.disk_config` and `cluster_config.worker_config.disk_config` blocks. + + ### `policy_uri` is now required on `google_dataproc_cluster.autoscaling_config` block. In an attempt to avoid allowing empty blocks in config files, `policy_uri` is now -required on the `google_dataproc_cluster.autoscaling_config` block. +required on the `autoscaling_config` block. ## Resource: `google_dataproc_job` +### At least one of `query_file_uri` or `query_list` is now required on +`hive_config`, `pig_config`, and `sparksql_config` + +In an attempt to avoid allowing empty blocks in config files, at least one of +`query_file_uri` or `query_list` is now required on the `hive_config`, `pig_config`, and +`sparksql_config` blocks. + +### At least one of `main_class` or `main_jar_file_uri` is now required on +`google_dataproc_job.spark_config` and `google_dataproc_job.hadoop_config` + +In an attempt to avoid allowing empty blocks in config files, at least one of +`main_class` or `main_jar_file_uri` is now required on the `spark_config` +and `hadoop_config` blocks. + ### `driver_log_levels` is now required on `logging_config` blocks for -`google_dataproc_job.pyspark_config`, `google_dataproc_job.hadoop_config`, -`google_dataproc_job.spark_config`, `google_dataproc_job.pig_config`, and -`google_dataproc_job.sparksql_config`. +`pyspark_config`, `hadoop_config`, `spark_config`, `pig_config`, and +`sparksql_config`. In an attempt to avoid allowing empty blocks in config files, `driver_log_levels` is now -required on the different `google_dataproc_job` config blocks. +required on `pyspark_config`, `hadoop_config`, `spark_config`, `pig_config`, and +`sparksql_config` blocks. ### `max_failures_per_hour` is now required on block `google_dataproc_job.scheduling` In an attempt to avoid allowing empty blocks in config files, `max_failures_per_hour` is now -required on the `google_dataproc_job.scheduling` block. +required on the `scheduling` block. ## Resource: `google_dns_managed_zone` +### At least one of `kind`, `non_existence`, `state`, or `default_key_specs` +is now required on `google_dns_managed_zone.dnssec_config` + +In an attempt to avoid allowing empty blocks in config files, at least one of +`kind`, `non_existence`, `state`, or `default_key_specs` is now required on the +`dnssec_config` block. + +### `target_network` is now required on block `google_dns_managed_zone.peering_config` + +In an attempt to avoid allowing empty blocks in config files, `target_network` is now +required on the `peering_config` block. + +### `network_url` is now required on block `google_dns_managed_zone.peering_config.target_network` + +In an attempt to avoid allowing empty blocks in config files, `network_url` is now +required on the `peering_config.target_network` block. + +### `target_name_servers` is now required on block `google_dns_managed_zone.forwarding_config` + +In an attempt to avoid allowing empty blocks in config files, `target_name_servers` is now +required on the `forwarding_config` block. + +### `ipv4_address` is now required on block `google_dns_managed_zone.forwarding_config.target_name_servers` + +In an attempt to avoid allowing empty blocks in config files, `ipv4_address` is now +required on the `forwarding_config.target_name_servers` block. + +### `target_name_servers` is now required on block `google_dns_managed_zone.forwarding_config` + +In an attempt to avoid allowing empty blocks in config files, `target_name_servers` is now +required on the `forwarding_config` block. + ### `networks` is now required on block `google_dns_managed_zone.private_visibility_config` In an attempt to avoid allowing empty blocks in config files, `networks` is now -required on the `google_dns_managed_zone.private_visibility_config` block. +required on the `private_visibility_config` block. ### `network_url` is now required on block `google_dns_managed_zone.private_visibility_config.networks` In an attempt to avoid allowing empty blocks in config files, `network_url` is now -required on the `google_dns_managed_zone.private_visibility_config.networks` block. +required on the `private_visibility_config.networks` block. + +## Resource: `google_dns_policy` + +### `network_url` is now required on block `google_dns_policy.networks` + +In an attempt to avoid allowing empty blocks in config files, `network_url` is now +required on the `networks` block. + +### `target_name_servers` is now required on block `google_dns_policy.alternative_name_server_config` + +In an attempt to avoid allowing empty blocks in config files, `target_name_servers` is now +required on the `alternative_name_server_config` block. + +### `ipv4_address` is now required on block `google_dns_policy.alternative_name_server_config.target_name_servers` + +In an attempt to avoid allowing empty blocks in config files, `ipv4_address` is now +required on the `alternative_name_server_config.target_name_servers` block. + +## Resource: `google_healthcare_hl7_v2_store` + +### At least one of `allow_null_header ` or `segment_terminator` is now required on +`google_healthcare_hl7_v2_store.parser_config` + +In an attempt to avoid allowing empty blocks in config files, at least one of `allow_null_header ` +or `segment_terminator` is now required on the `parser_config` block. + +## Resource: `google_logging_metric` + +### At least one of `linear_buckets`, `exponential_buckets` or `explicit_buckets` is now required +on `google_logging_metric.bucket_options` + +In an attempt to avoid allowing empty blocks in config files, at least one of `linear_buckets`, +`exponential_buckets` or `explicit_buckets` is now required on the `bucket_options` block. + +### At least one of `num_finite_buckets`, `width` or `offset` is now required on +`google_logging_metric.bucket_options.linear_buckets` + +In an attempt to avoid allowing empty blocks in config files, at least one of `num_finite_buckets`, +`width` or `offset` is now required on the `bucket_options.linear_buckets` block. + +### At least one of `num_finite_buckets`, `growth_factor` or `scale` is now required on +`google_logging_metric.bucket_options.exponential_buckets` + +In an attempt to avoid allowing empty blocks in config files, at least one of `num_finite_buckets`, +`growth_factor` or `scale` is now required on the `bucket_options.exponential_buckets` block. + +### `bounds` is now required on `google_logging_metric.bucket_options.explicit_buckets` + +In an attempt to avoid allowing empty blocks in config files, `bounds` is now required on the +`bucket_options.explicit_buckets` block. + +## Resource: `google_mlengine_model` + +### `name` is now required on `google_mlengine_model.default_version` + +In an attempt to avoid allowing empty blocks in config files, `name` is now required on the +`default_version` block. ## Resource: `google_monitoring_alert_policy` @@ -729,12 +1326,43 @@ required on the `google_dns_managed_zone.private_visibility_config.networks` blo `labels` is removed as it was never used. See `user_labels` for the correct field. +### At least one of `content` or `mime_type` is now required on `google_monitoring_alert_policy.documentation` + +In an attempt to avoid allowing empty blocks in config files, at least one of `content` or `mime_type` +is now required on the `documentation` block. + ## Resource: `google_monitoring_uptime_check_config` +### Exactly one of `resource_group` or `monitored_resource` is now required on `google_monitoring_uptime_check_config` + +In attempt to be more consistent with the API, exactly one of `resource_group` or `monitored_resource` is now required +on `google_monitoring_uptime_check_config`. + +### Exactly one of `http_check` or `tcp_check` is now required on `google_monitoring_uptime_check_config` + +In attempt to be more consistent with the API, exactly one of `http_check` or `tcp_check` is now required +on `google_monitoring_uptime_check_config`. + +### At least one of `auth_info`, `port`, `headers`, `path`, `use_ssl`, or `mask_headers` is +now required on `google_monitoring_uptime_check_config.http_check` + +In an attempt to avoid allowing empty blocks in config files, at least one of `auth_info`, +`port`, `headers`, `path`, `use_ssl`, or `mask_headers` is now required on the `http_check` block. + +### At least one of `resource_type` or `group_id` is now required on `google_monitoring_uptime_check_config.resource_group` + +In an attempt to avoid allowing empty blocks in config files, at least one of `resource_type` or `group_id` +is now required on the `resource_group` block. + ### `content` is now required on block `google_monitoring_uptime_check_config.content_matchers` In an attempt to avoid allowing empty blocks in config files, `content` is now -required on the `google_monitoring_uptime_check_config.content_matchers` block. +required on the `content_matchers` block. + +### `username` and `password` are now required on block `google_monitoring_uptime_check_config.http_check.auth_info` + +In an attempt to avoid allowing empty blocks in config files, `username` and `password` are now +required on the `http_check.auth_info` block. ### `is_internal` and `internal_checker` are now removed @@ -742,10 +1370,22 @@ required on the `google_monitoring_uptime_check_config.content_matchers` block. ## Resource: `google_organization_policy` +### Exactly one of `list_policy`, `boolean_policy`, or `restore_policy` is now required on +`google_organization_policy` + +In attempt to be more consistent with the API, exactly one of `list_policy`, `boolean_policy`, +or `restore_policy` is now required on `google_organization_policy`. + +### Exactly one of `all` or `values` is now required on `google_organization_policy.list_policy.allow` +and `google_organization_policy.list_policy.deny` + +In an attempt to avoid allowing empty blocks in config files, exactly one of `all` or `values` is now +required on the `list_policy.allow` and `list_policy.deny` blocks. + ### `inherit_from_parent` is now required on block `google_organization_policy.list_policy` In an attempt to avoid allowing empty blocks in config files, `inherit_from_parent` is now -required on the `google_organization_policy.list_policy` block. +required on the `list_policy` block. ## Resource: `google_project_iam_audit_config` @@ -837,7 +1477,6 @@ resource "google_project_service" "service" { } ``` - ## Resource: `google_pubsub_subscription` ### `name` must now be a short name @@ -845,6 +1484,20 @@ resource "google_project_service" "service" { `name` previously could have been specified by a long name (e.g. `projects/my-project/subscriptions/my-subscription`) or a shortname (e.g. `my-subscription`). `name` now must be the shortname. +### `ttl` is now required on `google_pubsub_subscription.expiration_policy` + +Previously, an empty `expiration_policy` block would allow the resource to never expire. In an attempt to avoid +allowing empty blocks in config files, `ttl` is now required on the `expiration_policy` block. `ttl` should be set +to `""` for the resource to never expire. + +## Resource: `google_securitiy_scanner_scan_config` + +### At least one of `google_account` or `custom_account` is now required on +`google_securitiy_scanner_scan_config.authentication` + +In an attempt to avoid allowing empty blocks in config files, at least one of `google_account` or +`custom_account` is now required on the `authentication` block. + ## Resource: `google_service_account_key` ### `pgp_key`, `private_key_fingerprint`, and `private_key_encrypted` are now removed @@ -859,39 +1512,98 @@ is no known alternative at this time. ## Resource: `google_sql_database_instance` -### `dump_file_path`, `username` and `password` are now required on block `google_sql_database_instance.replica_configuration` +### At least one of `ca_certificate`, `client_certificate`, `client_key`, `connect_retry_interval`, +`dump_file_path`, `failover_target`, `master_heartbeat_period`, `password`, +`ssl_cipher`, `username`, or `verify_server_certificate` is now required on +`google_sql_database_instance.settings.replica_configuration` + +In an attempt to avoid allowing empty blocks in config files, at least one of `ca_certificate`, `client_certificate`, `client_key`, `connect_retry_interval`, +`dump_file_path`, `failover_target`, `master_heartbeat_period`, `password`, +`ssl_cipher`, `username`, or `verify_server_certificate` is now required on the +`settings.replica_configuration` block. + +### At least one of `cert`, `common_name`, `create_time`, `expiration_time`, or `sha1_fingerprint` +is now required on `google_sql_database_instance.settings.server_ca_cert` -In an attempt to avoid allowing empty blocks in config files, `dump_file_path`, `username` and `password` are now -required on the `google_sql_database_instance.replica_configuration` block. +In an attempt to avoid allowing empty blocks in config files, at least one of `cert`, `common_name`, `create_time`, +`expiration_time`, or `sha1_fingerprint` is now required on the +`settings.server_ca_cert` block. + +### At least one of `day`, `hour`, or `update_track` is now required on +`google_sql_database_instance.settings.maintenance_window` + +In an attempt to avoid allowing empty blocks in config files, at least one of `day`, `hour`, +or `update_track` is now required on the `settings.maintenance_window` block. + +### At least one of `binary_log_enabled`, `enabled`, `start_time`, or `location` is now required on +`google_sql_database_instance.settings.backup_configuration` + +In an attempt to avoid allowing empty blocks in config files, at least one of `binary_log_enabled`, +`enabled`, `start_time`, or `location` is now required on the +`settings.backup_configuration` block. + +### At least one of `authorized_networks`, `ipv4_enabled`, `require_ssl`, or `private_network` is now +required on `google_sql_database_instance.settings.ip_configuration` + +In an attempt to avoid allowing empty blocks in config files, at least one of `authorized_networks`, `ipv4_enabled`, +`require_ssl`, and `private_network` is now required on the `settings.ip_configuration` block. ### `name` and `value` are now required on block `google_sql_database_instance.settings.database_flags` In an attempt to avoid allowing empty blocks in config files, `name` and `value` are now -required on the `google_sql_database_instance.settings.database_flags` block. +required on the `settings.database_flags` block. ### `value` is now required on block `google_sql_database_instance.settings.ip_configuration.authorized_networks` In an attempt to avoid allowing empty blocks in config files, `value` is now -required on the `google_sql_database_instance.settings.ip_configuration.authorized_networks` block. +required on the `settings.ip_configuration.authorized_networks` block. ### `zone` is now required on block `google_sql_database_instance.settings.location_preference` In an attempt to avoid allowing empty blocks in config files, `zone` is now -required on the `google_sql_database_instance.settings.location_preference` block. +required on the `settings.location_preference` block. ## Resource: `google_storage_bucket` ### `enabled` is now required on block `google_storage_bucket.versioning` Previously the default value of `enabled` was `false`. In an attempt to avoid allowing empty blocks -in config files, `enabled` is now required on the `google_storage_bucket.versioning` block. +in config files, `enabled` is now required on the `versioning` block. + +### At least one of `main_page_suffix` or `not_found_page` is now required on `google_storage_bucket.website` + +In an attempt to avoid allowing empty blocks in config files, at least one of `main_page_suffix` or +`not_found_page` is now required on the `website` block. + +### At least one of `min_time_elapsed_since_last_modification`, `max_time_elapsed_since_last_modification`, +`include_prefixes`, or `exclude_prefixes` is now required on +`google_storage_transfer_job.transfer_spec.object_conditions` + +In an attempt to avoid allowing empty blocks in config files, at least one of `min_time_elapsed_since_last_modification`, +`max_time_elapsed_since_last_modification`, `include_prefixes`, or `exclude_prefixes` is now required +on the `transfer_spec.object_conditions` block. ### `is_live` is now removed Please use `with_state` instead, as `is_live` is now removed. ## Resource: `google_storage_transfer_job` -### `overwrite_objects_already_existing_in_sink` is now required on block `google_storage_transfer_job.transfer_options` +### At least one of `overwrite_objects_already_existing_in_sink`, `delete_objects_unique_in_sink`, or +`delete_objects_from_source_after_transfer` is now required on `google_storage_transfer_job.transfer_spec.transfer_options` + +In an attempt to avoid allowing empty blocks in config files, at least one of `overwrite_objects_already_existing_in_sink`, +`delete_objects_unique_in_sink`, or `delete_objects_from_source_after_transfer` is now required on the +`transfer_spec.transfer_options` block. + +### At least one of `gcs_data_source`, `aws_s3_data_source`, or `http_data_source` is now required +on `google_storage_transfer_job.transfer_spec` + +In an attempt to avoid allowing empty blocks in config files, at least one of `gcs_data_source`, `aws_s3_data_source`, +or `http_data_source` is now required on the `transfer_spec` block. + +## Resource: `google_tpu_node` + +### `preemptible` is now required on block `google_tpu_node.scheduling_config` -In an attempt to avoid allowing empty blocks in config files, `overwrite_objects_already_existing_in_sink` is now -required on the `google_storage_transfer_job.transfer_options` block. +In an attempt to avoid allowing empty blocks in config files, `preemptible` is now +required on the `scheduling_config` block.