From 5e32e56030c1bd90305a3b80d60d6fd1e39d409d Mon Sep 17 00:00:00 2001 From: hezijie Date: Mon, 5 Feb 2024 17:45:16 +0800 Subject: [PATCH] add validate for key vault secret only as tom suggested. --- ...container_app_environment_resource_test.go | 2 +- .../containerapps/helpers/container_apps.go | 11 +++-- .../containerapps/validate/validate.go | 6 +++ .../containerapps/validate/validate_test.go | 45 +++++++++++++++++++ 4 files changed, 59 insertions(+), 5 deletions(-) diff --git a/internal/services/containerapps/container_app_environment_resource_test.go b/internal/services/containerapps/container_app_environment_resource_test.go index b1a5f4c21307..285ab9c50f87 100644 --- a/internal/services/containerapps/container_app_environment_resource_test.go +++ b/internal/services/containerapps/container_app_environment_resource_test.go @@ -182,7 +182,7 @@ func (r ContainerAppEnvironmentResource) basic(data acceptance.TestData) string return fmt.Sprintf(` provider "azurerm" { features { - key_vault { + key_vault { purge_soft_deleted_secrets_on_destroy = true recover_soft_deleted_secrets = true } diff --git a/internal/services/containerapps/helpers/container_apps.go b/internal/services/containerapps/helpers/container_apps.go index bf4e4d468364..2e156eb873c0 100644 --- a/internal/services/containerapps/helpers/container_apps.go +++ b/internal/services/containerapps/helpers/container_apps.go @@ -2575,10 +2575,13 @@ func SecretsSchema() *pluginsdk.Schema { }, "key_vault_url": { - Type: pluginsdk.TypeString, - Optional: true, - ValidateFunc: validation.IsURLWithHTTPS, - Description: "Azure Key Vault URL pointing to the secret referenced by the container app.", + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.All( + validation.IsURLWithHTTPS, + validate.KeyVaultSecretUrl, + ), + Description: "Azure Key Vault URL pointing to the secret referenced by the container app.", }, "identity_id": { diff --git a/internal/services/containerapps/validate/validate.go b/internal/services/containerapps/validate/validate.go index 1b9cc1aa9ecf..fcff47c2c065 100644 --- a/internal/services/containerapps/validate/validate.go +++ b/internal/services/containerapps/validate/validate.go @@ -8,6 +8,8 @@ import ( "regexp" "strconv" "strings" + + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" ) func InitTimeout(i interface{}, k string) (warnings []string, errors []error) { @@ -144,3 +146,7 @@ func ContainerAppScaleRuleConcurrentRequests(i interface{}, k string) (warnings return } + +func KeyVaultSecretUrl(i interface{}, k string) (warnings []string, errors []error) { + return validation.StringMatch(regexp.MustCompile(`https?:\/\/([a-zA-Z0-9_-]+)\.(vault\.azure\.net|vault\.azure\.cn|vault\.usgovcloudapi\.net|vault\.microsoftazure\.de)\/secrets(\/.*)?`), "only Key Vault's secret are supported now, we don't support Managed HSM items this time.")(i, k) +} diff --git a/internal/services/containerapps/validate/validate_test.go b/internal/services/containerapps/validate/validate_test.go index 44203f9dc88f..22793695bdfc 100644 --- a/internal/services/containerapps/validate/validate_test.go +++ b/internal/services/containerapps/validate/validate_test.go @@ -320,3 +320,48 @@ func TestContainerAppScaleRuleConcurrentRequests(t *testing.T) { } } } + +// Object's url pattern could be found here: https://learn.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates#object-identifiers +func TestKeyVaultSecretUrl(t *testing.T) { + cases := []struct { + Input string + Valid bool + }{ + { + Input: "https://myVault.vault.azure.net/secrets/mySecret/version", + Valid: true, + }, + { + Input: "https://myVault.vault.azure.cn/secrets/mySecret/version", + Valid: true, + }, + { + Input: "https://myVault.vault.usgovcloudapi.net/secrets/mySecret/version", + Valid: true, + }, + { + Input: "https://myVault.vault.microsoftazure.de/secrets/mySecret/version", + Valid: true, + }, + { + // No HSM + Input: "https://myHSM.managedhsm.azure.net/secrets/mySecret/version", + Valid: false, + }, + { + // Must be secrets + Input: "https://myVault.vault.azure.net/keys/myKey/version", + Valid: false, + }, + } + + for _, tc := range cases { + t.Logf("[DEBUG] Testing Value %s", tc.Input) + _, errors := KeyVaultSecretUrl(tc.Input, "test") + valid := len(errors) == 0 + + if tc.Valid != valid { + t.Fatalf("Expected %t but got %t for %s", tc.Valid, valid, tc.Input) + } + } +}