Skip to content

Commit

Permalink
azurerm_windows_virtual_machine_scale_set/`azurerm_linux_virtual_ma…
Browse files Browse the repository at this point in the history
…chine_scale_set` - define Hash function for extension block to ignore `protected_setting` (#13440)
  • Loading branch information
mbfrahry authored Sep 24, 2021
1 parent d841e69 commit ffe93c8
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,7 @@ func TestAccLinuxVirtualMachineScaleSet_otherEncryptionAtHost(t *testing.T) {
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep("admin_password", "extension.0.protected_settings"),
data.ImportStep("admin_password"),
})
}

Expand All @@ -538,21 +538,21 @@ func TestAccLinuxVirtualMachineScaleSet_otherEncryptionAtHostUpdate(t *testing.T
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep("admin_password", "extension.0.protected_settings"),
data.ImportStep("admin_password"),
{
Config: r.otherEncryptionAtHost(data, false),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep("admin_password", "extension.0.protected_settings"),
data.ImportStep("admin_password"),
{
Config: r.otherEncryptionAtHost(data, true),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep("admin_password", "extension.0.protected_settings"),
data.ImportStep("admin_password"),
})
}

Expand All @@ -567,7 +567,7 @@ func TestAccLinuxVirtualMachineScaleSet_otherEncryptionAtHostWithCMK(t *testing.
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep("admin_password", "extension.0.protected_settings"),
data.ImportStep("admin_password"),
})
}

Expand All @@ -582,7 +582,7 @@ func TestAccLinuxVirtualMachineScaleSet_otherPlatformFaultDomainCount(t *testing
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep("admin_password", "extension.0.protected_settings"),
data.ImportStep("admin_password"),
})
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func (r LinuxVirtualMachineScaleSetResource) Exists(ctx context.Context, clients

resp, err := clients.Compute.VMScaleSetClient.Get(ctx, id.ResourceGroup, id.Name)
if err != nil {
return nil, fmt.Errorf("retrieving Compute Linux Virtual Machine Scale Set %q", id)
return nil, fmt.Errorf("retrieving Compute Linux Virtual Machine Scale Set %q: %+v", id, err)
}

return utils.Bool(resp.ID != nil), nil
Expand Down
77 changes: 71 additions & 6 deletions internal/services/compute/virtual_machine_scale_set.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package compute

import (
"bytes"
"fmt"

"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2020-12-01/compute"
Expand Down Expand Up @@ -1553,13 +1554,61 @@ func VirtualMachineScaleSetExtensionsSchema() *pluginsdk.Schema {
},
},
},
Set: virtualMachineScaleSetExtensionHash,
}
}

