diff --git a/internal/services/applications/application_certificate_resource.go b/internal/services/applications/application_certificate_resource.go index 8fe4133090..baf13cc18a 100644 --- a/internal/services/applications/application_certificate_resource.go +++ b/internal/services/applications/application_certificate_resource.go @@ -62,6 +62,20 @@ func applicationCertificateResource() *pluginsdk.Resource { ExactlyOneOf: []string{"application_id", "application_object_id"}, Deprecated: "The `application_object_id` property has been replaced with the `application_id` property and will be removed in version 3.0 of the AzureAD provider", ValidateFunc: validation.Any(validation.IsUUID, parse.ValidateApplicationID), + DiffSuppressFunc: func(_, oldValue, newValue string, _ *pluginsdk.ResourceData) bool { + // Where oldValue is a UUID (i.e. the bare object ID), and newValue is a properly formed application + // resource ID, we'll ignore a diff where these point to the same application resource. + // This maintains compatibility with configurations mixing the ID attributes, e.g. + // application_object_id = azuread_application.example.id + if _, err := uuid.ParseUUID(oldValue); err == nil { + if applicationId, err := parse.ParseApplicationID(newValue); err == nil { + if applicationId.ApplicationId == oldValue { + return true + } + } + } + return false + }, }, "encoding": { diff --git a/internal/services/applications/application_federated_identity_credential_resource.go b/internal/services/applications/application_federated_identity_credential_resource.go index 146e19723a..4d6dbeca93 100644 --- a/internal/services/applications/application_federated_identity_credential_resource.go +++ b/internal/services/applications/application_federated_identity_credential_resource.go @@ -62,6 +62,20 @@ func applicationFederatedIdentityCredentialResource() *pluginsdk.Resource { ExactlyOneOf: []string{"application_id", "application_object_id"}, Deprecated: "The `application_object_id` property has been replaced with the `application_id` property and will be removed in version 3.0 of the AzureAD provider", ValidateFunc: validation.Any(validation.IsUUID, parse.ValidateApplicationID), + DiffSuppressFunc: func(_, oldValue, newValue string, _ *pluginsdk.ResourceData) bool { + // Where oldValue is a UUID (i.e. the bare object ID), and newValue is a properly formed application + // resource ID, we'll ignore a diff where these point to the same application resource. + // This maintains compatibility with configurations mixing the ID attributes, e.g. + // application_object_id = azuread_application.example.id + if _, err := uuid.ParseUUID(oldValue); err == nil { + if applicationId, err := parse.ParseApplicationID(newValue); err == nil { + if applicationId.ApplicationId == oldValue { + return true + } + } + } + return false + }, }, "audiences": { diff --git a/internal/services/applications/application_password_resource.go b/internal/services/applications/application_password_resource.go index 4c0059889f..8399a86ae9 100644 --- a/internal/services/applications/application_password_resource.go +++ b/internal/services/applications/application_password_resource.go @@ -66,6 +66,20 @@ func applicationPasswordResource() *pluginsdk.Resource { ExactlyOneOf: []string{"application_id", "application_object_id"}, Deprecated: "The `application_object_id` property has been replaced with the `application_id` property and will be removed in version 3.0 of the AzureAD provider", ValidateFunc: validation.Any(validation.IsUUID, parse.ValidateApplicationID), + DiffSuppressFunc: func(_, oldValue, newValue string, _ *pluginsdk.ResourceData) bool { + // Where oldValue is a UUID (i.e. the bare object ID), and newValue is a properly formed application + // resource ID, we'll ignore a diff where these point to the same application resource. + // This maintains compatibility with configurations mixing the ID attributes, e.g. + // application_object_id = azuread_application.example.id + if _, err := uuid.ParseUUID(oldValue); err == nil { + if applicationId, err := parse.ParseApplicationID(newValue); err == nil { + if applicationId.ApplicationId == oldValue { + return true + } + } + } + return false + }, }, "display_name": { diff --git a/internal/services/applications/application_pre_authorized_resource.go b/internal/services/applications/application_pre_authorized_resource.go index 7c8080b2c1..016ae2e294 100644 --- a/internal/services/applications/application_pre_authorized_resource.go +++ b/internal/services/applications/application_pre_authorized_resource.go @@ -62,6 +62,20 @@ func applicationPreAuthorizedResource() *pluginsdk.Resource { ExactlyOneOf: []string{"application_id", "application_object_id"}, Deprecated: "The `application_object_id` property has been replaced with the `application_id` property and will be removed in version 3.0 of the AzureAD provider", ValidateFunc: validation.Any(validation.IsUUID, parse.ValidateApplicationID), + DiffSuppressFunc: func(_, oldValue, newValue string, _ *pluginsdk.ResourceData) bool { + // Where oldValue is a UUID (i.e. the bare object ID), and newValue is a properly formed application + // resource ID, we'll ignore a diff where these point to the same application resource. + // This maintains compatibility with configurations mixing the ID attributes, e.g. + // application_object_id = azuread_application.example.id + if _, err := uuid.ParseUUID(oldValue); err == nil { + if applicationId, err := parse.ParseApplicationID(newValue); err == nil { + if applicationId.ApplicationId == oldValue { + return true + } + } + } + return false + }, }, "authorized_app_id": {