hashicorp / terraform-provider-azurerm

Terraform provider for Azure Resource Manager
https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs
Mozilla Public License 2.0
4.53k stars 4.6k forks source link

azurerm_signalr_service_custom_certificate key vault in different subscription #23131

Open sergiomcalzada opened 1 year ago

sergiomcalzada commented 1 year ago

Is there an existing issue for this?

Community Note

Terraform Version

1.4.6

AzureRM Provider Version

3.71.0

Affected Resource(s)/Data Source(s)

azurerm_signalr_service_custom_certificate

Terraform Configuration Files

don't have an example, but easy to reproduce

Debug Output/Panic Output

Stack trace from the terraform-provider-azurerm_v3.71.0_x5 plugin:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x5b12235]

goroutine 106 [running]:
github.com/hashicorp/terraform-provider-azurerm/internal/services/signalr.CustomCertSignalrServiceResource.Read.func1({0x7a4e028, 0xc004f31f20}, {0xc0015ce480, {0x7a4e8b0, 0xc0005a8b70}, 0xc004f19880, 0x0, {0x7a4fa30, 0xc424de8}})
        github.com/hashicorp/terraform-provider-azurerm/internal/services/signalr/signalr_service_custom_certificate_resource.go:171 +0x415
github.com/hashicorp/terraform-provider-azurerm/internal/sdk.(*ResourceWrapper).Resource.func2({0x7a4e028, 0xc004f31f20}, 0x7a4e060?, {0x64a9480?, 0xc0015ce480?})
        github.com/hashicorp/terraform-provider-azurerm/internal/sdk/wrapper_resource.go:62 +0x1e5
github.com/hashicorp/terraform-provider-azurerm/internal/sdk.diagnosticsWrapper.func1({0x7a4e028, 0xc004f31f20}, 0x0?, {0x64a9480, 0xc0015ce480})
        github.com/hashicorp/terraform-provider-azurerm/internal/sdk/wrapper_resource.go:188 +0xb8
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*Resource).create(0xc00071c2a0, {0x7a4e060, 0xc004f31320}, 0xd?, {0x64a9480, 0xc0015ce480})
        github.com/hashicorp/terraform-plugin-sdk/v2@v2.26.1/helper/schema/resource.go:707 +0x12e
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*Resource).Apply(0xc00071c2a0, {0x7a4e060, 0xc004f31320}, 0xc004f1d380, 0xc004f19700, {0x64a9480, 0xc0015ce480})
        github.com/hashicorp/terraform-plugin-sdk/v2@v2.26.1/helper/schema/resource.go:837 +0xa85
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*GRPCProviderServer).ApplyResourceChange(0xc0009979f8, {0x7a4e060?, 0xc004f31200?}, 0xc000873130)
        github.com/hashicorp/terraform-plugin-sdk/v2@v2.26.1/helper/schema/grpc_provider.go:1021 +0xe8d
github.com/hashicorp/terraform-plugin-go/tfprotov5/tf5server.(*server).ApplyResourceChange(0xc0001a6280, {0x7a4e060?, 0xc004f30810?}, 0xc000929180)
        github.com/hashicorp/terraform-plugin-go@v0.14.3/tfprotov5/tf5server/server.go:818 +0x574
github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5._Provider_ApplyResourceChange_Handler({0x6e900a0?, 0xc0001a6280}, {0x7a4e060, 0xc004f30810}, 0xc000929110, 0x0)
        github.com/hashicorp/terraform-plugin-go@v0.14.3/tfprotov5/internal/tfplugin5/tfplugin5_grpc.pb.go:385 +0x170
google.golang.org/grpc.(*Server).processUnaryRPC(0xc00024a1e0, {0x7a5e640, 0xc001970820}, 0xc004f2d560, 0xc0018e1e30, 0xc3e3d80, 0x0)
        google.golang.org/grpc@v1.53.0/server.go:1336 +0xd33
google.golang.org/grpc.(*Server).handleStream(0xc00024a1e0, {0x7a5e640, 0xc001970820}, 0xc004f2d560, 0x0)
        google.golang.org/grpc@v1.53.0/server.go:1704 +0xa36
