diff --git a/builtin/providers/azurerm/provider.go b/builtin/providers/azurerm/provider.go index bf02ab83ad..58d0b6a8fd 100644 --- a/builtin/providers/azurerm/provider.go +++ b/builtin/providers/azurerm/provider.go @@ -1,6 +1,9 @@ package azurerm import ( + "crypto/sha1" + "encoding/base64" + "encoding/hex" "fmt" "log" "reflect" @@ -323,3 +326,31 @@ func ignoreCaseDiffSuppressFunc(k, old, new string, d *schema.ResourceData) bool func ignoreCaseStateFunc(val interface{}) string { return strings.ToLower(val.(string)) } + +func userDataStateFunc(v interface{}) string { + switch s := v.(type) { + case string: + s = base64Encode(s) + hash := sha1.Sum([]byte(s)) + return hex.EncodeToString(hash[:]) + default: + return "" + } +} + +// Base64Encode encodes data if the input isn't already encoded using +// base64.StdEncoding.EncodeToString. If the input is already base64 encoded, +// return the original input unchanged. +func base64Encode(data string) string { + // Check whether the data is already Base64 encoded; don't double-encode + if isBase64Encoded(data) { + return data + } + // data has not been encoded encode and return + return base64.StdEncoding.EncodeToString([]byte(data)) +} + +func isBase64Encoded(data string) bool { + _, err := base64.StdEncoding.DecodeString(data) + return err == nil +} diff --git a/builtin/providers/azurerm/resource_arm_virtual_machine.go b/builtin/providers/azurerm/resource_arm_virtual_machine.go index 3ba431a22d..389a82953d 100644 --- a/builtin/providers/azurerm/resource_arm_virtual_machine.go +++ b/builtin/providers/azurerm/resource_arm_virtual_machine.go @@ -2,7 +2,6 @@ package azurerm import ( "bytes" - "encoding/base64" "fmt" "log" "net/http" @@ -296,9 +295,10 @@ func resourceArmVirtualMachine() *schema.Resource { }, "custom_data": { - Type: schema.TypeString, - Optional: true, - Computed: true, + Type: schema.TypeString, + Optional: true, + Computed: true, + StateFunc: userDataStateFunc, }, }, }, @@ -887,14 +887,7 @@ func flattenAzureRmVirtualMachineOsProfile(osProfile *compute.OSProfile) []inter result["computer_name"] = *osProfile.ComputerName result["admin_username"] = *osProfile.AdminUsername if osProfile.CustomData != nil { - var data string - if isBase64Encoded(*osProfile.CustomData) { - decodedData, _ := base64.StdEncoding.DecodeString(*osProfile.CustomData) - data = string(decodedData) - } else { - data = *osProfile.CustomData - } - result["custom_data"] = data + result["custom_data"] = *osProfile.CustomData } return []interface{}{result} @@ -1047,12 +1040,7 @@ func expandAzureRmVirtualMachineOsProfile(d *schema.ResourceData) (*compute.OSPr } if v := osProfile["custom_data"].(string); v != "" { - if isBase64Encoded(v) { - log.Printf("[WARN] Future Versions of Terraform will automatically base64encode custom_data") - } else { - v = base64Encode(v) - } - + v = base64Encode(v) profile.CustomData = &v } diff --git a/builtin/providers/azurerm/resource_arm_virtual_machine_scale_set.go b/builtin/providers/azurerm/resource_arm_virtual_machine_scale_set.go index 02389f6707..f063119bd0 100644 --- a/builtin/providers/azurerm/resource_arm_virtual_machine_scale_set.go +++ b/builtin/providers/azurerm/resource_arm_virtual_machine_scale_set.go @@ -2,7 +2,6 @@ package azurerm import ( "bytes" - "encoding/base64" "fmt" "log" "net/http" @@ -93,8 +92,9 @@ func resourceArmVirtualMachineScaleSet() *schema.Resource { }, "custom_data": { - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, + StateFunc: userDataStateFunc, }, }, }, @@ -652,14 +652,7 @@ func flattenAzureRMVirtualMachineScaleSetOsProfile(profile *compute.VirtualMachi result["admin_username"] = *profile.AdminUsername if profile.CustomData != nil { - var data string - if isBase64Encoded(*profile.CustomData) { - decodedData, _ := base64.StdEncoding.DecodeString(*profile.CustomData) - data = string(decodedData) - } else { - data = *profile.CustomData - } - result["custom_data"] = data + result["custom_data"] = *profile.CustomData } return []interface{}{result} @@ -861,15 +854,6 @@ func expandAzureRmVirtualMachineScaleSetNetworkProfile(d *schema.ResourceData) * } } -func base64Encode(data string) string { - return base64.StdEncoding.EncodeToString([]byte(data)) -} - -func isBase64Encoded(data string) bool { - _, err := base64.StdEncoding.DecodeString(data) - return err == nil -} - func expandAzureRMVirtualMachineScaleSetsOsProfile(d *schema.ResourceData) (*compute.VirtualMachineScaleSetOSProfile, error) { osProfileConfigs := d.Get("os_profile").(*schema.Set).List() @@ -889,11 +873,7 @@ func expandAzureRMVirtualMachineScaleSetsOsProfile(d *schema.ResourceData) (*com } if customData != "" { - if isBase64Encoded(customData) { - log.Printf("[WARN] Future Versions of Terraform will automatically base64encode custom_data") - } else { - customData = base64Encode(customData) - } + customData = base64Encode(customData) osProfile.CustomData = &customData }