func virtualMachineScaleSetExtensionHash(v interface{}) int {
var buf bytes.Buffer

if m, ok := v.(map[string]interface{}); ok {
buf.WriteString(fmt.Sprintf("%s-", m["name"].(string)))
buf.WriteString(fmt.Sprintf("%s-", m["publisher"].(string)))
buf.WriteString(fmt.Sprintf("%s-", m["type"].(string)))
buf.WriteString(fmt.Sprintf("%s-", m["type_handler_version"].(string)))
buf.WriteString(fmt.Sprintf("%t-", m["auto_upgrade_minor_version"].(bool)))

if v, ok = m["force_update_tag"]; ok {
buf.WriteString(fmt.Sprintf("%s-", v))
}

if v, ok := m["provision_after_extensions"]; ok {
buf.WriteString(fmt.Sprintf("%s-", v))
}

// we need to ensure the whitespace is consistent
settings := m["settings"].(string)
if settings != "" {
expandedSettings, err := pluginsdk.ExpandJsonFromString(settings)
if err == nil {
serializedSettings, err := pluginsdk.FlattenJsonToString(expandedSettings)
if err == nil {
buf.WriteString(fmt.Sprintf("%s-", serializedSettings))
}
}
}

if v, ok := m["protected_settings"]; ok {
settings := v.(string)
if settings != "" {
expandedSettings, err := pluginsdk.ExpandJsonFromString(settings)
if err == nil {
serializedSettings, err := pluginsdk.FlattenJsonToString(expandedSettings)
if err == nil {
buf.WriteString(fmt.Sprintf("%s-", serializedSettings))
}
}
}
}
}

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

func expandVirtualMachineScaleSetExtensions(input []interface{}) (extensionProfile *compute.VirtualMachineScaleSetExtensionProfile, hasHealthExtension bool, err error) {
extensionProfile = &compute.VirtualMachineScaleSetExtensionProfile{}
if len(input) == 0 {
return nil, false, nil
return extensionProfile, false, nil
}

extensions := make([]compute.VirtualMachineScaleSetExtension, 0)
Expand Down Expand Up @@ -1616,7 +1665,21 @@ func flattenVirtualMachineScaleSetExtensions(input *compute.VirtualMachineScaleS
return result, nil
}

for k, v := range *input.Extensions {
// extensionsFromState holds the "extension" block, which is used to retrieve the "protected_settings" to fill it back the state,
// since it is not returned from the API.
extensionsFromState := map[string]map[string]interface{}{}
if extSet, ok := d.GetOk("extension"); ok && extSet != nil {
extensions := extSet.(*pluginsdk.Set).List()
for _, ext := range extensions {
if ext == nil {
continue
}
ext := ext.(map[string]interface{})
extensionsFromState[ext["name"].(string)] = ext
}
}

for _, v := range *input.Extensions {
name := ""
if v.Name != nil {
name = *v.Name
Expand Down Expand Up @@ -1664,10 +1727,12 @@ func flattenVirtualMachineScaleSetExtensions(input *compute.VirtualMachineScaleS
extSettings = extSettingsRaw
}
}
// protected_settings isn't returned, so we attempt to get it from config otherwise set to empty string
if protectedSettingsFromConfig, ok := d.GetOk(fmt.Sprintf("extension.%d.protected_settings", k)); ok {
if protectedSettingsFromConfig.(string) != "" && protectedSettingsFromConfig.(string) != "{}" {
protectedSettings = protectedSettingsFromConfig.(string)
// protected_settings isn't returned, so we attempt to get it from state otherwise set to empty string
if ext, ok := extensionsFromState[name]; ok {
if protectedSettingsFromState, ok := ext["protected_settings"]; ok {
if protectedSettingsFromState.(string) != "" && protectedSettingsFromState.(string) != "{}" {
protectedSettings = protectedSettingsFromState.(string)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func TestAccWindowsVirtualMachineScaleSet_extensionMultiple(t *testing.T) {
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep("admin_password", "extension.0.protected_settings"),
data.ImportStep("admin_password", "extension.0.protected_settings", "extension.1.protected_settings"),
})
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -629,7 +629,7 @@ func TestAccWindowsVirtualMachineScaleSet_otherEncryptionAtHostEnabled(t *testin
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep("admin_password", "extension.0.protected_settings"),
data.ImportStep("admin_password"),
})
}

Expand All @@ -644,21 +644,21 @@ func TestAccWindowsVirtualMachineScaleSet_otherEncryptionAtHostEnabledUpdate(t *
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep("admin_password", "extension.0.protected_settings"),
data.ImportStep("admin_password"),
{
Config: r.otherEncryptionAtHostEnabled(data, false),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep("admin_password", "extension.0.protected_settings"),
data.ImportStep("admin_password"),
{
Config: r.otherEncryptionAtHostEnabled(data, true),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep("admin_password", "extension.0.protected_settings"),
data.ImportStep("admin_password"),
})
}

Expand All @@ -673,7 +673,7 @@ func TestAccWindowsVirtualMachineScaleSet_otherEncryptionAtHostEnabledWithCMK(t
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep("admin_password", "extension.0.protected_settings"),
data.ImportStep("admin_password"),
})
}

Expand All @@ -688,7 +688,7 @@ func TestAccWindowsVirtualMachineScaleSet_otherPlatformFaultDomainCount(t *testi
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep("admin_password", "extension.0.protected_settings"),
data.ImportStep("admin_password"),
})
}

Expand Down

0 comments on commit ffe93c8

Please sign in to comment.