Skip to content

Commit

Permalink
azurerm_spring_cloud_connection, azurerm_app_service_connection: …
Browse files Browse the repository at this point in the history
…Add support for `secret_store` (#20613)
  • Loading branch information
jiaweitao001 authored Feb 28, 2023
1 parent 695a27b commit 7feb3b4
Show file tree
Hide file tree
Showing 7 changed files with 311 additions and 12 deletions.
46 changes: 46 additions & 0 deletions internal/services/serviceconnector/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,27 @@ type AuthInfoModel struct {
Certificate string `tfschema:"certificate"`
}

type SecretStoreModel struct {
KeyVaultId string `tfschema:"key_vault_id"`
}

func secretStoreSchema() *pluginsdk.Schema {
return &pluginsdk.Schema{
Type: pluginsdk.TypeList,
Optional: true,
MaxItems: 1,
Elem: &pluginsdk.Resource{
Schema: map[string]*schema.Schema{
"key_vault_id": {
Type: pluginsdk.TypeString,
Required: true,
ValidateFunc: validation.StringIsNotEmpty,
},
},
},
}
}

func authInfoSchema() *pluginsdk.Schema {
return &pluginsdk.Schema{
Type: pluginsdk.TypeList,
Expand Down Expand Up @@ -83,6 +104,18 @@ func authInfoSchema() *pluginsdk.Schema {
}
}

func expandSecretStore(input []SecretStoreModel) *servicelinker.SecretStore {
if len(input) == 0 {
return nil
}
v := input[0]

keyVaultId := v.KeyVaultId
return &servicelinker.SecretStore{
KeyVaultId: utils.String(keyVaultId),
}
}

func expandServiceConnectorAuthInfo(input []AuthInfoModel) (servicelinker.AuthInfoBase, error) {
if len(input) == 0 {
return nil, fmt.Errorf("authentication should be defined")
Expand Down Expand Up @@ -286,3 +319,16 @@ func flattenTargetService(input servicelinker.TargetServiceBase) string {

return targetServiceId
}

func flattenSecretStore(input servicelinker.SecretStore) []SecretStoreModel {
var keyVaultId string
if input.KeyVaultId != nil {
keyVaultId = *input.KeyVaultId
}

return []SecretStoreModel{
{
KeyVaultId: keyVaultId,
},
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@ import (
type AppServiceConnectorResource struct{}

type AppServiceConnectorResourceModel struct {
Name string `tfschema:"name"`
AppServiceId string `tfschema:"app_service_id"`
TargetResourceId string `tfschema:"target_resource_id"`
ClientType string `tfschema:"client_type"`
AuthInfo []AuthInfoModel `tfschema:"authentication"`
VnetSolution string `tfschema:"vnet_solution"`
Name string `tfschema:"name"`
AppServiceId string `tfschema:"app_service_id"`
TargetResourceId string `tfschema:"target_resource_id"`
ClientType string `tfschema:"client_type"`
AuthInfo []AuthInfoModel `tfschema:"authentication"`
VnetSolution string `tfschema:"vnet_solution"`
SecretStore []SecretStoreModel `tfschema:"secret_store"`
}

func (r AppServiceConnectorResource) Arguments() map[string]*schema.Schema {
Expand Down Expand Up @@ -70,6 +71,8 @@ func (r AppServiceConnectorResource) Arguments() map[string]*schema.Schema {
}, false),
},

"secret_store": secretStoreSchema(),

"vnet_solution": {
Type: pluginsdk.TypeString,
Optional: true,
Expand Down Expand Up @@ -136,6 +139,11 @@ func (r AppServiceConnectorResource) Create() sdk.ResourceFunc {
}
}

if model.SecretStore != nil {
secretStore := expandSecretStore(model.SecretStore)
serviceConnectorProperties.SecretStore = secretStore
}

if model.ClientType != "" {
clientType := servicelinker.ClientType(model.ClientType)
serviceConnectorProperties.ClientType = &clientType
Expand Down Expand Up @@ -206,6 +214,10 @@ func (r AppServiceConnectorResource) Read() sdk.ResourceFunc {
state.VnetSolution = string(*props.VNetSolution.Type)
}

if props.SecretStore != nil {
state.SecretStore = flattenSecretStore(*props.SecretStore)
}

return metadata.Encode(&state)
}
return nil
Expand Down Expand Up @@ -265,6 +277,10 @@ func (r AppServiceConnectorResource) Update() sdk.ResourceFunc {
linkerProps.VNetSolution = &vnetSolution
}

if d.HasChange("secret_store") {
linkerProps.SecretStore = (*links.SecretStore)(expandSecretStore(state.SecretStore))
}

if d.HasChange("authentication") {
linkerProps.AuthInfo = state.AuthInfo
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,21 @@ func TestAccServiceConnectorAppServiceStorageBlob_basic(t *testing.T) {
})
}

func TestAccServiceConnectorAppServiceStorageBlob_secretStore(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_app_service_connection", "test")
r := ServiceConnectorAppServiceResource{}

data.ResourceTest(t, r, []acceptance.TestStep{
{
Config: r.secretStore(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep(),
})
}

func TestAccServiceConnectorAppServiceCosmosdb_update(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_app_service_connection", "test")
r := ServiceConnectorAppServiceResource{}
Expand Down Expand Up @@ -200,6 +215,107 @@ resource "azurerm_app_service_connection" "test" {
`, template, data.RandomString, data.RandomInteger)
}

func (r ServiceConnectorAppServiceResource) secretStore(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
features {
key_vault {
recover_soft_deleted_key_vaults = false
purge_soft_delete_on_destroy = false
purge_soft_deleted_keys_on_destroy = false
}
}
}
data "azurerm_client_config" "current" {}
resource "azurerm_resource_group" "test" {
name = "acctestRG-%[2]d"
location = "%[1]s"
}
resource "azurerm_storage_account" "test" {
name = "acctestacc%[4]s"
resource_group_name = azurerm_resource_group.test.name
location = azurerm_resource_group.test.location
account_tier = "Standard"
account_replication_type = "LRS"
}
resource "azurerm_service_plan" "test" {
name = "acctestASP-%[2]d"
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name
os_type = "Linux"
sku_name = "P1v2"
}
resource "azurerm_virtual_network" "test" {
name = "vnet-%[3]d"
address_space = ["10.0.0.0/16"]
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name
}
resource "azurerm_subnet" "test1" {
name = "subnet1"
resource_group_name = azurerm_resource_group.test.name
virtual_network_name = azurerm_virtual_network.test.name
address_prefixes = ["10.0.1.0/24"]
private_endpoint_network_policies_enabled = true
delegation {
name = "delegation"
service_delegation {
name = "Microsoft.Web/serverFarms"
actions = ["Microsoft.Network/virtualNetworks/subnets/action"]
}
}
}
resource "azurerm_linux_web_app" "test" {
name = "acctestWA-%[3]d"
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name
service_plan_id = azurerm_service_plan.test.id
virtual_network_subnet_id = azurerm_subnet.test1.id
site_config {}
lifecycle {
ignore_changes = [
app_settings["AZURE_STORAGEBLOB_RESOURCEENDPOINT"],
identity,
]
}
}
resource "azurerm_key_vault" "test" {
name = "accAKV-%[4]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
}
resource "azurerm_app_service_connection" "test" {
name = "acctestserviceconnector%[3]d"
app_service_id = azurerm_linux_web_app.test.id
target_resource_id = azurerm_storage_account.test.id
client_type = "java"
secret_store {
key_vault_id = azurerm_key_vault.test.id
}
authentication {
type = "systemAssignedIdentity"
}
}
`, data.Locations.Primary, data.RandomInteger, data.RandomInteger, data.RandomString)
}

func (r ServiceConnectorAppServiceResource) complete(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@ import (
type SpringCloudConnectorResource struct{}

type SpringCloudConnectorResourceModel struct {
Name string `tfschema:"name"`
SpringCloudId string `tfschema:"spring_cloud_id"`
TargetResourceId string `tfschema:"target_resource_id"`
ClientType string `tfschema:"client_type"`
AuthInfo []AuthInfoModel `tfschema:"authentication"`
VnetSolution string `tfschema:"vnet_solution"`
Name string `tfschema:"name"`
SpringCloudId string `tfschema:"spring_cloud_id"`
TargetResourceId string `tfschema:"target_resource_id"`
ClientType string `tfschema:"client_type"`
AuthInfo []AuthInfoModel `tfschema:"authentication"`
VnetSolution string `tfschema:"vnet_solution"`
SecretStore []SecretStoreModel `tfschema:"secret_store"`
}

func (r SpringCloudConnectorResource) Arguments() map[string]*schema.Schema {
Expand Down Expand Up @@ -72,6 +73,8 @@ func (r SpringCloudConnectorResource) Arguments() map[string]*schema.Schema {
}, false),
},

"secret_store": secretStoreSchema(),

"vnet_solution": {
Type: pluginsdk.TypeString,
Optional: true,
Expand Down Expand Up @@ -138,6 +141,11 @@ func (r SpringCloudConnectorResource) Create() sdk.ResourceFunc {
}
}

if model.SecretStore != nil {
secretStore := expandSecretStore(model.SecretStore)
serviceConnectorProperties.SecretStore = secretStore
}

if model.ClientType != "" {
clientType := servicelinker.ClientType(model.ClientType)
serviceConnectorProperties.ClientType = &clientType
Expand Down Expand Up @@ -207,6 +215,10 @@ func (r SpringCloudConnectorResource) Read() sdk.ResourceFunc {
state.VnetSolution = string(*props.VNetSolution.Type)
}

if props.SecretStore != nil {
state.SecretStore = flattenSecretStore(*props.SecretStore)
}

return metadata.Encode(&state)
}
return nil
Expand Down Expand Up @@ -266,6 +278,10 @@ func (r SpringCloudConnectorResource) Update() sdk.ResourceFunc {
linkerProps.VNetSolution = &vnetSolution
}

if d.HasChange("secret_store") {
linkerProps.SecretStore = (*links.SecretStore)(expandSecretStore(state.SecretStore))
}

if d.HasChange("authentication") {
linkerProps.AuthInfo = state.AuthInfo
}
Expand Down
Loading

0 comments on commit 7feb3b4

Please sign in to comment.