google.golang.org/grpc.(*Server).serveStreams.func1.2()
        google.golang.org/grpc@v1.53.0/server.go:965 +0x98
created by google.golang.org/grpc.(*Server).serveStreams.func1
        google.golang.org/grpc@v1.53.0/server.go:963 +0x28a

Error: The terraform-provider-azurerm_v3.71.0_x5 plugin crashed!

Expected Behaviour

Custom certificate is added to the signalr service in azure and the command don't fails

Actual Behaviour

The custom certificate is added to the signalr service in azure but terraform crash with a panic

Steps to Reproduce

Use a certificate that is hosted in a KeyVault that is not located in the same subscription

Important Factoids

No response

References

No response

xiaxyi commented 1 year ago

Thanks @sergiomcalzada for raising this issue, may I know if you were trying to link a certificate from the key value which exists in different subs than the signalr service? I see that you mentioned that the certificate seems added successfully to the signalR service in azure portal but terraform crashed when it was trying to set the resource back to state?

sergiomcalzada commented 1 year ago

Hi @xiaxyi Yes, the key vault and the signar service are in different subscriptions. Indeed the "azurerm_signalr_service_custom_certificate" is created by terraform but it fails to read back the secret (or something) and it is not added to the state-file and the end result is a panic. Indeed I can see how it makes a request to get the keyvault by name but with the wrong subscription_id. I suppose, from the code, that as the parameter for the certificate has the key vault name try to find it to get back some more info assuming the subscription_id from the signalR service. Maybe an optional parameter to specify the key_vault_id (or key_vault_subscription_id) when it is hosted in a different subscription can fix it.

Yes, manually or even with the CLI we can link the certificate.

sergiomcalzada commented 1 year ago

Hi,

any update on this one?

xiaxyi commented 1 year ago

Thanks @sergiomcalzada for the update, I checked the provider code, indeed, we need to add a nil check for the key vault pointer when getting the key vault. However, your issue seems cannot be resolved by fixing the crash issue here since we still return an error if anything goes wrong fetching the key vault.

we are getting the key vault by based_url as below code:

keyVaultIdRaw, err := keyVaultClient.KeyVaultIDFromBaseUrl(ctx, resourcesClient, vaultBasedUri)
            if err != nil {
                return fmt.Errorf("getting key vault base uri from %s: %+v", id, err)
            }
            vaultId, err := commonids.ParseKeyVaultID(*keyVaultIdRaw)
            if err != nil {
                return fmt.Errorf("parsing key vault %s: %+v", vaultId, err)
            }

I assume there might be some permission or other issue when getting the cert from the key valut during the creation as we also use the cert id (looks like: "id": "https://xiaxintestkeyvault.vault.azure.net/certificates/xiaxintestcert/9a12b1c19xxxf5044",) to locate the cert, instead of the name:

    keyVaultCertificateId, err := keyVaultParse.ParseOptionallyVersionedNestedItemID(metadata.ResourceData.Get("custom_certificate_id").(string))
            if err != nil {
                return fmt.Errorf("parsing custom certificate id error: %+v", err)
            }

            keyVaultUri := keyVaultCertificateId.KeyVaultBaseUrl
            keyVaultSecretName := keyVaultCertificateId.Name
sergiomcalzada commented 11 months ago

Hi,

I totally understand that is not only fixing the null pointer, the kv and cert should be resolved in a different way.

Any ETA for fixing it?

xiaxyi commented 11 months ago

Thanks @sergiomcalzada for the update, the terraform provider is trying to locate the key vault by its base URL, not just the name, the kv cannot be found by the endpoint you provided, would you mind trying to do the same operation by azure api to see if the kv can be connected?

sergiomcalzada commented 11 months ago

Hi @xiaxyi

I have tested with the portal and it works properly so the az API should work too. We will test this week it and will confirm that also works

Kind regards, Sergio

benj-ch commented 5 months ago

Hi,

any news on this topic?

It's impossible to create a custom domain on SignalR with Terraform.

Regarding the permission, it's done by the managed identity