Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

azurerm_healthcare_service: support for customer managed key #11481

Merged
merged 9 commits into from
Apr 29, 2021
16 changes: 2 additions & 14 deletions azurerm/internal/services/cosmos/cosmosdb_account_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/cosmos/common"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/cosmos/parse"
keyVaultParse "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/keyvault/parse"
keyVaultSuppress "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/keyvault/suppress"
keyVaultValidate "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/keyvault/validate"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tf/pluginsdk"
Expand Down Expand Up @@ -135,7 +136,7 @@ func resourceCosmosDbAccount() *schema.Resource {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
DiffSuppressFunc: diffSuppressIgnoreKeyVaultKeyVersion,
DiffSuppressFunc: keyVaultSuppress.DiffSuppressIgnoreKeyVaultKeyVersion,
ValidateFunc: keyVaultValidate.VersionlessNestedItemId,
},

Expand Down Expand Up @@ -1084,16 +1085,3 @@ func resourceAzureRMCosmosDBAccountVirtualNetworkRuleHash(v interface{}) int {

return schema.HashString(buf.String())
}

func diffSuppressIgnoreKeyVaultKeyVersion(k, old, new string, d *schema.ResourceData) bool {
oldKey, err := keyVaultParse.ParseOptionallyVersionedNestedItemID(old)
if err != nil {
return false
}
newKey, err := keyVaultParse.ParseOptionallyVersionedNestedItemID(new)
if err != nil {
return false
}

return (oldKey.KeyVaultBaseUrl == newKey.KeyVaultBaseUrl) && (oldKey.Name == newKey.Name)
}
2 changes: 1 addition & 1 deletion azurerm/internal/services/healthcare/client/client.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package client

import (
healthcare "github.com/Azure/azure-sdk-for-go/services/healthcareapis/mgmt/2019-09-16/healthcareapis"
healthcare "github.com/Azure/azure-sdk-for-go/services/healthcareapis/mgmt/2020-03-30/healthcareapis"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common"
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ func dataSourceHealthcareService() *schema.Resource {
Computed: true,
},

"cosmosdb_key_vault_key_versionless_id": {
Type: schema.TypeString,
Computed: true,
},

"access_policy_object_ids": {
Type: schema.TypeSet,
Computed: true,
Expand Down Expand Up @@ -140,11 +145,18 @@ func dataSourceHealthcareServiceRead(d *schema.ResourceData, meta interface{}) e
return fmt.Errorf("Error setting `access_policy_object_ids`: %+v", err)
}

cosmosThroughput := 0
if props.CosmosDbConfiguration != nil && props.CosmosDbConfiguration.OfferThroughput != nil {
cosmosThroughput = int(*props.CosmosDbConfiguration.OfferThroughput)
cosmodDbKeyVaultKeyVersionlessId := ""
cosmosDbThroughput := 0
if cosmos := props.CosmosDbConfiguration; cosmos != nil {
if v := cosmos.OfferThroughput; v != nil {
cosmosDbThroughput = int(*v)
}
if v := cosmos.KeyVaultKeyURI; v != nil {
cosmodDbKeyVaultKeyVersionlessId = *v
}
}
d.Set("cosmosdb_throughput", cosmosThroughput)
d.Set("cosmosdb_key_vault_key_versionless_id", cosmodDbKeyVaultKeyVersionlessId)
d.Set("cosmosdb_throughput", cosmosDbThroughput)

if err := d.Set("authentication_configuration", flattenHealthcareAuthConfig(props.AuthenticationConfiguration)); err != nil {
return fmt.Errorf("Error setting `authentication_configuration`: %+v", err)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,26 @@ func TestAccHealthCareServiceDataSource_basic(t *testing.T) {
check.That(data.ResourceName).Key("resource_group_name").Exists(),
check.That(data.ResourceName).Key("kind").Exists(),
check.That(data.ResourceName).Key("cosmosdb_throughput").Exists(),
check.That(data.ResourceName).Key("cosmosdb_key_vault_key_versionless_id").HasValue(""),
check.That(data.ResourceName).Key("tags.%").HasValue("0"),
),
},
})
}

func TestAccHealthCareServiceDataSource_complete(t *testing.T) {
data := acceptance.BuildTestData(t, "data.azurerm_healthcare_service", "test")
r := HealthCareServiceDataSource{}
data.DataSourceTest(t, []acceptance.TestStep{
{
Config: r.complete(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).Key("cosmosdb_key_vault_key_versionless_id").Exists(),
),
},
})
}

func (HealthCareServiceDataSource) basic(data acceptance.TestData) string {
return fmt.Sprintf(`
%s
Expand All @@ -41,3 +55,15 @@ data "azurerm_healthcare_service" "test" {
}
`, HealthCareServiceResource{}.basic(data))
}

func (HealthCareServiceDataSource) complete(data acceptance.TestData) string {
return fmt.Sprintf(`
%s

data "azurerm_healthcare_service" "test" {
name = azurerm_healthcare_service.test.name
resource_group_name = azurerm_healthcare_service.test.resource_group_name
location = azurerm_resource_group.test.location
}
`, HealthCareServiceResource{}.complete(data))
}
58 changes: 48 additions & 10 deletions azurerm/internal/services/healthcare/healthcare_service_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@ import (
"log"
"time"

"github.com/Azure/azure-sdk-for-go/services/healthcareapis/mgmt/2019-09-16/healthcareapis"
"github.com/Azure/azure-sdk-for-go/services/healthcareapis/mgmt/2020-03-30/healthcareapis"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/healthcare/parse"
keyVaultParse "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/keyvault/parse"
keyVaultSuppress "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/keyvault/suppress"
keyVaultValidate "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/keyvault/validate"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tf/pluginsdk"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts"
Expand Down Expand Up @@ -67,6 +70,14 @@ func resourceHealthcareService() *schema.Resource {
ValidateFunc: validation.IntBetween(1, 10000),
},

"cosmosdb_key_vault_key_versionless_id": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
DiffSuppressFunc: keyVaultSuppress.DiffSuppressIgnoreKeyVaultKeyVersion,
ValidateFunc: keyVaultValidate.VersionlessNestedItemId,
},

"access_policy_object_ids": {
Type: schema.TypeSet,
Optional: true,
Expand Down Expand Up @@ -196,7 +207,6 @@ func resourceHealthcareServiceCreateUpdate(d *schema.ResourceData, meta interfac
t := d.Get("tags").(map[string]interface{})

kind := d.Get("kind").(string)
cdba := int32(d.Get("cosmosdb_throughput").(int))

if d.IsNewResource() {
existing, err := client.Get(ctx, resGroup, name)
Expand All @@ -211,15 +221,18 @@ func resourceHealthcareServiceCreateUpdate(d *schema.ResourceData, meta interfac
}
}

cosmosDbConfiguration, err := expandAzureRMhealthcareapisCosmosDbConfiguration(d)
if err != nil {
return fmt.Errorf("Error expanding cosmosdb_configuration: %+v", err)
}

healthcareServiceDescription := healthcareapis.ServicesDescription{
Location: utils.String(location),
Tags: tags.Expand(t),
Kind: healthcareapis.Kind(kind),
Properties: &healthcareapis.ServicesProperties{
AccessPolicies: expandAzureRMhealthcareapisAccessPolicyEntries(d),
CosmosDbConfiguration: &healthcareapis.ServiceCosmosDbConfigurationInfo{
OfferThroughput: &cdba,
},
AccessPolicies: expandAzureRMhealthcareapisAccessPolicyEntries(d),
CosmosDbConfiguration: cosmosDbConfiguration,
CorsConfiguration: expandAzureRMhealthcareapisCorsConfiguration(d),
AuthenticationConfiguration: expandAzureRMhealthcareapisAuthentication(d),
},
Expand Down Expand Up @@ -282,11 +295,18 @@ func resourceHealthcareServiceRead(d *schema.ResourceData, meta interface{}) err
return fmt.Errorf("Error setting `access_policy_object_ids`: %+v", err)
}

cosmosThroughput := 0
if props.CosmosDbConfiguration != nil && props.CosmosDbConfiguration.OfferThroughput != nil {
cosmosThroughput = int(*props.CosmosDbConfiguration.OfferThroughput)
cosmodDbKeyVaultKeyVersionlessId := ""
cosmosDbThroughput := 0
if cosmos := props.CosmosDbConfiguration; cosmos != nil {
if v := cosmos.OfferThroughput; v != nil {
cosmosDbThroughput = int(*v)
}
if v := cosmos.KeyVaultKeyURI; v != nil {
cosmodDbKeyVaultKeyVersionlessId = *v
}
}
d.Set("cosmosdb_throughput", cosmosThroughput)
d.Set("cosmosdb_key_vault_key_versionless_id", cosmodDbKeyVaultKeyVersionlessId)
d.Set("cosmosdb_throughput", cosmosDbThroughput)

if err := d.Set("authentication_configuration", flattenHealthcareAuthConfig(props.AuthenticationConfiguration)); err != nil {
return fmt.Errorf("Error setting `authentication_configuration`: %+v", err)
Expand Down Expand Up @@ -379,6 +399,24 @@ func expandAzureRMhealthcareapisAuthentication(d *schema.ResourceData) *healthca
return auth
}

func expandAzureRMhealthcareapisCosmosDbConfiguration(d *schema.ResourceData) (*healthcareapis.ServiceCosmosDbConfigurationInfo, error) {
throughput := int32(d.Get("cosmosdb_throughput").(int))

cosmosdb := &healthcareapis.ServiceCosmosDbConfigurationInfo{
OfferThroughput: utils.Int32(throughput),
}

if keyVaultKeyIDRaw, ok := d.GetOk("cosmosdb_key_vault_key_versionless_id"); ok {
keyVaultKey, err := keyVaultParse.ParseOptionallyVersionedNestedItemID(keyVaultKeyIDRaw.(string))
if err != nil {
return nil, fmt.Errorf("could not parse Key Vault Key ID: %+v", err)
}
cosmosdb.KeyVaultKeyURI = utils.String(keyVaultKey.ID())
}

return cosmosdb, nil
}

func flattenHealthcareAccessPolicies(policies *[]healthcareapis.ServiceAccessPolicyEntry) []string {
result := make([]string, 0)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,17 +127,80 @@ func (HealthCareServiceResource) complete(data acceptance.TestData) string {

return fmt.Sprintf(`
provider "azurerm" {
features {}
features {
key_vault {
purge_soft_delete_on_destroy = false
}
}
}

provider "azuread" {}

data "azurerm_client_config" "current" {
}

data "azuread_service_principal" "cosmosdb" {
display_name = "Azure Cosmos DB"
}

resource "azurerm_resource_group" "test" {
name = "acctestRG-health-%d"
location = "%s"
}

resource "azurerm_key_vault" "test" {
name = "acctestkv-%s"
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name
tenant_id = data.azurerm_client_config.current.tenant_id
sku_name = "standard"

purge_protection_enabled = true
soft_delete_enabled = true
soft_delete_retention_days = 7

access_policy {
tenant_id = data.azurerm_client_config.current.tenant_id
object_id = data.azurerm_client_config.current.object_id

key_permissions = [
"list",
"create",
"delete",
"get",
"purge",
"update",
]
}

access_policy {
tenant_id = data.azurerm_client_config.current.tenant_id
object_id = data.azuread_service_principal.cosmosdb.id

key_permissions = [
"get",
"unwrapKey",
"wrapKey",
]
}
}

resource "azurerm_key_vault_key" "test" {
name = "examplekey"
key_vault_id = azurerm_key_vault.test.id
key_type = "RSA"
key_size = 2048

key_opts = [
"decrypt",
"encrypt",
"sign",
"unwrapKey",
"verify",
"wrapKey",
]
}

resource "azurerm_healthcare_service" "test" {
name = "testacc%d"
location = azurerm_resource_group.test.location
Expand Down Expand Up @@ -165,6 +228,9 @@ resource "azurerm_healthcare_service" "test" {
max_age_in_seconds = 500
allow_credentials = true
}

cosmosdb_throughput = 400
cosmosdb_key_vault_key_versionless_id = azurerm_key_vault_key.test.versionless_id
}
`, data.RandomInteger, location, data.RandomIntOfLength(17)) // name can only be 24 chars long
`, data.RandomInteger, location, data.RandomString, data.RandomIntOfLength(17)) // name can only be 24 chars long
}
19 changes: 19 additions & 0 deletions azurerm/internal/services/keyvault/suppress/key_vault_key.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package suppress

import (
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
keyVaultParse "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/keyvault/parse"
)

func DiffSuppressIgnoreKeyVaultKeyVersion(k, old, new string, d *schema.ResourceData) bool {
oldKey, err := keyVaultParse.ParseOptionallyVersionedNestedItemID(old)
if err != nil {
return false
}
newKey, err := keyVaultParse.ParseOptionallyVersionedNestedItemID(new)
if err != nil {
return false
}

return (oldKey.KeyVaultBaseUrl == newKey.KeyVaultBaseUrl) && (oldKey.Name == newKey.Name)
}
Loading