Missing glue for Terraform Plugin Framework resources - #89
Merged
fernandezcuesta merged 2 commits intoMay 13, 2026
Merged
Conversation
chore: bump up go dependencies Signed-off-by: Jesús Fernández <7312236+fernandezcuesta@users.noreply.github.com>
fernandezcuesta
force-pushed
the
84-cannotobserveexternalresource-when-creating-a-new-advancedcluster
branch
from
May 11, 2026 23:21
be70ed5 to
983ceb3
Compare
Collaborator
Author
|
Fix: #84 |
2 tasks
javier-gascon
approved these changes
May 13, 2026
fernandezcuesta
deleted the
84-cannotobserveexternalresource-when-creating-a-new-advancedcluster
branch
May 13, 2026 12:37
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
TPF External Name Fixes
Problem
Last versions of MongoDB Atlas Terraform Provider migrated resources from SDKv2 to the
Terraform Plugin Framework (TPF). TPF resources do not expose
idas a schemaattribute. Upjet's default
GetExternalNameFn(IDAsExternalName) readstfstate["id"]and fails with:This manifests as
CannotObserveExternalResourceon every reconciliation attempt.A second category of resources used
config.IdentifierFromProviderbut their TFprovider actually stores IDs using Atlas's
conversion.EncodeStateIDformat(base64-encoded key-value pairs). These resources need
encodedStateIDtocorrectly reconstruct the TF import ID and extract the external name.
Root Cause
Upjet intentionally skips injecting
idfor TPF resources that don't declare itin their schema (
external_tfpluginfw.go:147). WhenGetExternalNameFncallstfstate["id"], the key is missing and the function returns an error.For EncodeStateID resources,
config.IdentifierFromProviderassumes the rawidstring is the external name. But Atlas encodes composite keys as base64 pairs
(e.g.,
cHJvamVjdF9pZA==:YWJjMTIz-Y2x1c3Rlcl9uYW1l:bXlDbHVzdGVy), so theexternal name must be decoded from this format.
Changes
1. TPF fallback in
templatedStringAsIdentifier(config/external_name.go)Added
GetExternalNameFnthat falls back to rendering the template from statefields when
idis absent:Affected resources (use
templatedStringAsIdentifier):mongodbatlas_advanced_cluster{{ .parameters.project_id }}-{{ .parameters.name }}mongodbatlas_flex_cluster{{ .parameters.project_id }}-{{ .parameters.name }}mongodbatlas_search_deployment{{ .parameters.project_id }}-{{ .parameters.cluster_name }}mongodbatlas_stream_instance{{ .parameters.project_id }}-{{ .parameters.instance_name }}mongodbatlas_stream_connection{{ .parameters.workspace_name }}-{{ .parameters.project_id }}-{{ .parameters.connection_name }}mongodbatlas_stream_processor{{ .parameters.instance_name }}-{{ .parameters.project_id }}-{{ .parameters.processor_name }}mongodbatlas_encryption_at_rest{{ .parameters.project_id }}mongodbatlas_push_based_log_export{{ .parameters.project_id }}mongodbatlas_maintenance_window{{ .parameters.project_id }}mongodbatlas_custom_dns_configuration_cluster_aws{{ .parameters.project_id }}mongodbatlas_ldap_configuration{{ .parameters.project_id }}2. Merged
encodedStateIDWithExternalNameintoencodedStateIDMapped(config/external_name.go)Previously two separate functions existed:
encodedStateIDMapped-- all encoded keys come fromforProviderparamsencodedStateIDWithExternalName-- one key (provider-assigned) comes from the external name annotationMerged into a single
encodedStateIDMappedthat checks whetherexternalNameKeyis already covered by the field mapping. If not, it adds the external name
annotation value:
3. Migrated EncodeStateID resources from
IdentifierFromProvidertoencodedStateIDThese resources use Atlas's base64-encoded composite ID format but were incorrectly
configured with
config.IdentifierFromProvider:mongodbatlas_alert_configurationproject_ididIdentifierFromProvidermongodbatlas_cloud_backup_snapshot_export_bucketproject_ididIdentifierFromProvidermongodbatlas_cloud_backup_snapshot_export_jobproject_id,cluster_nameexport_job_idIdentifierFromProvidermongodbatlas_cloud_backup_snapshot_restore_jobproject_id,cluster_namesnapshot_restore_job_idIdentifierFromProvidermongodbatlas_cloud_backup_snapshotproject_id,cluster_namesnapshot_idIdentifierFromProvidermongodbatlas_cloud_provider_access_setupproject_id,provider_nameidIdentifierFromProvidermongodbatlas_network_containerproject_idcontainer_idIdentifierFromProvidermongodbatlas_network_peeringproject_id,provider_namepeer_idIdentifierFromProvidermongodbatlas_privatelink_endpoint_serviceproject_id,private_link_id,endpoint_service_id,provider_nameendpoint_service_idIdentifierFromProvidermongodbatlas_privatelink_endpointproject_id,provider_name,regionprivate_link_idIdentifierFromProvidermongodbatlas_search_indexproject_id,cluster_nameindex_idIdentifierFromProvidermongodbatlas_serverless_instanceproject_id,namenameIdentifierFromProvider4. Removed incorrect
GetIDFn/GetExternalNameFnoverrides in resource configuratorsPrevious overrides assumed TF IDs were simple dash-separated or double-dash-separated
strings (e.g.,
{project_id}-{snapshot_id}). The actual format is Atlas'sbase64-encoded state ID. Since the correct encoding is now handled by
encodedStateID/encodedStateIDMappedinexternal_name.go, these overrideswere removed.
5. Added TPF-aware
GetExternalNameFnoverrides forIdentifierFromProviderresourcesResources that remain on
config.IdentifierFromProviderbut are now TPF-basedneed custom
GetExternalNameFnto read the external name from a state fieldinstead of
id. Three helper functions were added toconfig/{cluster,namespaced}/common/common.go:ExternalNameFromIDOrState(sep, skipLeft, skipRight, stateField)id(SDKv2) or readstateFielddirectly (TPF)ExternalNameFromStateField(fields...)-ExternalNameFromAccessListState(scopeField){scope}-{client_id}-{ip_address}from state fieldsResources using these helpers:
mongodbatlas_log_integrationExternalNameFromIDOrStatetypemongodbatlas_service_accountExternalNameFromIDOrStateclient_idmongodbatlas_service_account_secretExternalNameFromIDOrStatesecret_idmongodbatlas_project_service_accountExternalNameFromIDOrStateclient_idmongodbatlas_project_service_account_secretExternalNameFromIDOrStatesecret_idmongodbatlas_service_account_access_list_entryExternalNameFromAccessListStateorg_id,client_id,ip_address/cidr_blockmongodbatlas_project_service_account_access_list_entryExternalNameFromAccessListStateproject_id,client_id,ip_address/cidr_blockSummary
templatedStringAsIdentifierGetExternalNameFn(automatic)IdentifierFromProviderencodedStateIDencodedStateID)IdentifierFromProviderneeding field extractionExternalNameFromIDOrState/ExternalNameFromAccessListStateencodedStateIDWithExternalNameintoencodedStateIDMapped