From 83c5939152dad3973b969770ee95d3a8d1d74547 Mon Sep 17 00:00:00 2001 From: "Elena Xin (Centific Technologies Inc)" Date: Wed, 15 May 2024 17:05:50 +0800 Subject: [PATCH 1/3] fix gh issue 25788 --- .../container_app_custom_domain_resource.go | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/internal/services/containerapps/container_app_custom_domain_resource.go b/internal/services/containerapps/container_app_custom_domain_resource.go index fc0f3930e351..aec0f2487e81 100644 --- a/internal/services/containerapps/container_app_custom_domain_resource.go +++ b/internal/services/containerapps/container_app_custom_domain_resource.go @@ -211,11 +211,22 @@ func (a ContainerAppCustomDomainResource) Read() sdk.ResourceFunc { state.Name = id.CustomDomainName state.ContainerAppId = containerAppId.ID() if pointer.From(v.CertificateId) != "" { - certId, err := managedenvironments.ParseCertificateIDInsensitively(pointer.From(v.CertificateId)) - if err != nil { - return err + // The `v.CertificateId` returned from API has two possible values. when using an Azure created Managed Certificate, + // its format is "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.App/managedEnvironments/%s/managedCertificates/%s", + // another format is "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.App/managedEnvironments/%s/certificates/%s", + // both cases are handled here to avoid parsing error. + certificateId := "" + certId, err1 := managedenvironments.ParseCertificateIDInsensitively(pointer.From(v.CertificateId)) + if err1 != nil { + managedCertId, err2 := managedenvironments.ParseManagedCertificateID(pointer.From(v.CertificateId)) + if err2 != nil { + return err1 + } + certificateId = managedCertId.ID() + } else { + certificateId = certId.ID() } - state.CertificateId = certId.ID() + state.CertificateId = certificateId } state.BindingType = string(pointer.From(v.BindingType)) From 2f5838594c074c5ce825ad654b542c21a0431881 Mon Sep 17 00:00:00 2001 From: Elena Xin Date: Thu, 16 May 2024 16:18:32 +0800 Subject: [PATCH 2/3] fix run bash ./scripts/fun-gradually-deprecated.sh error --- .../container_app_custom_domain_resource.go | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/internal/services/containerapps/container_app_custom_domain_resource.go b/internal/services/containerapps/container_app_custom_domain_resource.go index aec0f2487e81..b884dee9e291 100644 --- a/internal/services/containerapps/container_app_custom_domain_resource.go +++ b/internal/services/containerapps/container_app_custom_domain_resource.go @@ -254,14 +254,6 @@ func (a ContainerAppCustomDomainResource) Delete() sdk.ResourceFunc { return err } - // attempt to lock the cert if we have the ID - if certIdRaw := metadata.ResourceData.Get("container_app_environment_certificate_id").(string); certIdRaw != "" { - if certId, err := managedenvironments.ParseCertificateID(certIdRaw); err == nil { - locks.ByID(certId.ID()) - defer locks.UnlockByID(certId.ID()) - } - } - containerAppId := containerapps.NewContainerAppID(id.SubscriptionId, id.ResourceGroupName, id.ContainerAppName) containerApp, err := client.Get(ctx, containerAppId) @@ -281,6 +273,13 @@ func (a ContainerAppCustomDomainResource) Delete() sdk.ResourceFunc { for _, v := range *customDomains { if !strings.EqualFold(v.Name, id.CustomDomainName) { updatedCustomDomains = append(updatedCustomDomains, v) + } else { + // attempt to lock the cert if we have the ID + certificateId := pointer.From(v.CertificateId) + if certificateId != "" { + locks.ByID(certificateId) + defer locks.UnlockByID(certificateId) + } } } } From 69a0591cdb418f70ccc2351bd3645e2ab868868a Mon Sep 17 00:00:00 2001 From: Elena Xin Date: Fri, 17 May 2024 10:54:41 +0800 Subject: [PATCH 3/3] fix comments --- .../container_app_custom_domain_resource.go | 22 +++++++++++-------- .../container_app_custom_domain.html.markdown | 6 +++++ 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/internal/services/containerapps/container_app_custom_domain_resource.go b/internal/services/containerapps/container_app_custom_domain_resource.go index b884dee9e291..06b142c0266b 100644 --- a/internal/services/containerapps/container_app_custom_domain_resource.go +++ b/internal/services/containerapps/container_app_custom_domain_resource.go @@ -28,10 +28,11 @@ type ContainerAppCustomDomainResource struct{} var _ sdk.Resource = ContainerAppCustomDomainResource{} type ContainerAppCustomDomainResourceModel struct { - Name string `tfschema:"name"` - ContainerAppId string `tfschema:"container_app_id"` - CertificateId string `tfschema:"container_app_environment_certificate_id"` - BindingType string `tfschema:"certificate_binding_type"` + Name string `tfschema:"name"` + ContainerAppId string `tfschema:"container_app_id"` + CertificateId string `tfschema:"container_app_environment_certificate_id"` + BindingType string `tfschema:"certificate_binding_type"` + ManagedCertificateId string `tfschema:"container_app_environment_managed_certificate_id"` } func (a ContainerAppCustomDomainResource) Arguments() map[string]*pluginsdk.Schema { @@ -70,7 +71,12 @@ func (a ContainerAppCustomDomainResource) Arguments() map[string]*pluginsdk.Sche } func (a ContainerAppCustomDomainResource) Attributes() map[string]*pluginsdk.Schema { - return map[string]*pluginsdk.Schema{} + return map[string]*pluginsdk.Schema{ + "container_app_environment_managed_certificate_id": { + Type: pluginsdk.TypeString, + Computed: true, + }, + } } func (a ContainerAppCustomDomainResource) ModelObject() interface{} { @@ -215,18 +221,16 @@ func (a ContainerAppCustomDomainResource) Read() sdk.ResourceFunc { // its format is "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.App/managedEnvironments/%s/managedCertificates/%s", // another format is "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.App/managedEnvironments/%s/certificates/%s", // both cases are handled here to avoid parsing error. - certificateId := "" certId, err1 := managedenvironments.ParseCertificateIDInsensitively(pointer.From(v.CertificateId)) if err1 != nil { managedCertId, err2 := managedenvironments.ParseManagedCertificateID(pointer.From(v.CertificateId)) if err2 != nil { return err1 } - certificateId = managedCertId.ID() + state.ManagedCertificateId = managedCertId.ID() } else { - certificateId = certId.ID() + state.CertificateId = certId.ID() } - state.CertificateId = certificateId } state.BindingType = string(pointer.From(v.BindingType)) diff --git a/website/docs/r/container_app_custom_domain.html.markdown b/website/docs/r/container_app_custom_domain.html.markdown index 8ed03c7a5952..b64ee51ac81b 100644 --- a/website/docs/r/container_app_custom_domain.html.markdown +++ b/website/docs/r/container_app_custom_domain.html.markdown @@ -125,6 +125,12 @@ The following arguments are supported: !> **NOTE:** If using an Azure Managed Certificate `container_app_environment_certificate_id` and `certificate_binding_type` should be added to `ignore_changes` to prevent resource recreation due to these values being modified asynchronously outside of Terraform. +## Attributes Reference + +In addition to the Arguments listed above - the following Attributes are exported: + +* `container_app_environment_managed_certificate_id` - The ID of the Container App Environment Managed Certificate to use. + ## Timeouts The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/docs/configuration/resources.html#timeouts) for certain actions: