Release Notes - v3.1.0
Overview
v3.1.0 is a minor release on top of v3.0.0. It bumps the underlying Terraform Google provider from v7.39.0 to v7.46.1, the last v7.x release, and introduces Plan: an offline, credential-free preview of what applying a managed resource would change, computed by the provider itself. It also adds 15 new managed resources, a universeDomain option on the ProviderConfig, and fixes several regressions from v3.0.0. Among them: write-only field panics, a Subnetwork reconcile failure, and NodePool update hot-loops.
The release carries one breaking bugfix API change, made for security reasons: compute.BackendService iap.oauth2ClientId is now a Secret reference. See the breaking bugfix API changes section below before upgrading.
Field paths below apply to both the cluster-scoped (*.gcp.upbound.io) and namespaced (*.gcp.m.upbound.io) variants of each resource.
⚠️ Breaking bugfix API changes
BackendService.compute: iap.oauth2ClientId moved to a Secret reference (#1036)
The upstream Terraform provider changed iap.oauth2_client_id on google_compute_backend_service from a regular attribute to a Sensitive attribute in v7.46.0 (hashicorp/terraform-provider-google#28809). Until now, the IAP OAuth2 client ID was stored in plaintext in the managed resource. Consequently:
spec.forProvider.iap.oauth2ClientIdandspec.initProvider.iap.oauth2ClientIdare removed from the CRD and replaced byiap.oauth2ClientIdSecretRef.status.atProvider.iap.oauth2ClientIdis removed from the CRD. The client ID is no longer reported in status.
Move the client ID into a Secret before upgrading and set
iap.oauth2ClientIdSecretRefon everyBackendServicethat setsiap.oauth2ClientId. Once the CRD is upgraded, the API server drops the inline value, and the provider treats the client ID as unset.⚠️ If you have compositions or functions that read
status.atProvider.iap.oauth2ClientId, update them. The value is no longer available from the managed resource.
# v3.0.0
iap:
enabled: true
oauth2ClientId: 1234567890-abc.apps.googleusercontent.com
oauth2ClientSecretSecretRef:
name: iap-oauth
namespace: crossplane-system
key: client-secret
# v3.1.0
iap:
enabled: true
oauth2ClientIdSecretRef:
name: iap-oauth
namespace: crossplane-system
key: client-id
oauth2ClientSecretSecretRef:
name: iap-oauth
namespace: crossplane-system
key: client-secretFor the namespaced compute.gcp.m.upbound.io API, Secret references are local to the managed resource's namespace, so omit namespace.
Go module consumers only: module path is now github.com/upbound/provider-gcp/v3 (#999)
The module declaration moved from github.com/upbound/provider-gcp/v2 to github.com/upbound/provider-gcp/v3, as Go semantic import versioning requires for v3 tags.
This is not a CRD/YAML-level change. Existing manifests and stored objects are unaffected. It only matters if you import this provider's packages in Go (for example from functions or custom controllers). Update your import paths accordingly.
Offline Diff Server (alpha)
This provider now support an offline gRPC-based diff server that computes diffs/plans for managed resources without connecting to Kubernetes or making cloud API calls.
The diff server allows users to preview what would change before applying a resource, without interacting with live infrastructure.
Key capabilities:
Computes CREATE, UPDATE, REPLACE, and NO_OP actions from the desired resource and its optional observed state.
Reports field-level changes, including planned values, replacement requirements, and change origins.
Accepts a PlanRequest with the desired resource, an optional actual resource, and an in-memory store containing the required ProviderConfig and referenced Secrets.
Supports both namespaced and cluster-scoped managed resources, including previously served API versions.
Runs without cloud credentials or live infrastructure access.
Exposes the PlanService.Plan gRPC API through the internal diff-server subcommand. Support is advertised through the DiffServer package capability.
Known limitations:
Some resources require cloud API calls during planning and cannot be fully evaluated offline. These requests may return FAILED_PRECONDITION, allowing callers to fall back to a raw diff.
Accurate plans depend on a complete observed state. Missing fields in status.atProvider may produce unexpected changes.
The gRPC API is experimental and may change without backward compatibility guarantees.
Resource coverage and planning behavior may vary between providers.
Design and implementation:
- Plan service one-pager - upjet (crossplane/upjet#694)
- crossplane/upjet#765, crossplane/upjet#769
- Provider integration: #1044
New Features
New Resources
All new resources are available at v1beta1 in both the cluster-scoped and namespaced APIs.
| Group | Kind(s) | Terraform resource(s) | PR |
|---|---|---|---|
alloydb
| User | google_alloydb_user
| #1017 |
cloudrun
| V2JobIAMBinding, V2JobIAMMember, V2JobIAMPolicy | google_cloud_run_v2_job_iam_binding, _iam_member, _iam_policy
| #954 |
cloudtasks
| QueueIAMMember | google_cloud_tasks_queue_iam_member
| #1031 |
iam
| DenyPolicy | google_iam_deny_policy
| #1061 |
networksecurity
| ServerTLSPolicy | google_network_security_server_tls_policy
| #1012 |
networksecurity
| BackendAuthenticationConfig, ClientTLSPolicy | google_network_security_backend_authentication_config, google_network_security_client_tls_policy
| #1035 |
spanner
| BackupSchedule | google_spanner_backup_schedule
| #996 |
vectorsearch
| Collection | google_vector_search_collection
| #1062 |
vertexai
| ReasoningEngine, ReasoningEngineIAMBinding, ReasoningEngineIAMMember, ReasoningEngineIAMPolicy | google_vertex_ai_reasoning_engine and its _iam_* resources
| #1009 |
vectorsearch is a new API group, published as a new family package: provider-gcp-vectorsearch.
ProviderConfig: universeDomain
ProviderConfig and ClusterProviderConfig accept a new optional universeDomain field: the Google Cloud universe to authenticate and issue API requests against. Leave it unset to use the default googleapis.com universe. The Terraform provider rejects a universe mismatch between its configuration and the credentials, so universeDomain is required when credentials carry a non-default universe, and it must match the credentials. (#1040)
Terraform Google Provider v7.46.1: New Fields
The Terraform provider bump adds new fields to 30 resources in both API scopes. Highlights:
container.Cluster:addonsConfig.highScaleCheckpointingConfig,addonsConfig.nodeReadinessConfig,desiredEmulatedVersion,maintenancePolicy.recurringMaintenanceWindow,nodeConfig.linuxNodeConfig.customNodeInit,rollbackSafeUpgrade.container.NodePool:maintenancePolicy,nodeConfig.linuxNodeConfig.customNodeInit.compute.Instance,InstanceFromTemplate,InstanceTemplate:scheduling.hostErrorTimeoutSeconds,workloadIdentityConfig.compute.BackendService,RegionBackendService:logConfig.requestHeaders,logConfig.responseHeaders.sql.DatabaseInstance:enforceNewSqlNetworkArchitecture,includeReplicasForMajorVersionUpgrade,settings.replicationLagMaxSeconds,settings.ipConfiguration.pscConfig[].pscAutoConnectionPolicyEnabled,switchTransactionLogsToCloudStorageEnabled.dataproc.Cluster: attached disk configuration on master, worker and preemptible worker configs, andconfidentialInstanceType.redis.Cluster,memorystore.Instance:aclPolicy.cloudrun.V2Service,V2Job:tags, plus sandbox settings on V2Service.
See #1036 for the complete list of added fields per resource.
Behaviour Changes from Upstream
sql.DatabaseInstance:diskTypeis no longer ForceNew, so changing it updates the instance in place instead of recreating it (v7.44.0).certificatemanager.Certificate: self-managed certificate data is updated in place instead of recreated (v7.41.0).container.NodePool: the default timeout is raised to 2h (v7.42.0).networksecurity.GatewaySecurityPolicy: changingnameorlocationnow forces replacement (v7.45.0).
Newly Deprecated Upstream
⚠️ These will be removed in the next major version. Plan your migration to the replacements.
| Resource | Deprecated | Replacement |
|---|---|---|
dataproc.Cluster
| clusterConfig.gceClusterConfig.confidentialInstanceConfig.enableConfidentialCompute
| confidentialInstanceType
|
beyondcorp.AppConnection, beyondcorp.AppConnector
| whole resources | google_beyondcorp_security_gateway / google_beyondcorp_security_gateway_application (not yet available in this provider)
|
beyondcorp.AppConnection and beyondcorp.AppConnector are kept unchanged in this release. In addition, workflows.Workflow sourceContents becomes required in Terraform provider v8.0.0.
Lower Memory Use and --enable-secret-cache
The update to crossplane-runtime v2.4.0 strips CRD schemas from the informer cache, which reduces provider memory use. A new flag, --enable-secret-cache (env ENABLE_SECRET_CACHE, default true), lets you turn off Secret informer caching to save more memory, at the cost of additional API server load. (#1010)
ProviderConfigs Protected While Managed Resources Terminate
A ProviderConfig can no longer be deleted while a managed resource that uses it is still terminating. ProviderConfigUsage objects now carry the finalizer.providerconfigusage.crossplane.io finalizer until the managed resource is gone. (#1025, crossplane/crossplane-runtime#1113)
Dependency Updates
| Dependency | v3.0.0 | v3.1.0 |
|---|---|---|
| Terraform Google Provider | v7.39.0 | v7.46.1 |
| Upjet | v2.4.1-0.20260728103920-4f6e6e10dff2 | v2.5.1-0.20261005082904-c3b7d449d0d4 |
| crossplane-runtime | v2.3.3 | v2.5.0-rc.0.0.20260908074656-9b2fb6b1d1ff |
| crossplane/crossplane APIs | v2.3.4 | v2.4.2 |
| Go | 1.26.5 | 1.27.1 |
Security updates: google.golang.org/grpc v1.83.2 and go.opentelemetry.io/otel/sdk v1.45.0.
Bug Fixes
compute.SSLCertificate,RegionSSLCertificate,VPNTunnel: fixed every operation failing withInvalid address to set: <field>_wo_versionsince v3.0.0. The*WoVersionfields are kept in the Terraform schema and exposed as status fields (privateKeyWoVersion,sharedSecretWoVersion); no spec fields were removed. (#998, #1043)sql.User: fixed anot a stringpanic on create and update for users without a password (for exampleCLOUD_IAM_SERVICE_ACCOUNTusers) since v3.0.0. (#1000, #1043)monitoring.NotificationChannel: fixed a panic caused by missing_wo_versionfields at runtime since v3.0.0.status.atProvider.sensitiveLabelsnow reportsauthTokenWoVersion,passwordWoVersionandserviceKeyWoVersionin place of the Secret reference fields previously listed there;specis unchanged. (#1037)storage.Notification,apigee.KeystoresAliasesKeyCertFile: fixed Plugin Framework provider wiring that left these resources non-functional in v3.0.0. (#995, #997)compute.Subnetwork: fixed a panic on every reconcile that kept Subnetwork resources from ever becoming Ready in v3.0.x. Upjet now populatesRawStateon the Plugin SDKv2 Observe path. (#1002, #1036)container.NodePool: stopped a sub-second no-op update loop on every NodePool that does not setnodeDrainConfig. (#1019, #1022)container.Cluster,container.NodePool: fixed arecovered from panic: value is nullfailure on create whennodeConfighas nokubeletConfig. (#1023, #1013, #1022)container.Cluster: suppressed a perpetual update loop caused by GCP returningmonitoringConfig.enableComponentsin non-deterministic order. (#1024)sql.DatabaseInstance:replicaNamesis no longer late-initialized intospec.forProvider. A stale value caused a no-op Cloud SQL update on every reconcile after the replica set changed. (#1026, #1027)sql.DatabaseInstance: updates are no longer blocked withcannot change the value of the argument "settings.0.disk_size"after Cloud SQL autoresizes a disk whosesettings.diskSizeis set only inspec.initProvider. Fixed by the upjet bump (crossplane/upjet#728). (#1030)cloudplatform.Project: a masked403returned for an absent project ID is now treated as not found, so Observe proceeds to Create instead of failing permanently. (#977, #1015)compute.FirewallPolicy: fixed Observe failing withHTTP 400(missingparentId) by resolving the correct identifier. (#820, #875)- Debug logging:
--debugnow surfaces controller-runtime logs, including recovered reconcile panics andReconciler errorlines, which were previously discarded. (#1036)
What's Changed
- compute: fix FirewallPolicy observe by correcting identifier resolution by @AndresAbdo in #875
- Add Spanner BackupSchedule managed resource by @rickard-von-essen in #996
- Fix framework provider wiring by @jonasz-lasut in #997
- Bump go module path to v3 by @nateinaction in #999
- Bump upjet to latest by @sergenyalcin in #1001
- Update to crossplane-runtime v2.4.0 by @jonasz-lasut in #1010
- fix(container): prevent panic on empty kubelet_config in node_config diff by @aayushrangwala in #1013
- Add google_network_security_server_tls_policy resource by @jamesachn in #1012
- Add example manifest linter to CI by @sergenyalcin in #1014
- feat[adding new resource]: Adding google_vertex_ai_reasoning_engine resource to provider (Issue #1006) by @tplastow in #1009
- Suppress
monitoring_config.enable_componentsorder-only diffs via CustomDiff by @sergenyalcin in #1024 - Consume crossplane-runtime #1113 by @jonasz-lasut in #1025
- fix(cloudplatform): treat masked 403 on absent project as not found by @gsoeldner in #1015
- feat(alloydb): add support for google_alloydb_user by @afarbos in #1017
- Ignore replica_names during late initialization for sql.DatabaseInstance by @amir-allahveran in #1027
- Add
BackendAuthenticationConfig.networksecurityandClientTLSPolicy.networksecurityby @jonasz-lasut in #1035 - fix(container): drop empty node_drain_config diff to stop nodepool reconcile hot-loop by @aayushrangwala in #1022
- Add QueueIAMMember resource for Cloud Tasks by @bakunowski in #1031
- Fix NotificationChannel panic due to missing _wo_version fields at runtime by @jonasz-lasut in #1037
- Fix compute SSL certificate, VPNTunnel and sql User failures due to missing _wo fields at runtime by @jonasz-lasut in #1043
- fix(build): run config unit tests in make test by @jonasz-lasut in #1042
- feat: add universe_domain option support for GCP provider by @duc00 in #1040
- Update go module directive to v1.26.8 by @renovate[bot] in #1003
- Update negz/create-tag action to v2 by @renovate[bot] in #1005
- Update module google.golang.org/grpc to v1.83.1 [SECURITY] by @renovate[bot] in #1020
- Update module go.opentelemetry.io/otel/sdk to v1.45.0 [SECURITY] by @renovate[bot] in #1033
- Update dependency kubernetes-sigs/kind to v0.33.0 by @renovate[bot] in #1052
- Update module github.com/crossplane/crossplane/apis/v2 to v2.4.2 by @renovate[bot] in #1050
- Update dependency golangci/golangci-lint to v2.14.0 by @renovate[bot] in #1008
- Update dependency ubuntu to v26 by @renovate[bot] in #1057
- Update jlumbroso/free-disk-space action to v2 by @renovate[bot] in #1058
- Update alpine Docker tag to v3.24.2 by @renovate[bot] in #1048
- Update docker/setup-qemu-action digest to 9901266 by @renovate[bot] in #1047
- Update module google.golang.org/grpc to v1.83.2 [SECURITY] by @renovate[bot] in #1059
- Update module sigs.k8s.io/controller-runtime to v0.25.2 by @renovate[bot] in #1055
- Update go module directive to v1.27.1 by @renovate[bot] in #1007
- Update kubernetes patches to v0.37.1 by @renovate[bot] in #1060
- Update module sigs.k8s.io/controller-tools to v0.22.0 by @renovate[bot] in #1056
- Update dependency crossplane/crossplane to v2.4.2 by @renovate[bot] in #1016
- feat(iam): add DenyPolicy resource (google_iam_deny_policy) by @gsoeldner in #1061
- Add a gRPC diff service implementation by @sergenyalcin in #1044
- Update underlying terraform provider to v7.46.1 by @jonasz-lasut in #1036
- feat: add support for cloud run job v2 iam by @lv-docto in #954
- Add google_vector_search_collection resource by @jamesachn in #1062
- Update actions/upload-artifact action to v7.0.2 by @renovate[bot] in #1049
New Contributors
- @AndresAbdo made their first contribution in #875
- @nateinaction made their first contribution in #999
- @aayushrangwala made their first contribution in #1013
- @jamesachn made their first contribution in #1012
- @tplastow made their first contribution in #1009
- @gsoeldner made their first contribution in #1015
- @afarbos made their first contribution in #1017
- @amir-allahveran made their first contribution in #1027
- @bakunowski made their first contribution in #1031
- @duc00 made their first contribution in #1040
- @lv-docto made their first contribution in #954
Full Changelog: v3.0.0...v3.1.0