diff --git a/azurerm/helpers/azure/mysql.go b/azurerm/helpers/azure/mysql.go
deleted file mode 100644
index 7d133e333be3..000000000000
--- a/azurerm/helpers/azure/mysql.go
+++ /dev/null
@@ -1,15 +0,0 @@
-package azure
-
-import (
-	"fmt"
-
-	"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate"
-)
-
-func ValidateMySqlServerName(i interface{}, k string) (_ []string, errors []error) {
-	if m, regexErrs := validate.RegExHelper(i, k, `^[0-9a-z]([-0-9a-z]{0,61}[0-9a-z])?$`); !m {
-		return nil, append(regexErrs, fmt.Errorf("%q can contain only lowercase letters, numbers, and '-', but can't start or end with '-' or have more than 63 characters.", k))
-	}
-
-	return nil, nil
-}
diff --git a/azurerm/internal/services/mysql/mysql_configuration_resource.go b/azurerm/internal/services/mysql/mysql_configuration_resource.go
index ea1cd6e80ad2..e7c1485a3b00 100644
--- a/azurerm/internal/services/mysql/mysql_configuration_resource.go
+++ b/azurerm/internal/services/mysql/mysql_configuration_resource.go
@@ -9,6 +9,7 @@ import (
 	"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
 	"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure"
 	"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients"
+	"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/mysql/validate"
 	"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts"
 	"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
 )
@@ -43,7 +44,7 @@ func resourceArmMySQLConfiguration() *schema.Resource {
 				Type:         schema.TypeString,
 				Required:     true,
 				ForceNew:     true,
-				ValidateFunc: azure.ValidateMySqlServerName,
+				ValidateFunc: validate.MysqlServerServerName,
 			},
 
 			"value": {
diff --git a/azurerm/internal/services/mysql/mysql_database_resource.go b/azurerm/internal/services/mysql/mysql_database_resource.go
index f1f96e5ad6b8..1c7b8398cd55 100644
--- a/azurerm/internal/services/mysql/mysql_database_resource.go
+++ b/azurerm/internal/services/mysql/mysql_database_resource.go
@@ -12,6 +12,7 @@ import (
 	"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/features"
+	"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/mysql/validate"
 	"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts"
 	"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
 )
@@ -46,7 +47,7 @@ func resourceArmMySqlDatabase() *schema.Resource {
 				Type:         schema.TypeString,
 				Required:     true,
 				ForceNew:     true,
-				ValidateFunc: azure.ValidateMySqlServerName,
+				ValidateFunc: validate.MysqlServerServerName,
 			},
 
 			"charset": {
diff --git a/azurerm/internal/services/mysql/mysql_firewall_rule_resource.go b/azurerm/internal/services/mysql/mysql_firewall_rule_resource.go
index cc21cf9c0f48..b2435ced5e46 100644
--- a/azurerm/internal/services/mysql/mysql_firewall_rule_resource.go
+++ b/azurerm/internal/services/mysql/mysql_firewall_rule_resource.go
@@ -11,6 +11,7 @@ import (
 	"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/features"
+	"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/mysql/validate"
 	"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts"
 	"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
 )
@@ -46,7 +47,7 @@ func resourceArmMySqlFirewallRule() *schema.Resource {
 				Type:         schema.TypeString,
 				Required:     true,
 				ForceNew:     true,
-				ValidateFunc: azure.ValidateMySqlServerName,
+				ValidateFunc: validate.MysqlServerServerName,
 			},
 
 			"start_ip_address": {
diff --git a/azurerm/internal/services/mysql/mysql_server_resource.go b/azurerm/internal/services/mysql/mysql_server_resource.go
index 54bab650e0f6..7cc3d8364401 100644
--- a/azurerm/internal/services/mysql/mysql_server_resource.go
+++ b/azurerm/internal/services/mysql/mysql_server_resource.go
@@ -8,6 +8,8 @@ import (
 	"time"
 
 	"github.com/Azure/azure-sdk-for-go/services/mysql/mgmt/2017-12-01/mysql"
+	"github.com/Azure/go-autorest/autorest/date"
+	"github.com/hashicorp/go-azure-helpers/response"
 	"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"
@@ -15,6 +17,8 @@ import (
 	"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/features"
+	"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/mysql/parse"
+	"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/mysql/validate"
 	"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags"
 	"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts"
 	"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
@@ -28,7 +32,18 @@ func resourceArmMySqlServer() *schema.Resource {
 		Delete: resourceArmMySqlServerDelete,
 
 		Importer: &schema.ResourceImporter{
-			State: schema.ImportStatePassthrough,
+			State: func(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
+				if _, err := parse.MysqlServerServerID(d.Id()); err != nil {
+					return []*schema.ResourceData{d}, err
+				}
+
+				d.Set("create_mode", "Default")
+				if v, ok := d.GetOk("create_mode"); ok && v.(string) != "" {
+					d.Set("create_mode", v)
+				}
+
+				return []*schema.ResourceData{d}, nil
+			},
 		},
 
 		Timeouts: &schema.ResourceTimeout{
@@ -43,13 +58,89 @@ func resourceArmMySqlServer() *schema.Resource {
 				Type:         schema.TypeString,
 				Required:     true,
 				ForceNew:     true,
-				ValidateFunc: azure.ValidateMySqlServerName,
+				ValidateFunc: validate.MysqlServerServerName,
+			},
+
+			"administrator_login": {
+				Type:     schema.TypeString,
+				Optional: true,
+				Computed: true,
+				ForceNew: true,
+			},
+
+			"administrator_login_password": {
+				Type:      schema.TypeString,
+				Optional:  true,
+				Sensitive: true,
+			},
+
+			"auto_grow_enabled": {
+				Type:          schema.TypeBool,
+				Optional:      true,
+				Computed:      true, // TODO: remove in 3.0 and default to true
+				ConflictsWith: []string{"storage_profile.0.auto_grow"},
+			},
+
+			"backup_retention_days": {
+				Type:          schema.TypeInt,
+				Optional:      true,
+				Computed:      true,
+				ConflictsWith: []string{"storage_profile.0.backup_retention_days"},
+				ValidateFunc:  validation.IntBetween(7, 35),
+			},
+
+			"create_mode": {
+				Type:     schema.TypeString,
+				Optional: true,
+				Default:  string(mysql.CreateModeDefault),
+				ValidateFunc: validation.StringInSlice([]string{
+					string(mysql.CreateModeDefault),
+					string(mysql.CreateModeGeoRestore),
+					string(mysql.CreateModePointInTimeRestore),
+					string(mysql.CreateModeReplica),
+				}, false),
+			},
+
+			"creation_source_server_id": {
+				Type:         schema.TypeString,
+				Optional:     true,
+				ValidateFunc: validate.MysqlServerServerID,
+			},
+
+			"fqdn": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+
+			"geo_redundant_backup_enabled": {
+				Type:          schema.TypeBool,
+				Optional:      true,
+				Computed:      true,
+				ConflictsWith: []string{"storage_profile.0.geo_redundant_backup"},
+			},
+
+			"infrastructure_encryption_enabled": {
+				Type:     schema.TypeBool,
+				Optional: true,
+				ForceNew: true,
 			},
 
 			"location": azure.SchemaLocation(),
 
+			"public_network_access_enabled": {
+				Type:     schema.TypeBool,
+				Optional: true,
+				Default:  true,
+			},
+
 			"resource_group_name": azure.SchemaResourceGroupName(),
 
+			"restore_point_in_time": {
+				Type:         schema.TypeString,
+				Optional:     true,
+				ValidateFunc: validation.IsRFC3339Time,
+			},
+
 			"sku_name": {
 				Type:     schema.TypeString,
 				Required: true,
@@ -77,100 +168,129 @@ func resourceArmMySqlServer() *schema.Resource {
 				}, false),
 			},
 
-			"administrator_login": {
-				Type:     schema.TypeString,
-				Required: true,
-				ForceNew: true,
+			"ssl_enforcement": {
+				Type:         schema.TypeString,
+				Optional:     true,
+				Computed:     true,
+				Deprecated:   "this has been moved to the boolean attribute `ssl_enforcement_enabled` and will be removed in version 3.0 of the provider.",
+				ExactlyOneOf: []string{"ssl_enforcement", "ssl_enforcement_enabled"},
+				ValidateFunc: validation.StringInSlice([]string{
+					string(mysql.SslEnforcementEnumDisabled),
+					string(mysql.SslEnforcementEnumEnabled),
+				}, true),
+				DiffSuppressFunc: suppress.CaseDifference,
 			},
 
-			"administrator_login_password": {
-				Type:      schema.TypeString,
-				Required:  true,
-				Sensitive: true,
+			"ssl_enforcement_enabled": {
+				Type:         schema.TypeBool,
+				Optional:     true, // required in 3.0
+				Computed:     true, // remove computed in 3.0
+				ExactlyOneOf: []string{"ssl_enforcement", "ssl_enforcement_enabled"},
 			},
 
-			"version": {
+			"ssl_minimal_tls_version_enforced": {
 				Type:     schema.TypeString,
-				Required: true,
+				Optional: true,
+				Default:  string(mysql.TLSEnforcementDisabled),
 				ValidateFunc: validation.StringInSlice([]string{
-					string(mysql.FiveFullStopSix),
-					string(mysql.FiveFullStopSeven),
-					string(mysql.EightFullStopZero),
-				}, true),
-				DiffSuppressFunc: suppress.CaseDifference,
-				ForceNew:         true,
+					string(mysql.TLSEnforcementDisabled),
+					string(mysql.TLS10),
+					string(mysql.TLS11),
+					string(mysql.TLS12),
+				}, false),
+			},
+
+			"storage_mb": {
+				Type:         schema.TypeInt,
+				Optional:     true,
+				Computed:     true,
+				ExactlyOneOf: []string{"storage_profile.0.storage_mb"},
+				ValidateFunc: validation.All(
+					validation.IntBetween(5120, 4194304),
+					validation.IntDivisibleBy(1024),
+				),
 			},
 
 			"storage_profile": {
-				Type:     schema.TypeList,
-				Required: true,
-				MaxItems: 1,
+				Type:       schema.TypeList,
+				Optional:   true,
+				Computed:   true,
+				MaxItems:   1,
+				Deprecated: "all storage_profile properties have been moved to the top level. This block will be removed in version 3.0 of the provider.",
 				Elem: &schema.Resource{
 					Schema: map[string]*schema.Schema{
-						"storage_mb": {
-							Type:     schema.TypeInt,
-							Required: true,
-							ValidateFunc: validation.All(
-								validation.IntBetween(5120, 4194304),
-								validation.IntDivisibleBy(1024),
-							),
+						"auto_grow": {
+							Type:             schema.TypeString,
+							Optional:         true,
+							Computed:         true,
+							ConflictsWith:    []string{"auto_grow_enabled"},
+							Deprecated:       "this has been moved to the top level boolean attribute `auto_grow_enabled` and will be removed in version 3.0 of the provider.",
+							DiffSuppressFunc: suppress.CaseDifference,
+							ValidateFunc: validation.StringInSlice([]string{
+								string(mysql.StorageAutogrowEnabled),
+								string(mysql.StorageAutogrowDisabled),
+							}, false),
 						},
 						"backup_retention_days": {
-							Type:         schema.TypeInt,
-							Optional:     true,
-							ValidateFunc: validation.IntBetween(7, 35),
+							Type:          schema.TypeInt,
+							Optional:      true,
+							Computed:      true,
+							ConflictsWith: []string{"backup_retention_days"},
+							Deprecated:    "this has been moved to the top level and will be removed in version 3.0 of the provider.",
+							ValidateFunc:  validation.IntBetween(7, 35),
 						},
 						"geo_redundant_backup": {
-							Type:     schema.TypeString,
-							Optional: true,
+							Type:             schema.TypeString,
+							Optional:         true,
+							Computed:         true,
+							ConflictsWith:    []string{"geo_redundant_backup_enabled"},
+							Deprecated:       "this has been moved to the top level boolean attribute `geo_redundant_backup_enabled` and will be removed in version 3.0 of the provider.",
+							DiffSuppressFunc: suppress.CaseDifference,
 							ValidateFunc: validation.StringInSlice([]string{
 								"Enabled",
 								"Disabled",
 							}, true),
-							DiffSuppressFunc: suppress.CaseDifference,
 						},
-						"auto_grow": {
-							Type:     schema.TypeString,
-							Optional: true,
-							Default:  string(mysql.StorageAutogrowEnabled),
-							ValidateFunc: validation.StringInSlice([]string{
-								string(mysql.StorageAutogrowEnabled),
-								string(mysql.StorageAutogrowDisabled),
-							}, false),
+						"storage_mb": {
+							Type:          schema.TypeInt,
+							Optional:      true,
+							ConflictsWith: []string{"storage_mb"},
+							Deprecated:    "this has been moved to the top level and will be removed in version 3.0 of the provider.",
+							ValidateFunc: validation.All(
+								validation.IntBetween(5120, 4194304),
+								validation.IntDivisibleBy(1024),
+							),
 						},
 					},
 				},
 			},
 
-			"ssl_enforcement": {
+			"tags": tags.Schema(),
+
+			"version": {
 				Type:     schema.TypeString,
 				Required: true,
 				ValidateFunc: validation.StringInSlice([]string{
-					string(mysql.SslEnforcementEnumDisabled),
-					string(mysql.SslEnforcementEnumEnabled),
+					string(mysql.FiveFullStopSix),
+					string(mysql.FiveFullStopSeven),
+					string(mysql.EightFullStopZero),
 				}, true),
 				DiffSuppressFunc: suppress.CaseDifference,
+				ForceNew:         true,
 			},
-
-			"public_network_access_enabled": {
-				Type:     schema.TypeBool,
-				Optional: true,
-				Default:  true,
-			},
-
-			"fqdn": {
-				Type:     schema.TypeString,
-				Computed: true,
-			},
-
-			"tags": tags.Schema(),
 		},
 
 		CustomizeDiff: func(diff *schema.ResourceDiff, v interface{}) error {
 			tier, _ := diff.GetOk("sku_name")
-			storageMB, _ := diff.GetOk("storage_profile.0.storage_mb")
 
-			if strings.HasPrefix(tier.(string), "B_") && storageMB.(int) > 1048576 {
+			var storageMB int
+			if v, ok := diff.GetOk("storage_mb"); ok {
+				storageMB = v.(int)
+			} else if v, ok := diff.GetOk("storage_profile.0.storage_mb"); ok {
+				storageMB = v.(int)
+			}
+
+			if strings.HasPrefix(tier.(string), "B_") && storageMB > 1048576 {
 				return fmt.Errorf("basic pricing tier only supports upto 1,048,576 MB (1TB) of storage")
 			}
 
@@ -190,16 +310,11 @@ func resourceArmMySqlServerCreate(d *schema.ResourceData, meta interface{}) erro
 	location := azure.NormalizeLocation(d.Get("location").(string))
 	resourceGroup := d.Get("resource_group_name").(string)
 
-	publicAccess := mysql.PublicNetworkAccessEnumEnabled
-	if v := d.Get("public_network_access_enabled").(bool); !v {
-		publicAccess = mysql.PublicNetworkAccessEnumDisabled
-	}
-
 	if features.ShouldResourcesBeImported() && d.IsNewResource() {
 		existing, err := client.Get(ctx, resourceGroup, name)
 		if err != nil {
 			if !utils.ResponseWasNotFound(existing.Response) {
-				return fmt.Errorf("Error checking for presence of existing MySQL Server %q (Resource Group %q): %+v", name, resourceGroup, err)
+				return fmt.Errorf("checking for presence of existing MySQL Server %q (Resource Group %q): %+v", name, resourceGroup, err)
 			}
 		}
 
@@ -208,42 +323,131 @@ func resourceArmMySqlServerCreate(d *schema.ResourceData, meta interface{}) erro
 		}
 	}
 
+	mode := mysql.CreateMode(d.Get("create_mode").(string))
+	tlsMin := mysql.MinimalTLSVersionEnum(d.Get("ssl_minimal_tls_version_enforced").(string))
+	source := d.Get("creation_source_server_id").(string)
+	version := mysql.ServerVersion(d.Get("version").(string))
+
 	sku, err := expandServerSkuName(d.Get("sku_name").(string))
 	if err != nil {
-		return fmt.Errorf("error expanding sku_name for MySQL Server %q (Resource Group %q): %v", name, resourceGroup, err)
+		return fmt.Errorf("expanding sku_name for MySQL Server %q (Resource Group %q): %v", name, resourceGroup, err)
 	}
 
-	properties := mysql.ServerForCreate{
-		Location: &location,
-		Properties: &mysql.ServerPropertiesForDefaultCreate{
-			AdministratorLogin:         utils.String(d.Get("administrator_login").(string)),
-			AdministratorLoginPassword: utils.String(d.Get("administrator_login_password").(string)),
-			Version:                    mysql.ServerVersion(d.Get("version").(string)),
-			SslEnforcement:             mysql.SslEnforcementEnum(d.Get("ssl_enforcement").(string)),
-			StorageProfile:             expandMySQLStorageProfile(d),
-			CreateMode:                 mysql.CreateMode("Default"),
+	infraEncrypt := mysql.InfrastructureEncryptionEnabled
+	if v := d.Get("infrastructure_encryption_enabled"); !v.(bool) {
+		infraEncrypt = mysql.InfrastructureEncryptionDisabled
+	}
+
+	publicAccess := mysql.PublicNetworkAccessEnumEnabled
+	if v := d.Get("public_network_access_enabled"); !v.(bool) {
+		publicAccess = mysql.PublicNetworkAccessEnumDisabled
+	}
+
+	ssl := mysql.SslEnforcementEnumEnabled
+	if v, ok := d.GetOk("ssl_enforcement"); ok && strings.EqualFold(v.(string), string(mysql.SslEnforcementEnumDisabled)) {
+		ssl = mysql.SslEnforcementEnumDisabled
+	}
+	if v, ok := d.GetOkExists("ssl_enforcement_enabled"); ok && !v.(bool) {
+		ssl = mysql.SslEnforcementEnumDisabled
+	}
+
+	storage := expandMySQLStorageProfile(d)
+
+	var props mysql.BasicServerPropertiesForCreate
+	switch mode {
+	case mysql.CreateModeDefault:
+		admin := d.Get("administrator_login").(string)
+		pass := d.Get("administrator_login_password").(string)
+
+		if admin == "" {
+			return fmt.Errorf("`administrator_login` must not be empty when `create_mode` is `default`")
+		}
+		if pass == "" {
+			return fmt.Errorf("`administrator_login_password` must not be empty when `create_mode` is `default`")
+		}
+
+		if _, ok := d.GetOk("restore_point_in_time"); ok {
+			return fmt.Errorf("`restore_point_in_time` cannot be set when `create_mode` is `default`")
+		}
+
+		// check admin
+		props = &mysql.ServerPropertiesForDefaultCreate{
+			AdministratorLogin:         &admin,
+			AdministratorLoginPassword: &pass,
+			CreateMode:                 mode,
+			InfrastructureEncryption:   infraEncrypt,
 			PublicNetworkAccess:        publicAccess,
-		},
-		Sku:  sku,
-		Tags: tags.Expand(d.Get("tags").(map[string]interface{})),
+			MinimalTLSVersion:          tlsMin,
+			SslEnforcement:             ssl,
+			StorageProfile:             storage,
+			Version:                    version,
+		}
+	case mysql.CreateModePointInTimeRestore:
+		v, ok := d.GetOk("restore_point_in_time")
+		if !ok || v.(string) == "" {
+			return fmt.Errorf("restore_point_in_time must be set when create_mode is PointInTimeRestore")
+		}
+		time, _ := time.Parse(time.RFC3339, v.(string)) // should be validated by the schema
+
+		props = &mysql.ServerPropertiesForRestore{
+			CreateMode:     mode,
+			SourceServerID: &source,
+			RestorePointInTime: &date.Time{
+				Time: time,
+			},
+			InfrastructureEncryption: infraEncrypt,
+			PublicNetworkAccess:      publicAccess,
+			MinimalTLSVersion:        tlsMin,
+			SslEnforcement:           ssl,
+			StorageProfile:           storage,
+			Version:                  version,
+		}
+	case mysql.CreateModeGeoRestore:
+		props = &mysql.ServerPropertiesForGeoRestore{
+			CreateMode:               mode,
+			SourceServerID:           &source,
+			InfrastructureEncryption: infraEncrypt,
+			PublicNetworkAccess:      publicAccess,
+			MinimalTLSVersion:        tlsMin,
+			SslEnforcement:           ssl,
+			StorageProfile:           storage,
+			Version:                  version,
+		}
+	case mysql.CreateModeReplica:
+		props = &mysql.ServerPropertiesForReplica{
+			CreateMode:               mode,
+			SourceServerID:           &source,
+			InfrastructureEncryption: infraEncrypt,
+			PublicNetworkAccess:      publicAccess,
+			MinimalTLSVersion:        tlsMin,
+			SslEnforcement:           ssl,
+			Version:                  version,
+		}
+	}
+
+	server := mysql.ServerForCreate{
+		Location:   &location,
+		Properties: props,
+		Sku:        sku,
+		Tags:       tags.Expand(d.Get("tags").(map[string]interface{})),
 	}
 
-	future, err := client.Create(ctx, resourceGroup, name, properties)
+	future, err := client.Create(ctx, resourceGroup, name, server)
 	if err != nil {
-		return fmt.Errorf("Error creating MySQL Server %q (Resource Group %q): %+v", name, resourceGroup, err)
+		return fmt.Errorf("creating MySQL Server %q (Resource Group %q): %+v", name, resourceGroup, err)
 	}
 
 	if err = future.WaitForCompletionRef(ctx, client.Client); err != nil {
-		return fmt.Errorf("Error waiting for creation of MySQL Server %q (Resource Group %q): %+v", name, resourceGroup, err)
+		return fmt.Errorf("waiting for creation of MySQL Server %q (Resource Group %q): %+v", name, resourceGroup, err)
 	}
 
 	read, err := client.Get(ctx, resourceGroup, name)
 	if err != nil {
-		return fmt.Errorf("Error retrieving MySQL Server %q (Resource Group %q): %+v", name, resourceGroup, err)
+		return fmt.Errorf("retrieving MySQL Server %q (Resource Group %q): %+v", name, resourceGroup, err)
 	}
 
 	if read.ID == nil {
-		return fmt.Errorf("Cannot read MySQL Server %q (Resource Group %q) ID", name, resourceGroup)
+		return fmt.Errorf("cannot read MySQL Server %q (Resource Group %q) ID", name, resourceGroup)
 	}
 
 	d.SetId(*read.ID)
@@ -258,12 +462,14 @@ func resourceArmMySqlServerUpdate(d *schema.ResourceData, meta interface{}) erro
 
 	log.Printf("[INFO] preparing arguments for AzureRM MySQL Server update.")
 
-	name := d.Get("name").(string)
-	resourceGroup := d.Get("resource_group_name").(string)
+	id, err := parse.MysqlServerServerID(d.Id())
+	if err != nil {
+		return fmt.Errorf("parsing MySQL Server ID : %v", err)
+	}
 
 	sku, err := expandServerSkuName(d.Get("sku_name").(string))
 	if err != nil {
-		return fmt.Errorf("error expanding sku_name for MySQL Server %q (Resource Group %q): %v", name, resourceGroup, err)
+		return fmt.Errorf("expanding sku_name for MySQL Server %q (Resource Group %q): %v", id.Name, id.ResourceGroup, err)
 	}
 
 	publicAccess := mysql.PublicNetworkAccessEnumEnabled
@@ -271,34 +477,44 @@ func resourceArmMySqlServerUpdate(d *schema.ResourceData, meta interface{}) erro
 		publicAccess = mysql.PublicNetworkAccessEnumDisabled
 	}
 
+	ssl := mysql.SslEnforcementEnumEnabled
+	if v := d.Get("ssl_enforcement"); strings.EqualFold(v.(string), string(mysql.SslEnforcementEnumDisabled)) {
+		ssl = mysql.SslEnforcementEnumDisabled
+	}
+	if v := d.Get("ssl_enforcement_enabled").(bool); !v {
+		ssl = mysql.SslEnforcementEnumDisabled
+	}
+
+	storageProfile := expandMySQLStorageProfile(d)
+
 	properties := mysql.ServerUpdateParameters{
 		ServerUpdateParametersProperties: &mysql.ServerUpdateParametersProperties{
-			StorageProfile:             expandMySQLStorageProfile(d),
 			AdministratorLoginPassword: utils.String(d.Get("administrator_login_password").(string)),
-			Version:                    mysql.ServerVersion(d.Get("version").(string)),
-			SslEnforcement:             mysql.SslEnforcementEnum(d.Get("ssl_enforcement").(string)),
 			PublicNetworkAccess:        publicAccess,
+			SslEnforcement:             ssl,
+			StorageProfile:             storageProfile,
+			Version:                    mysql.ServerVersion(d.Get("version").(string)),
 		},
 		Sku:  sku,
 		Tags: tags.Expand(d.Get("tags").(map[string]interface{})),
 	}
 
-	future, err := client.Update(ctx, resourceGroup, name, properties)
+	future, err := client.Update(ctx, id.ResourceGroup, id.Name, properties)
 	if err != nil {
-		return fmt.Errorf("Error updating MySQL Server %q (Resource Group %q): %+v", name, resourceGroup, err)
+		return fmt.Errorf("updating MySQL Server %q (Resource Group %q): %+v", id.Name, id.ResourceGroup, err)
 	}
 
 	if err = future.WaitForCompletionRef(ctx, client.Client); err != nil {
-		return fmt.Errorf("Error waiting for MySQL Server %q (Resource Group %q) to finish updating: %+v", name, resourceGroup, err)
+		return fmt.Errorf("waiting for MySQL Server %q (Resource Group %q) to finish updating: %+v", id.Name, id.ResourceGroup, err)
 	}
 
-	read, err := client.Get(ctx, resourceGroup, name)
+	read, err := client.Get(ctx, id.ResourceGroup, id.Name)
 	if err != nil {
-		return fmt.Errorf("Error retrieving MySQL Server %q (Resource Group %q): %+v", name, resourceGroup, err)
+		return fmt.Errorf("retrieving MySQL Server %q (Resource Group %q): %+v", id.Name, id.ResourceGroup, err)
 	}
 
 	if read.ID == nil {
-		return fmt.Errorf("Cannot read MySQL Server %q (Resource Group %q) ID", name, resourceGroup)
+		return fmt.Errorf("cannot read MySQL Server %q (Resource Group %q) ID", id.Name, id.ResourceGroup)
 	}
 
 	d.SetId(*read.ID)
@@ -311,25 +527,24 @@ func resourceArmMySqlServerRead(d *schema.ResourceData, meta interface{}) error
 	ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d)
 	defer cancel()
 
-	id, err := azure.ParseAzureResourceID(d.Id())
+	id, err := parse.MysqlServerServerID(d.Id())
 	if err != nil {
-		return err
+		return fmt.Errorf("parsing MySQL Server ID : %v", err)
 	}
-	resourceGroup := id.ResourceGroup
-	name := id.Path["servers"]
 
-	resp, err := client.Get(ctx, resourceGroup, name)
+	resp, err := client.Get(ctx, id.ResourceGroup, id.Name)
 	if err != nil {
 		if utils.ResponseWasNotFound(resp.Response) {
+			log.Printf("[WARN] MySQL Server %q was not found (Resource Group %q)", id.Name, id.ResourceGroup)
 			d.SetId("")
 			return nil
 		}
 
-		return fmt.Errorf("Error making Read request on Azure MySQL Server %q (Resource Group %q): %+v", name, resourceGroup, err)
+		return fmt.Errorf("making Read request on Azure MySQL Server %q (Resource Group %q): %+v", id.Name, id.ResourceGroup, err)
 	}
 
 	d.Set("name", resp.Name)
-	d.Set("resource_group_name", resourceGroup)
+	d.Set("resource_group_name", id.ResourceGroup)
 
 	if location := resp.Location; location != nil {
 		d.Set("location", azure.NormalizeLocation(*location))
@@ -339,17 +554,29 @@ func resourceArmMySqlServerRead(d *schema.ResourceData, meta interface{}) error
 		d.Set("sku_name", sku.Name)
 	}
 
-	d.Set("administrator_login", resp.AdministratorLogin)
-	d.Set("version", string(resp.Version))
-	d.Set("ssl_enforcement", string(resp.SslEnforcement))
-	d.Set("public_network_access_enabled", resp.PublicNetworkAccess != mysql.PublicNetworkAccessEnumDisabled)
+	if props := resp.ServerProperties; props != nil {
+		d.Set("administrator_login", props.AdministratorLogin)
+		d.Set("infrastructure_encryption_enabled", props.InfrastructureEncryption == mysql.InfrastructureEncryptionEnabled)
+		d.Set("public_network_access_enabled", props.PublicNetworkAccess == mysql.PublicNetworkAccessEnumEnabled)
+		d.Set("ssl_enforcement", string(props.SslEnforcement))
+		d.Set("ssl_enforcement_enabled", props.SslEnforcement == mysql.SslEnforcementEnumEnabled)
+		d.Set("ssl_minimal_tls_version_enforced", props.MinimalTLSVersion)
+		d.Set("version", string(props.Version))
+
+		if err := d.Set("storage_profile", flattenMySQLStorageProfile(resp.StorageProfile)); err != nil {
+			return fmt.Errorf("setting `storage_profile`: %+v", err)
+		}
 
-	if err := d.Set("storage_profile", flattenMySQLStorageProfile(resp.StorageProfile)); err != nil {
-		return fmt.Errorf("Error setting `storage_profile`: %+v", err)
-	}
+		if storage := props.StorageProfile; storage != nil {
+			d.Set("auto_grow_enabled", storage.StorageAutogrow == mysql.StorageAutogrowEnabled)
+			d.Set("backup_retention_days", storage.BackupRetentionDays)
+			d.Set("geo_redundant_backup_enabled", storage.GeoRedundantBackup == mysql.Enabled)
+			d.Set("storage_mb", storage.StorageMB)
+		}
 
-	// Computed
-	d.Set("fqdn", resp.FullyQualifiedDomainName)
+		// Computed
+		d.Set("fqdn", props.FullyQualifiedDomainName)
+	}
 
 	return tags.FlattenAndSet(d, resp.Tags)
 }
@@ -359,20 +586,24 @@ func resourceArmMySqlServerDelete(d *schema.ResourceData, meta interface{}) erro
 	ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d)
 	defer cancel()
 
-	id, err := azure.ParseAzureResourceID(d.Id())
+	id, err := parse.MysqlServerServerID(d.Id())
 	if err != nil {
-		return err
+		return fmt.Errorf("parsing MySQL Server ID : %v", err)
 	}
-	resourceGroup := id.ResourceGroup
-	name := id.Path["servers"]
 
-	future, err := client.Delete(ctx, resourceGroup, name)
+	future, err := client.Delete(ctx, id.ResourceGroup, id.Name)
 	if err != nil {
-		return fmt.Errorf("Error deleting MySQL Server %q (Resource Group %q): %+v", name, resourceGroup, err)
+		if response.WasNotFound(future.Response()) {
+			return nil
+		}
+		return fmt.Errorf("deleting MySQL Server %q (Resource Group %q): %+v", id.Name, id.ResourceGroup, err)
 	}
 
 	if err = future.WaitForCompletionRef(ctx, client.Client); err != nil {
-		return fmt.Errorf("Error waiting for deletion of MySQL Server %q (Resource Group %q): %+v", name, resourceGroup, err)
+		if response.WasNotFound(future.Response()) {
+			return nil
+		}
+		return fmt.Errorf("waiting for deletion of MySQL Server %q (Resource Group %q): %+v", id.Name, id.ResourceGroup, err)
 	}
 
 	return nil
@@ -410,36 +641,58 @@ func expandServerSkuName(skuName string) (*mysql.Sku, error) {
 }
 
 func expandMySQLStorageProfile(d *schema.ResourceData) *mysql.StorageProfile {
-	storageprofiles := d.Get("storage_profile").([]interface{})
-	storageprofile := storageprofiles[0].(map[string]interface{})
+	storage := mysql.StorageProfile{}
+	if v, ok := d.GetOk("storage_profile"); ok {
+		storageprofile := v.([]interface{})[0].(map[string]interface{})
+
+		storage.BackupRetentionDays = utils.Int32(int32(storageprofile["backup_retention_days"].(int)))
+		storage.GeoRedundantBackup = mysql.GeoRedundantBackup(storageprofile["geo_redundant_backup"].(string))
+		storage.StorageAutogrow = mysql.StorageAutogrow(storageprofile["auto_grow"].(string))
+		storage.StorageMB = utils.Int32(int32(storageprofile["storage_mb"].(int)))
+	}
+
+	// now override whatever we may have from the block with the top level properties
+	if v, ok := d.GetOk("auto_grow_enabled"); ok {
+		storage.StorageAutogrow = mysql.StorageAutogrowDisabled
+		if v.(bool) {
+			storage.StorageAutogrow = mysql.StorageAutogrowEnabled
+		}
+	}
+
+	if v, ok := d.GetOk("backup_retention_days"); ok {
+		storage.BackupRetentionDays = utils.Int32(int32(v.(int)))
+	}
 
-	backupRetentionDays := storageprofile["backup_retention_days"].(int)
-	geoRedundantBackup := storageprofile["geo_redundant_backup"].(string)
-	storageMB := storageprofile["storage_mb"].(int)
-	autoGrow := storageprofile["auto_grow"].(string)
+	if v, ok := d.GetOk("geo_redundant_backup_enabled"); ok {
+		storage.GeoRedundantBackup = mysql.Disabled
+		if v.(bool) {
+			storage.GeoRedundantBackup = mysql.Enabled
+		}
+	}
 
-	return &mysql.StorageProfile{
-		BackupRetentionDays: utils.Int32(int32(backupRetentionDays)),
-		GeoRedundantBackup:  mysql.GeoRedundantBackup(geoRedundantBackup),
-		StorageMB:           utils.Int32(int32(storageMB)),
-		StorageAutogrow:     mysql.StorageAutogrow(autoGrow),
+	if v, ok := d.GetOk("storage_mb"); ok {
+		storage.StorageMB = utils.Int32(int32(v.(int)))
 	}
+
+	return &storage
 }
 
 func flattenMySQLStorageProfile(resp *mysql.StorageProfile) []interface{} {
 	values := map[string]interface{}{}
 
-	if storageMB := resp.StorageMB; storageMB != nil {
-		values["storage_mb"] = *storageMB
-	}
+	values["auto_grow"] = string(resp.StorageAutogrow)
 
+	values["backup_retention_days"] = nil
 	if backupRetentionDays := resp.BackupRetentionDays; backupRetentionDays != nil {
 		values["backup_retention_days"] = *backupRetentionDays
 	}
 
 	values["geo_redundant_backup"] = string(resp.GeoRedundantBackup)
 
-	values["auto_grow"] = string(resp.StorageAutogrow)
+	values["storage_mb"] = nil
+	if storageMB := resp.StorageMB; storageMB != nil {
+		values["storage_mb"] = *storageMB
+	}
 
 	return []interface{}{values}
 }
diff --git a/azurerm/internal/services/mysql/mysql_virtual_network_rule_resource.go b/azurerm/internal/services/mysql/mysql_virtual_network_rule_resource.go
index 21a520afca60..7399af29bc5e 100644
--- a/azurerm/internal/services/mysql/mysql_virtual_network_rule_resource.go
+++ b/azurerm/internal/services/mysql/mysql_virtual_network_rule_resource.go
@@ -10,22 +10,22 @@ import (
 	"github.com/hashicorp/go-azure-helpers/response"
 	"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
 	"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/helpers/validate"
+	azValidate "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate"
 	"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients"
 	"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features"
+	"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/mysql/validate"
 	"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts"
 	"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
 )
 
-func resourceArmMySqlVirtualNetworkRule() *schema.Resource {
+func resourceArmMySSQLVirtualNetworkRule() *schema.Resource {
 	return &schema.Resource{
-		Create: resourceArmMySqlVirtualNetworkRuleCreateUpdate,
-		Read:   resourceArmMySqlVirtualNetworkRuleRead,
-		Update: resourceArmMySqlVirtualNetworkRuleCreateUpdate,
-		Delete: resourceArmMySqlVirtualNetworkRuleDelete,
+		Create: resourceArmMySSQLVirtualNetworkRuleCreateUpdate,
+		Read:   resourceArmMySSQLVirtualNetworkRuleRead,
+		Update: resourceArmMySSQLVirtualNetworkRuleCreateUpdate,
+		Delete: resourceArmMySSQLVirtualNetworkRuleDelete,
 		Importer: &schema.ResourceImporter{
 			State: schema.ImportStatePassthrough,
 		},
@@ -42,7 +42,7 @@ func resourceArmMySqlVirtualNetworkRule() *schema.Resource {
 				Type:         schema.TypeString,
 				Required:     true,
 				ForceNew:     true,
-				ValidateFunc: validate.VirtualNetworkRuleName,
+				ValidateFunc: azValidate.VirtualNetworkRuleName,
 			},
 
 			"resource_group_name": azure.SchemaResourceGroupName(),
@@ -51,7 +51,7 @@ func resourceArmMySqlVirtualNetworkRule() *schema.Resource {
 				Type:         schema.TypeString,
 				Required:     true,
 				ForceNew:     true,
-				ValidateFunc: validation.StringIsNotEmpty,
+				ValidateFunc: validate.MysqlServerServerName,
 			},
 
 			"subnet_id": {
@@ -63,7 +63,7 @@ func resourceArmMySqlVirtualNetworkRule() *schema.Resource {
 	}
 }
 
-func resourceArmMySqlVirtualNetworkRuleCreateUpdate(d *schema.ResourceData, meta interface{}) error {
+func resourceArmMySSQLVirtualNetworkRuleCreateUpdate(d *schema.ResourceData, meta interface{}) error {
 	client := meta.(*clients.Client).MySQL.VirtualNetworkRulesClient
 	ctx, cancel := timeouts.ForCreateUpdate(meta.(*clients.Client).StopContext, d)
 	defer cancel()
@@ -123,10 +123,10 @@ func resourceArmMySqlVirtualNetworkRuleCreateUpdate(d *schema.ResourceData, meta
 
 	d.SetId(*resp.ID)
 
-	return resourceArmMySqlVirtualNetworkRuleRead(d, meta)
+	return resourceArmMySSQLVirtualNetworkRuleRead(d, meta)
 }
 
-func resourceArmMySqlVirtualNetworkRuleRead(d *schema.ResourceData, meta interface{}) error {
+func resourceArmMySSQLVirtualNetworkRuleRead(d *schema.ResourceData, meta interface{}) error {
 	client := meta.(*clients.Client).MySQL.VirtualNetworkRulesClient
 	ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d)
 	defer cancel()
@@ -162,7 +162,7 @@ func resourceArmMySqlVirtualNetworkRuleRead(d *schema.ResourceData, meta interfa
 	return nil
 }
 
-func resourceArmMySqlVirtualNetworkRuleDelete(d *schema.ResourceData, meta interface{}) error {
+func resourceArmMySSQLVirtualNetworkRuleDelete(d *schema.ResourceData, meta interface{}) error {
 	client := meta.(*clients.Client).MySQL.VirtualNetworkRulesClient
 	ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d)
 	defer cancel()
diff --git a/azurerm/internal/services/mysql/parse/mysql.go b/azurerm/internal/services/mysql/parse/mysql.go
new file mode 100644
index 000000000000..a8a370133682
--- /dev/null
+++ b/azurerm/internal/services/mysql/parse/mysql.go
@@ -0,0 +1,33 @@
+package parse
+
+import (
+	"fmt"
+
+	"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure"
+)
+
+type MysqlServerServerId struct {
+	ResourceGroup string
+	Name          string
+}
+
+func MysqlServerServerID(input string) (*MysqlServerServerId, error) {
+	id, err := azure.ParseAzureResourceID(input)
+	if err != nil {
+		return nil, fmt.Errorf("[ERROR] Unable to parse MySQL Server ID %q: %+v", input, err)
+	}
+
+	server := MysqlServerServerId{
+		ResourceGroup: id.ResourceGroup,
+	}
+
+	if server.Name, err = id.PopSegment("servers"); err != nil {
+		return nil, err
+	}
+
+	if err := id.ValidateNoEmptySegments(input); err != nil {
+		return nil, err
+	}
+
+	return &server, nil
+}
diff --git a/azurerm/internal/services/mysql/parse/mysql_test.go b/azurerm/internal/services/mysql/parse/mysql_test.go
new file mode 100644
index 000000000000..c3ccf38972ea
--- /dev/null
+++ b/azurerm/internal/services/mysql/parse/mysql_test.go
@@ -0,0 +1,68 @@
+package parse
+
+import (
+	"testing"
+)
+
+func TestValidateMysqlServerServerID(t *testing.T) {
+	testData := []struct {
+		Name     string
+		Input    string
+		Expected *MysqlServerServerId
+	}{
+		{
+			Name:     "Empty resource ID",
+			Input:    "",
+			Expected: nil,
+		},
+		{
+			Name:     "No resourceGroups segment",
+			Input:    "/subscriptions/00000000-0000-0000-0000-000000000000",
+			Expected: nil,
+		},
+		{
+			Name:     "No resource group name",
+			Input:    "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/",
+			Expected: nil,
+		},
+		{
+			Name:     "Resource group",
+			Input:    "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/",
+			Expected: nil,
+		},
+		{
+			Name:     "Missing server name",
+			Input:    "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.DBforMySQL/servers/",
+			Expected: nil,
+		},
+		{
+			Name:  "Valid",
+			Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.DBforMySQL/servers/test-mysql",
+			Expected: &MysqlServerServerId{
+				Name:          "test-mysql",
+				ResourceGroup: "test-rg",
+			},
+		},
+	}
+
+	for _, v := range testData {
+		t.Logf("[DEBUG] Testing %q", v.Name)
+
+		actual, err := MysqlServerServerID(v.Input)
+		if err != nil {
+			if v.Expected == nil {
+				continue
+			}
+
+			t.Fatalf("Expected a value but got an error: %s", err)
+		}
+
+		if actual.Name != v.Expected.Name {
+			t.Fatalf("Expected %q but got %q for Name", v.Expected.Name, actual.Name)
+		}
+
+		if actual.ResourceGroup != v.Expected.ResourceGroup {
+			t.Fatalf("Expected %q but got %q for Resource Group", v.Expected.ResourceGroup, actual.ResourceGroup)
+		}
+	}
+}
diff --git a/azurerm/internal/services/mysql/registration.go b/azurerm/internal/services/mysql/registration.go
index cf8e58ead01b..01c7dc617d45 100644
--- a/azurerm/internal/services/mysql/registration.go
+++ b/azurerm/internal/services/mysql/registration.go
@@ -30,5 +30,5 @@ func (r Registration) SupportedResources() map[string]*schema.Resource {
 		"azurerm_mysql_database":             resourceArmMySqlDatabase(),
 		"azurerm_mysql_firewall_rule":        resourceArmMySqlFirewallRule(),
 		"azurerm_mysql_server":               resourceArmMySqlServer(),
-		"azurerm_mysql_virtual_network_rule": resourceArmMySqlVirtualNetworkRule()}
+		"azurerm_mysql_virtual_network_rule": resourceArmMySSQLVirtualNetworkRule()}
 }
diff --git a/azurerm/internal/services/mysql/tests/mysql_server_resource_test.go b/azurerm/internal/services/mysql/tests/mysql_server_resource_test.go
index 833e6aa6ea71..645cd296f6a7 100644
--- a/azurerm/internal/services/mysql/tests/mysql_server_resource_test.go
+++ b/azurerm/internal/services/mysql/tests/mysql_server_resource_test.go
@@ -3,6 +3,7 @@ package tests
 import (
 	"fmt"
 	"testing"
+	"time"
 
 	"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
 	"github.com/hashicorp/terraform-plugin-sdk/terraform"
@@ -20,7 +21,7 @@ func TestAccAzureRMMySQLServer_basicFiveSix(t *testing.T) {
 		CheckDestroy: testCheckAzureRMMySQLServerDestroy,
 		Steps: []resource.TestStep{
 			{
-				Config: testAccAzureRMMySQLServer_basicFiveSix(data),
+				Config: testAccAzureRMMySQLServer_basic(data, "5.6"),
 				Check: resource.ComposeTestCheckFunc(
 					testCheckAzureRMMySQLServerExists(data.ResourceName),
 				),
@@ -30,7 +31,7 @@ func TestAccAzureRMMySQLServer_basicFiveSix(t *testing.T) {
 	})
 }
 
-func TestAccAzureRMMySQLServer_disablePublicNetworkAccess(t *testing.T) {
+func TestAccAzureRMMySQLServer_basicFiveSixDeprecated(t *testing.T) { // remove in v3.0
 	data := acceptance.BuildTestData(t, "azurerm_mysql_server", "test")
 
 	resource.ParallelTest(t, resource.TestCase{
@@ -39,7 +40,7 @@ func TestAccAzureRMMySQLServer_disablePublicNetworkAccess(t *testing.T) {
 		CheckDestroy: testCheckAzureRMMySQLServerDestroy,
 		Steps: []resource.TestStep{
 			{
-				Config: testAccAzureRMMySQLServer_disablePublicNetworkAccess(data),
+				Config: testAccAzureRMMySQLServer_basicDeprecated(data, "5.6"),
 				Check: resource.ComposeTestCheckFunc(
 					testCheckAzureRMMySQLServerExists(data.ResourceName),
 				),
@@ -49,7 +50,7 @@ func TestAccAzureRMMySQLServer_disablePublicNetworkAccess(t *testing.T) {
 	})
 }
 
-func TestAccAzureRMMySQLServer_requiresImport(t *testing.T) {
+func TestAccAzureRMMySQLServer_basicFiveSeven(t *testing.T) {
 	data := acceptance.BuildTestData(t, "azurerm_mysql_server", "test")
 
 	resource.ParallelTest(t, resource.TestCase{
@@ -58,21 +59,38 @@ func TestAccAzureRMMySQLServer_requiresImport(t *testing.T) {
 		CheckDestroy: testCheckAzureRMMySQLServerDestroy,
 		Steps: []resource.TestStep{
 			{
-				Config: testAccAzureRMMySQLServer_basicFiveSevenUpdated(data),
+				Config: testAccAzureRMMySQLServer_basic(data, "5.7"),
 				Check: resource.ComposeTestCheckFunc(
 					testCheckAzureRMMySQLServerExists(data.ResourceName),
 				),
 			},
+			data.ImportStep("administrator_login_password"), // not returned as sensitive
+		},
+	})
+}
+
+func TestAccAzureRMMySQLServer_basicEightZero(t *testing.T) {
+	data := acceptance.BuildTestData(t, "azurerm_mysql_server", "test")
+
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck:     func() { acceptance.PreCheck(t) },
+		Providers:    acceptance.SupportedProviders,
+		CheckDestroy: testCheckAzureRMMySQLServerDestroy,
+		Steps: []resource.TestStep{
 			{
-				Config:      testAccAzureRMMySQLServer_requiresImport(data),
-				ExpectError: acceptance.RequiresImportError("azurerm_mysql_server"),
+				Config: testAccAzureRMMySQLServer_basic(data, "8.0"),
+				Check: resource.ComposeTestCheckFunc(
+					testCheckAzureRMMySQLServerExists(data.ResourceName),
+				),
 			},
+			data.ImportStep("administrator_login_password"), // not returned as sensitive
 		},
 	})
 }
 
-func TestAccAzureRMMySQLServer_basicFiveSeven(t *testing.T) {
+func TestAccAzureRMMySQLServer_autogrowOnly(t *testing.T) {
 	data := acceptance.BuildTestData(t, "azurerm_mysql_server", "test")
+	mysqlVersion := "5.7"
 
 	resource.ParallelTest(t, resource.TestCase{
 		PreCheck:     func() { acceptance.PreCheck(t) },
@@ -80,7 +98,14 @@ func TestAccAzureRMMySQLServer_basicFiveSeven(t *testing.T) {
 		CheckDestroy: testCheckAzureRMMySQLServerDestroy,
 		Steps: []resource.TestStep{
 			{
-				Config: testAccAzureRMMySQLServer_basicFiveSeven(data),
+				Config: testAccAzureRMMySQLServer_autogrow(data, mysqlVersion),
+				Check: resource.ComposeTestCheckFunc(
+					testCheckAzureRMMySQLServerExists(data.ResourceName),
+				),
+			},
+			data.ImportStep("administrator_login_password"), // not returned as sensitive
+			{
+				Config: testAccAzureRMMySQLServer_basic(data, mysqlVersion),
 				Check: resource.ComposeTestCheckFunc(
 					testCheckAzureRMMySQLServerExists(data.ResourceName),
 				),
@@ -90,8 +115,47 @@ func TestAccAzureRMMySQLServer_basicFiveSeven(t *testing.T) {
 	})
 }
 
-func TestAccAzureRMMySQLServer_basicEightZero(t *testing.T) {
+func TestAccAzureRMMySQLServer_requiresImport(t *testing.T) {
+	data := acceptance.BuildTestData(t, "azurerm_mysql_server", "test")
+
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck:     func() { acceptance.PreCheck(t) },
+		Providers:    acceptance.SupportedProviders,
+		CheckDestroy: testCheckAzureRMMySQLServerDestroy,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccAzureRMMySQLServer_basic(data, "5.7"),
+				Check: resource.ComposeTestCheckFunc(
+					testCheckAzureRMMySQLServerExists(data.ResourceName),
+				),
+			},
+			data.RequiresImportErrorStep(testAccAzureRMMySQLServer_requiresImport),
+		},
+	})
+}
+
+func TestAccAzureRMMySQLServer_complete(t *testing.T) {
+	data := acceptance.BuildTestData(t, "azurerm_mysql_server", "test")
+
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck:     func() { acceptance.PreCheck(t) },
+		Providers:    acceptance.SupportedProviders,
+		CheckDestroy: testCheckAzureRMMySQLServerDestroy,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccAzureRMMySQLServer_complete(data, "8.0"),
+				Check: resource.ComposeTestCheckFunc(
+					testCheckAzureRMMySQLServerExists(data.ResourceName),
+				),
+			},
+			data.ImportStep("administrator_login_password"), // not returned as sensitive
+		},
+	})
+}
+
+func TestAccAzureRMMySQLServer_update(t *testing.T) {
 	data := acceptance.BuildTestData(t, "azurerm_mysql_server", "test")
+	mysqlVersion := "8.0"
 
 	resource.ParallelTest(t, resource.TestCase{
 		PreCheck:     func() { acceptance.PreCheck(t) },
@@ -99,7 +163,21 @@ func TestAccAzureRMMySQLServer_basicEightZero(t *testing.T) {
 		CheckDestroy: testCheckAzureRMMySQLServerDestroy,
 		Steps: []resource.TestStep{
 			{
-				Config: testAccAzureRMMySQLServer_basicEightZero(data),
+				Config: testAccAzureRMMySQLServer_basic(data, mysqlVersion),
+				Check: resource.ComposeTestCheckFunc(
+					testCheckAzureRMMySQLServerExists(data.ResourceName),
+				),
+			},
+			data.ImportStep("administrator_login_password"), // not returned as sensitive
+			{
+				Config: testAccAzureRMMySQLServer_complete(data, mysqlVersion),
+				Check: resource.ComposeTestCheckFunc(
+					testCheckAzureRMMySQLServerExists(data.ResourceName),
+				),
+			},
+			data.ImportStep("administrator_login_password"), // not returned as sensitive
+			{
+				Config: testAccAzureRMMySQLServer_basic(data, mysqlVersion),
 				Check: resource.ComposeTestCheckFunc(
 					testCheckAzureRMMySQLServerExists(data.ResourceName),
 				),
@@ -109,8 +187,9 @@ func TestAccAzureRMMySQLServer_basicEightZero(t *testing.T) {
 	})
 }
 
-func TestAccAzureRMMySqlServer_memoryOptimized(t *testing.T) {
+func TestAccAzureRMMySQLServer_completeDeprecatedMigrate(t *testing.T) { // remove in v3.0
 	data := acceptance.BuildTestData(t, "azurerm_mysql_server", "test")
+	mysqlVersion := "5.6"
 
 	resource.ParallelTest(t, resource.TestCase{
 		PreCheck:     func() { acceptance.PreCheck(t) },
@@ -118,17 +197,26 @@ func TestAccAzureRMMySqlServer_memoryOptimized(t *testing.T) {
 		CheckDestroy: testCheckAzureRMMySQLServerDestroy,
 		Steps: []resource.TestStep{
 			{
-				Config: testAccAzureRMMySQLServer_memoryOptimizedGeoRedundant(data),
+				Config: testAccAzureRMMySQLServer_completeDeprecated(data, mysqlVersion),
+				Check: resource.ComposeTestCheckFunc(
+					testCheckAzureRMMySQLServerExists(data.ResourceName),
+				),
+			},
+			data.ImportStep("administrator_login_password"), // not returned as sensitive
+			{
+				Config: testAccAzureRMMySQLServer_complete(data, mysqlVersion),
 				Check: resource.ComposeTestCheckFunc(
 					testCheckAzureRMMySQLServerExists(data.ResourceName),
 				),
-			}, data.ImportStep("administrator_login_password"), // not returned as sensitive
+			},
+			data.ImportStep("administrator_login_password"), // not returned as sensitive
 		},
 	})
 }
 
-func TestAccAzureRMMySQLServer_basicFiveSevenUpdated(t *testing.T) {
+func TestAccAzureRMMySQLServer_updateDeprecated(t *testing.T) { // remove in v3.0
 	data := acceptance.BuildTestData(t, "azurerm_mysql_server", "test")
+	mysqlVersion := "5.6"
 
 	resource.ParallelTest(t, resource.TestCase{
 		PreCheck:     func() { acceptance.PreCheck(t) },
@@ -136,23 +224,23 @@ func TestAccAzureRMMySQLServer_basicFiveSevenUpdated(t *testing.T) {
 		CheckDestroy: testCheckAzureRMMySQLServerDestroy,
 		Steps: []resource.TestStep{
 			{
-				Config: testAccAzureRMMySQLServer_basicFiveSeven(data),
+				Config: testAccAzureRMMySQLServer_basicDeprecated(data, mysqlVersion),
+				Check: resource.ComposeTestCheckFunc(
+					testCheckAzureRMMySQLServerExists(data.ResourceName),
+				),
+			},
+			data.ImportStep("administrator_login_password"), // not returned as sensitive
+			{
+				Config: testAccAzureRMMySQLServer_completeDeprecated(data, mysqlVersion),
 				Check: resource.ComposeTestCheckFunc(
 					testCheckAzureRMMySQLServerExists(data.ResourceName),
-					resource.TestCheckResourceAttr(data.ResourceName, "sku_name", "GP_Gen5_2"),
-					resource.TestCheckResourceAttr(data.ResourceName, "version", "5.7"),
-					resource.TestCheckResourceAttr(data.ResourceName, "storage_profile.0.storage_mb", "51200"),
-					resource.TestCheckResourceAttr(data.ResourceName, "administrator_login", "acctestun"),
 				),
 			},
+			data.ImportStep("administrator_login_password"), // not returned as sensitive
 			{
-				Config: testAccAzureRMMySQLServer_basicFiveSevenUpdated(data),
+				Config: testAccAzureRMMySQLServer_basicDeprecated(data, mysqlVersion),
 				Check: resource.ComposeTestCheckFunc(
 					testCheckAzureRMMySQLServerExists(data.ResourceName),
-					resource.TestCheckResourceAttr(data.ResourceName, "sku_name", "GP_Gen5_4"),
-					resource.TestCheckResourceAttr(data.ResourceName, "version", "5.7"),
-					resource.TestCheckResourceAttr(data.ResourceName, "storage_profile.0.storage_mb", "640000"),
-					resource.TestCheckResourceAttr(data.ResourceName, "administrator_login", "acctestun"),
 				),
 			},
 			data.ImportStep("administrator_login_password"), // not returned as sensitive
@@ -169,29 +257,26 @@ func TestAccAzureRMMySQLServer_updateSKU(t *testing.T) {
 		CheckDestroy: testCheckAzureRMMySQLServerDestroy,
 		Steps: []resource.TestStep{
 			{
-				Config: testAccAzureRMMySQLServer_basicEightZero(data),
+				Config: testAccAzureRMMySQLServer_sku(data, "GP_Gen5_2"),
 				Check: resource.ComposeTestCheckFunc(
 					testCheckAzureRMMySQLServerExists(data.ResourceName),
-					resource.TestCheckResourceAttr(data.ResourceName, "sku_name", "GP_Gen5_2"),
-					resource.TestCheckResourceAttr(data.ResourceName, "storage_profile.0.storage_mb", "51200"),
-					resource.TestCheckResourceAttr(data.ResourceName, "administrator_login", "acctestun"),
 				),
 			},
+			data.ImportStep("administrator_login_password"), // not returned as sensitive
 			{
-				Config: testAccAzureRMMySQLServer_basicFiveSevenUpdated(data),
+				Config: testAccAzureRMMySQLServer_sku(data, "MO_Gen5_16"),
 				Check: resource.ComposeTestCheckFunc(
 					testCheckAzureRMMySQLServerExists(data.ResourceName),
-					resource.TestCheckResourceAttr(data.ResourceName, "sku_name", "GP_Gen5_4"),
-					resource.TestCheckResourceAttr(data.ResourceName, "storage_profile.0.storage_mb", "4194304"),
-					resource.TestCheckResourceAttr(data.ResourceName, "administrator_login", "acctestun"),
 				),
 			},
+			data.ImportStep("administrator_login_password"), // not returned as sensitive
 		},
 	})
 }
 
-func TestAccAzureRMMySQLServer_storageAutogrow(t *testing.T) {
+func TestAccAzureRMMySQLServer_createReplica(t *testing.T) {
 	data := acceptance.BuildTestData(t, "azurerm_mysql_server", "test")
+	mysqlVersion := "8.0"
 
 	resource.ParallelTest(t, resource.TestCase{
 		PreCheck:     func() { acceptance.PreCheck(t) },
@@ -199,24 +284,53 @@ func TestAccAzureRMMySQLServer_storageAutogrow(t *testing.T) {
 		CheckDestroy: testCheckAzureRMMySQLServerDestroy,
 		Steps: []resource.TestStep{
 			{
-				Config: testAccAzureRMMySQLServer_basicFiveSeven(data),
+				Config: testAccAzureRMMySQLServer_basic(data, mysqlVersion),
 				Check: resource.ComposeTestCheckFunc(
 					testCheckAzureRMMySQLServerExists(data.ResourceName),
-					resource.TestCheckResourceAttr(data.ResourceName, "storage_profile.0.auto_grow", "Enabled"),
 				),
 			},
+			data.ImportStep("administrator_login_password"),
 			{
-				Config: testAccAzureRMMySQLServer_autogrow(data),
+				Config: testAccAzureRMMySQLServer_createReplica(data, mysqlVersion),
 				Check: resource.ComposeTestCheckFunc(
 					testCheckAzureRMMySQLServerExists(data.ResourceName),
-					resource.TestCheckResourceAttr(data.ResourceName, "storage_profile.0.auto_grow", "Disabled"),
+					testCheckAzureRMMySQLServerExists("azurerm_mysql_server.replica"),
 				),
 			},
+			data.ImportStep("administrator_login_password"),
 		},
 	})
 }
 
-//
+func TestAccAzureRMMySQLServer_createPointInTimeRestore(t *testing.T) {
+	data := acceptance.BuildTestData(t, "azurerm_mysql_server", "test")
+	restoreTime := time.Now().Add(11 * time.Minute)
+	mysqlVersion := "8.0"
+
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck:     func() { acceptance.PreCheck(t) },
+		Providers:    acceptance.SupportedProviders,
+		CheckDestroy: testCheckAzureRMMySQLServerDestroy,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccAzureRMMySQLServer_basic(data, mysqlVersion),
+				Check: resource.ComposeTestCheckFunc(
+					testCheckAzureRMMySQLServerExists(data.ResourceName),
+				),
+			},
+			data.ImportStep("administrator_login_password"),
+			{
+				PreConfig: func() { time.Sleep(restoreTime.Sub(time.Now().Add(-7 * time.Minute))) },
+				Config:    testAccAzureRMMySQLServer_createPointInTimeRestore(data, mysqlVersion, restoreTime.Format(time.RFC3339)),
+				Check: resource.ComposeTestCheckFunc(
+					testCheckAzureRMMySQLServerExists(data.ResourceName),
+					testCheckAzureRMMySQLServerExists("azurerm_mysql_server.restore"),
+				),
+			},
+			data.ImportStep("administrator_login_password"),
+		},
+	})
+}
 
 func testCheckAzureRMMySQLServerExists(resourceName string) resource.TestCheckFunc {
 	return func(s *terraform.State) error {
@@ -273,7 +387,7 @@ func testCheckAzureRMMySQLServerDestroy(s *terraform.State) error {
 	return nil
 }
 
-func testAccAzureRMMySQLServer_basicFiveSix(data acceptance.TestData) string {
+func testAccAzureRMMySQLServer_basic(data acceptance.TestData, version string) string {
 	return fmt.Sprintf(`
 provider "azurerm" {
   features {}
@@ -285,27 +399,20 @@ resource "azurerm_resource_group" "test" {
 }
 
 resource "azurerm_mysql_server" "test" {
-  name                = "acctestmysqlsvr-%d"
-  location            = azurerm_resource_group.test.location
-  resource_group_name = azurerm_resource_group.test.name
-
-  sku_name = "GP_Gen5_2"
-
-  storage_profile {
-    storage_mb            = 51200
-    backup_retention_days = 7
-    geo_redundant_backup  = "Disabled"
-  }
-
+  name                         = "acctestmysqlsvr-%d"
+  location                     = azurerm_resource_group.test.location
+  resource_group_name          = azurerm_resource_group.test.name
+  sku_name                     = "GP_Gen5_2"
   administrator_login          = "acctestun"
   administrator_login_password = "H@Sh1CoR3!"
-  version                      = "5.6"
-  ssl_enforcement              = "Enabled"
+  ssl_enforcement_enabled      = true
+  storage_mb                   = 51200
+  version                      = "%s"
 }
-`, data.RandomInteger, data.Locations.Primary, data.RandomInteger)
+`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, version)
 }
 
-func testAccAzureRMMySQLServer_disablePublicNetworkAccess(data acceptance.TestData) string {
+func testAccAzureRMMySQLServer_basicDeprecated(data acceptance.TestData, version string) string { // remove in v3.0
 	return fmt.Sprintf(`
 provider "azurerm" {
   features {}
@@ -324,21 +431,18 @@ resource "azurerm_mysql_server" "test" {
   sku_name = "GP_Gen5_2"
 
   storage_profile {
-    storage_mb            = 51200
-    backup_retention_days = 7
-    geo_redundant_backup  = "Disabled"
+    storage_mb = 51200
   }
 
-  administrator_login           = "acctestun"
-  administrator_login_password  = "H@Sh1CoR3!"
-  version                       = "5.6"
-  ssl_enforcement               = "Enabled"
-  public_network_access_enabled = false
+  administrator_login          = "acctestun"
+  administrator_login_password = "H@Sh1CoR3!"
+  version                      = "%s"
+  ssl_enforcement              = "Enabled"
 }
-`, data.RandomInteger, data.Locations.Primary, data.RandomInteger)
+`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, version)
 }
 
-func testAccAzureRMMySQLServer_basicFiveSeven(data acceptance.TestData) string {
+func testAccAzureRMMySQLServer_complete(data acceptance.TestData, version string) string {
 	return fmt.Sprintf(`
 provider "azurerm" {
   features {}
@@ -350,27 +454,24 @@ resource "azurerm_resource_group" "test" {
 }
 
 resource "azurerm_mysql_server" "test" {
-  name                = "acctestmysqlsvr-%d"
-  location            = azurerm_resource_group.test.location
-  resource_group_name = azurerm_resource_group.test.name
-
-  sku_name = "GP_Gen5_2"
-
-  storage_profile {
-    storage_mb            = 51200
-    backup_retention_days = 7
-    geo_redundant_backup  = "Disabled"
-  }
-
+  name                         = "acctestmysqlsvr-%d"
+  location                     = azurerm_resource_group.test.location
+  resource_group_name          = azurerm_resource_group.test.name
+  sku_name                     = "GP_Gen5_2"
   administrator_login          = "acctestun"
   administrator_login_password = "H@Sh1CoR3!"
-  version                      = "5.7"
-  ssl_enforcement              = "Enabled"
+  auto_grow_enabled            = true
+  backup_retention_days        = 7
+  create_mode                  = "Default"
+  geo_redundant_backup_enabled = false
+  ssl_enforcement_enabled      = true
+  storage_mb                   = 51200
+  version                      = "%s"
 }
-`, data.RandomInteger, data.Locations.Primary, data.RandomInteger)
+`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, version)
 }
 
-func testAccAzureRMMySQLServer_basicEightZero(data acceptance.TestData) string {
+func testAccAzureRMMySQLServer_completeDeprecated(data acceptance.TestData, version string) string { // remove in v3.0
 	return fmt.Sprintf(`
 provider "azurerm" {
   features {}
@@ -392,14 +493,15 @@ resource "azurerm_mysql_server" "test" {
     storage_mb            = 51200
     backup_retention_days = 7
     geo_redundant_backup  = "Disabled"
+    auto_grow             = "Enabled"
   }
 
   administrator_login          = "acctestun"
   administrator_login_password = "H@Sh1CoR3!"
-  version                      = "8.0"
+  version                      = "%s"
   ssl_enforcement              = "Enabled"
 }
-`, data.RandomInteger, data.Locations.Primary, data.RandomInteger)
+`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, version)
 }
 
 func testAccAzureRMMySQLServer_requiresImport(data acceptance.TestData) string {
@@ -410,24 +512,20 @@ resource "azurerm_mysql_server" "import" {
   name                = azurerm_mysql_server.test.name
   location            = azurerm_mysql_server.test.location
   resource_group_name = azurerm_mysql_server.test.resource_group_name
-
-  sku_name = "GP_Gen5_2"
-
-  storage_profile {
-    storage_mb            = 51200
-    backup_retention_days = 7
-    geo_redundant_backup  = "Disabled"
-  }
+  sku_name            = "GP_Gen5_2"
+  version             = "5.7"
 
   administrator_login          = "acctestun"
   administrator_login_password = "H@Sh1CoR3!"
-  version                      = "5.7"
-  ssl_enforcement              = "Enabled"
+  backup_retention_days        = 7
+  geo_redundant_backup_enabled = false
+  ssl_enforcement_enabled      = true
+  storage_mb                   = 51200
 }
-`, testAccAzureRMMySQLServer_basicFiveSevenUpdated(data))
+`, testAccAzureRMMySQLServer_basic(data, "5.7"))
 }
 
-func testAccAzureRMMySQLServer_basicFiveSevenUpdated(data acceptance.TestData) string {
+func testAccAzureRMMySQLServer_sku(data acceptance.TestData, sku string) string {
 	return fmt.Sprintf(`
 provider "azurerm" {
   features {}
@@ -442,24 +540,18 @@ resource "azurerm_mysql_server" "test" {
   name                = "acctestmysqlsvr-%d"
   location            = azurerm_resource_group.test.location
   resource_group_name = azurerm_resource_group.test.name
+  sku_name            = "%s"
+  version             = "5.7"
 
-  sku_name = "GP_Gen5_4"
-
-  storage_profile {
-    storage_mb            = 640000
-    backup_retention_days = 7
-    geo_redundant_backup  = "Disabled"
-  }
-
+  storage_mb                   = 4194304
   administrator_login          = "acctestun"
   administrator_login_password = "H@Sh1CoR3!"
-  version                      = "5.7"
-  ssl_enforcement              = "Enabled"
+  ssl_enforcement_enabled      = true
 }
-`, data.RandomInteger, data.Locations.Primary, data.RandomInteger)
+`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, sku)
 }
 
-func testAccAzureRMMySQLServer_memoryOptimizedGeoRedundant(data acceptance.TestData) string {
+func testAccAzureRMMySQLServer_autogrow(data acceptance.TestData, version string) string {
 	return fmt.Sprintf(`
 provider "azurerm" {
   features {}
@@ -474,52 +566,54 @@ resource "azurerm_mysql_server" "test" {
   name                = "acctestmysqlsvr-%d"
   location            = azurerm_resource_group.test.location
   resource_group_name = azurerm_resource_group.test.name
-
-  sku_name = "MO_Gen5_16"
-
-  storage_profile {
-    storage_mb            = 4194304
-    backup_retention_days = 7
-    geo_redundant_backup  = "Enabled"
-  }
+  sku_name            = "GP_Gen5_2"
+  version             = "%s"
 
   administrator_login          = "acctestun"
   administrator_login_password = "H@Sh1CoR3!"
-  version                      = "5.7"
-  ssl_enforcement              = "Enabled"
+  auto_grow_enabled            = true
+  backup_retention_days        = 7
+  geo_redundant_backup_enabled = false
+  ssl_enforcement_enabled      = true
+  storage_mb                   = 51200
 }
-`, data.RandomInteger, data.Locations.Primary, data.RandomInteger)
+`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, version)
 }
 
-func testAccAzureRMMySQLServer_autogrow(data acceptance.TestData) string {
+func testAccAzureRMMySQLServer_createReplica(data acceptance.TestData, version string) string {
 	return fmt.Sprintf(`
-provider "azurerm" {
-  features {}
-}
-
-resource "azurerm_resource_group" "test" {
-  name     = "acctestRG-%d"
-  location = "%s"
-}
+%s
 
-resource "azurerm_mysql_server" "test" {
-  name                = "acctestmysqlsvr-%d"
+resource "azurerm_mysql_server" "replica" {
+  name                = "acctestmysqlsvr-%d-replica"
   location            = azurerm_resource_group.test.location
   resource_group_name = azurerm_resource_group.test.name
+  sku_name            = "GP_Gen5_2"
+  version             = "%s"
 
-  sku_name = "GP_Gen5_2"
+  create_mode               = "Replica"
+  creation_source_server_id = azurerm_mysql_server.test.id
+  ssl_enforcement_enabled   = true
+}
+`, testAccAzureRMMySQLServer_basic(data, version), data.RandomInteger, version)
+}
 
-  storage_profile {
-    storage_mb            = 51200
-    backup_retention_days = 7
-    geo_redundant_backup  = "Disabled"
-    auto_grow             = "Disabled"
-  }
+func testAccAzureRMMySQLServer_createPointInTimeRestore(data acceptance.TestData, version, restoreTime string) string {
+	return fmt.Sprintf(`
+%s
 
-  administrator_login          = "acctestun"
-  administrator_login_password = "H@Sh1CoR3!"
-  version                      = "5.7"
-  ssl_enforcement              = "Enabled"
+resource "azurerm_mysql_server" "restore" {
+  name                = "acctestmysqlsvr-%d-restore"
+  location            = azurerm_resource_group.test.location
+  resource_group_name = azurerm_resource_group.test.name
+  sku_name            = "GP_Gen5_2"
+  version             = "%s"
+
+  create_mode               = "PointInTimeRestore"
+  creation_source_server_id = azurerm_mysql_server.test.id
+  restore_point_in_time     = "%s"
+  ssl_enforcement_enabled   = true
+  storage_mb                = 51200
 }
-`, data.RandomInteger, data.Locations.Primary, data.RandomInteger)
+`, testAccAzureRMMySQLServer_basic(data, version), data.RandomInteger, version, restoreTime)
 }
diff --git a/azurerm/internal/services/mysql/tests/mysql_virtual_network_rule_resource_test.go b/azurerm/internal/services/mysql/tests/mysql_virtual_network_rule_resource_test.go
index 67824d6c074d..797aea463362 100644
--- a/azurerm/internal/services/mysql/tests/mysql_virtual_network_rule_resource_test.go
+++ b/azurerm/internal/services/mysql/tests/mysql_virtual_network_rule_resource_test.go
@@ -13,66 +13,66 @@ import (
 	"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
 )
 
-func TestAccAzureRMMySqlVirtualNetworkRule_basic(t *testing.T) {
+func TestAccAzureRMMySSQLVirtualNetworkRule_basic(t *testing.T) {
 	data := acceptance.BuildTestData(t, "azurerm_mysql_virtual_network_rule", "test")
 
 	resource.ParallelTest(t, resource.TestCase{
 		PreCheck:     func() { acceptance.PreCheck(t) },
 		Providers:    acceptance.SupportedProviders,
-		CheckDestroy: testCheckAzureRMMySqlVirtualNetworkRuleDestroy,
+		CheckDestroy: testCheckAzureRMMySSQLVirtualNetworkRuleDestroy,
 		Steps: []resource.TestStep{
 			{
-				Config: testAccAzureRMMySqlVirtualNetworkRule_basic(data),
+				Config: testAccAzureRMMySSQLVirtualNetworkRule_basic(data),
 				Check: resource.ComposeTestCheckFunc(
-					testCheckAzureRMMySqlVirtualNetworkRuleExists(data.ResourceName),
+					testCheckAzureRMMySSQLVirtualNetworkRuleExists(data.ResourceName),
 				),
 			},
 		},
 	})
 }
 
-func TestAccAzureRMMySqlVirtualNetworkRule_badsubnet(t *testing.T) {
+func TestAccAzureRMMySSQLVirtualNetworkRule_badsubnet(t *testing.T) {
 	data := acceptance.BuildTestData(t, "azurerm_mysql_virtual_network_rule", "test")
 
 	resource.ParallelTest(t, resource.TestCase{
 		PreCheck:     func() { acceptance.PreCheck(t) },
 		Providers:    acceptance.SupportedProviders,
-		CheckDestroy: testCheckAzureRMMySqlVirtualNetworkRuleDestroy,
+		CheckDestroy: testCheckAzureRMMySSQLVirtualNetworkRuleDestroy,
 		Steps: []resource.TestStep{
 			{
-				Config: testAccAzureRMMySqlVirtualNetworkRule_badsubnet(data),
+				Config: testAccAzureRMMySSQLVirtualNetworkRule_badsubnet(data),
 				/*
 					Check: resource.ComposeTestCheckFunc(
-						testCheckAzureRMMySqlVirtualNetworkRuleExists(data.ResourceName),
+						testCheckAzureRMMySSQLVirtualNetworkRuleExists(data.ResourceName),
 					),*/
 			},
 		},
 	})
 }
 
-func TestAccAzureRMMySqlVirtualNetworkRule_requiresImport(t *testing.T) {
+func TestAccAzureRMMySSQLVirtualNetworkRule_requiresImport(t *testing.T) {
 	data := acceptance.BuildTestData(t, "azurerm_mysql_virtual_network_rule", "test")
 
 	resource.ParallelTest(t, resource.TestCase{
 		PreCheck:     func() { acceptance.PreCheck(t) },
 		Providers:    acceptance.SupportedProviders,
-		CheckDestroy: testCheckAzureRMMySqlVirtualNetworkRuleDestroy,
+		CheckDestroy: testCheckAzureRMMySSQLVirtualNetworkRuleDestroy,
 		Steps: []resource.TestStep{
 			{
-				Config: testAccAzureRMMySqlVirtualNetworkRule_basic(data),
+				Config: testAccAzureRMMySSQLVirtualNetworkRule_basic(data),
 				Check: resource.ComposeTestCheckFunc(
-					testCheckAzureRMMySqlVirtualNetworkRuleExists(data.ResourceName),
+					testCheckAzureRMMySSQLVirtualNetworkRuleExists(data.ResourceName),
 				),
 			},
 			{
-				Config:      testAccAzureRMMySqlVirtualNetworkRule_requiresImport(data),
+				Config:      testAccAzureRMMySSQLVirtualNetworkRule_requiresImport(data),
 				ExpectError: acceptance.RequiresImportError("azurerm_mysql_virtual_network_rule"),
 			},
 		},
 	})
 }
 
-func TestAccAzureRMMySqlVirtualNetworkRule_switchSubnets(t *testing.T) {
+func TestAccAzureRMMySSQLVirtualNetworkRule_switchSubnets(t *testing.T) {
 	data := acceptance.BuildTestData(t, "azurerm_mysql_virtual_network_rule", "test")
 
 	// Create regex strings that will ensure that one subnet name exists, but not the other
@@ -82,19 +82,19 @@ func TestAccAzureRMMySqlVirtualNetworkRule_switchSubnets(t *testing.T) {
 	resource.ParallelTest(t, resource.TestCase{
 		PreCheck:     func() { acceptance.PreCheck(t) },
 		Providers:    acceptance.SupportedProviders,
-		CheckDestroy: testCheckAzureRMMySqlVirtualNetworkRuleDestroy,
+		CheckDestroy: testCheckAzureRMMySSQLVirtualNetworkRuleDestroy,
 		Steps: []resource.TestStep{
 			{
-				Config: testAccAzureRMMySqlVirtualNetworkRule_subnetSwitchPre(data),
+				Config: testAccAzureRMMySSQLVirtualNetworkRule_subnetSwitchPre(data),
 				Check: resource.ComposeTestCheckFunc(
-					testCheckAzureRMMySqlVirtualNetworkRuleExists(data.ResourceName),
+					testCheckAzureRMMySSQLVirtualNetworkRuleExists(data.ResourceName),
 					resource.TestMatchResourceAttr(data.ResourceName, "subnet_id", preConfigRegex),
 				),
 			},
 			{
-				Config: testAccAzureRMMySqlVirtualNetworkRule_subnetSwitchPost(data),
+				Config: testAccAzureRMMySSQLVirtualNetworkRule_subnetSwitchPost(data),
 				Check: resource.ComposeTestCheckFunc(
-					testCheckAzureRMMySqlVirtualNetworkRuleExists(data.ResourceName),
+					testCheckAzureRMMySSQLVirtualNetworkRuleExists(data.ResourceName),
 					resource.TestMatchResourceAttr(data.ResourceName, "subnet_id", postConfigRegex),
 				),
 			},
@@ -102,19 +102,19 @@ func TestAccAzureRMMySqlVirtualNetworkRule_switchSubnets(t *testing.T) {
 	})
 }
 
-func TestAccAzureRMMySqlVirtualNetworkRule_disappears(t *testing.T) {
+func TestAccAzureRMMySSQLVirtualNetworkRule_disappears(t *testing.T) {
 	data := acceptance.BuildTestData(t, "azurerm_mysql_virtual_network_rule", "test")
 
 	resource.ParallelTest(t, resource.TestCase{
 		PreCheck:     func() { acceptance.PreCheck(t) },
 		Providers:    acceptance.SupportedProviders,
-		CheckDestroy: testCheckAzureRMMySqlVirtualNetworkRuleDestroy,
+		CheckDestroy: testCheckAzureRMMySSQLVirtualNetworkRuleDestroy,
 		Steps: []resource.TestStep{
 			{
-				Config: testAccAzureRMMySqlVirtualNetworkRule_basic(data),
+				Config: testAccAzureRMMySSQLVirtualNetworkRule_basic(data),
 				Check: resource.ComposeTestCheckFunc(
-					testCheckAzureRMMySqlVirtualNetworkRuleExists(data.ResourceName),
-					testCheckAzureRMMySqlVirtualNetworkRuleDisappears(data.ResourceName),
+					testCheckAzureRMMySSQLVirtualNetworkRuleExists(data.ResourceName),
+					testCheckAzureRMMySSQLVirtualNetworkRuleDisappears(data.ResourceName),
 				),
 				ExpectNonEmptyPlan: true,
 			},
@@ -122,7 +122,7 @@ func TestAccAzureRMMySqlVirtualNetworkRule_disappears(t *testing.T) {
 	})
 }
 
-func TestAccAzureRMMySqlVirtualNetworkRule_multipleSubnets(t *testing.T) {
+func TestAccAzureRMMySSQLVirtualNetworkRule_multipleSubnets(t *testing.T) {
 	data := acceptance.BuildTestData(t, "azurerm_mysql_virtual_network_rule", "rule1")
 
 	resourceName2 := "azurerm_mysql_virtual_network_rule.rule2"
@@ -131,21 +131,21 @@ func TestAccAzureRMMySqlVirtualNetworkRule_multipleSubnets(t *testing.T) {
 	resource.ParallelTest(t, resource.TestCase{
 		PreCheck:     func() { acceptance.PreCheck(t) },
 		Providers:    acceptance.SupportedProviders,
-		CheckDestroy: testCheckAzureRMMySqlVirtualNetworkRuleDestroy,
+		CheckDestroy: testCheckAzureRMMySSQLVirtualNetworkRuleDestroy,
 		Steps: []resource.TestStep{
 			{
-				Config: testAccAzureRMMySqlVirtualNetworkRule_multipleSubnets(data),
+				Config: testAccAzureRMMySSQLVirtualNetworkRule_multipleSubnets(data),
 				Check: resource.ComposeTestCheckFunc(
-					testCheckAzureRMMySqlVirtualNetworkRuleExists(data.ResourceName),
-					testCheckAzureRMMySqlVirtualNetworkRuleExists(resourceName2),
-					testCheckAzureRMMySqlVirtualNetworkRuleExists(resourceName3),
+					testCheckAzureRMMySSQLVirtualNetworkRuleExists(data.ResourceName),
+					testCheckAzureRMMySSQLVirtualNetworkRuleExists(resourceName2),
+					testCheckAzureRMMySSQLVirtualNetworkRuleExists(resourceName3),
 				),
 			},
 		},
 	})
 }
 
-func testCheckAzureRMMySqlVirtualNetworkRuleExists(resourceName string) resource.TestCheckFunc {
+func testCheckAzureRMMySSQLVirtualNetworkRuleExists(resourceName string) resource.TestCheckFunc {
 	return func(s *terraform.State) error {
 		client := acceptance.AzureProvider.Meta().(*clients.Client).MySQL.VirtualNetworkRulesClient
 		ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext
@@ -172,7 +172,7 @@ func testCheckAzureRMMySqlVirtualNetworkRuleExists(resourceName string) resource
 	}
 }
 
-func testCheckAzureRMMySqlVirtualNetworkRuleDestroy(s *terraform.State) error {
+func testCheckAzureRMMySSQLVirtualNetworkRuleDestroy(s *terraform.State) error {
 	client := acceptance.AzureProvider.Meta().(*clients.Client).MySQL.VirtualNetworkRulesClient
 	ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext
 
@@ -200,7 +200,7 @@ func testCheckAzureRMMySqlVirtualNetworkRuleDestroy(s *terraform.State) error {
 	return nil
 }
 
-func testCheckAzureRMMySqlVirtualNetworkRuleDisappears(resourceName string) resource.TestCheckFunc {
+func testCheckAzureRMMySSQLVirtualNetworkRuleDisappears(resourceName string) resource.TestCheckFunc {
 	return func(s *terraform.State) error {
 		client := acceptance.AzureProvider.Meta().(*clients.Client).MySQL.VirtualNetworkRulesClient
 		ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext
@@ -239,7 +239,7 @@ func testCheckAzureRMMySqlVirtualNetworkRuleDisappears(resourceName string) reso
 	}
 }
 
-func testAccAzureRMMySqlVirtualNetworkRule_basic(data acceptance.TestData) string {
+func testAccAzureRMMySSQLVirtualNetworkRule_basic(data acceptance.TestData) string {
 	return fmt.Sprintf(`
 provider "azurerm" {
   features {}
@@ -292,7 +292,7 @@ resource "azurerm_mysql_virtual_network_rule" "test" {
 `, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger, data.RandomInteger, data.RandomInteger)
 }
 
-func testAccAzureRMMySqlVirtualNetworkRule_badsubnet(data acceptance.TestData) string {
+func testAccAzureRMMySSQLVirtualNetworkRule_badsubnet(data acceptance.TestData) string {
 	return fmt.Sprintf(`
 provider "azurerm" {
   features {}
@@ -345,7 +345,7 @@ resource "azurerm_mysql_virtual_network_rule" "test" {
 `, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger, data.RandomInteger, data.RandomInteger)
 }
 
-func testAccAzureRMMySqlVirtualNetworkRule_requiresImport(data acceptance.TestData) string {
+func testAccAzureRMMySSQLVirtualNetworkRule_requiresImport(data acceptance.TestData) string {
 	return fmt.Sprintf(`
 %s
 
@@ -355,10 +355,10 @@ resource "azurerm_mysql_virtual_network_rule" "import" {
   server_name         = azurerm_mysql_virtual_network_rule.test.server_name
   subnet_id           = azurerm_mysql_virtual_network_rule.test.subnet_id
 }
-`, testAccAzureRMMySqlVirtualNetworkRule_basic(data))
+`, testAccAzureRMMySSQLVirtualNetworkRule_basic(data))
 }
 
-func testAccAzureRMMySqlVirtualNetworkRule_subnetSwitchPre(data acceptance.TestData) string {
+func testAccAzureRMMySSQLVirtualNetworkRule_subnetSwitchPre(data acceptance.TestData) string {
 	return fmt.Sprintf(`
 provider "azurerm" {
   features {}
@@ -419,7 +419,7 @@ resource "azurerm_mysql_virtual_network_rule" "test" {
 `, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger, data.RandomInteger, data.RandomInteger, data.RandomInteger)
 }
 
-func testAccAzureRMMySqlVirtualNetworkRule_subnetSwitchPost(data acceptance.TestData) string {
+func testAccAzureRMMySSQLVirtualNetworkRule_subnetSwitchPost(data acceptance.TestData) string {
 	return fmt.Sprintf(`
 provider "azurerm" {
   features {}
@@ -480,7 +480,7 @@ resource "azurerm_mysql_virtual_network_rule" "test" {
 `, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger, data.RandomInteger, data.RandomInteger, data.RandomInteger)
 }
 
-func testAccAzureRMMySqlVirtualNetworkRule_multipleSubnets(data acceptance.TestData) string {
+func testAccAzureRMMySSQLVirtualNetworkRule_multipleSubnets(data acceptance.TestData) string {
 	return fmt.Sprintf(`
 provider "azurerm" {
   features {}
diff --git a/azurerm/internal/services/mysql/validate/mysql.go b/azurerm/internal/services/mysql/validate/mysql.go
new file mode 100644
index 000000000000..e5abee8309ba
--- /dev/null
+++ b/azurerm/internal/services/mysql/validate/mysql.go
@@ -0,0 +1,30 @@
+package validate
+
+import (
+	"fmt"
+
+	"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate"
+	"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/mysql/parse"
+)
+
+func MysqlServerServerID(i interface{}, k string) (warnings []string, errors []error) {
+	v, ok := i.(string)
+	if !ok {
+		errors = append(errors, fmt.Errorf("expected type of %q to be string", k))
+		return warnings, errors
+	}
+
+	if _, err := parse.MysqlServerServerID(v); err != nil {
+		errors = append(errors, fmt.Errorf("Can not parse %q as a MySQL Server resource id: %v", k, err))
+	}
+
+	return warnings, errors
+}
+
+func MysqlServerServerName(i interface{}, k string) (_ []string, errors []error) {
+	if m, regexErrs := validate.RegExHelper(i, k, `^[0-9a-z][-0-9a-z]{1,61}[0-9a-z]$`); !m {
+		return nil, append(regexErrs, fmt.Errorf("%q can contain only lowercase letters, numbers, and '-', but can't start or end with '-', and must be at least 3 characters and no more than 63 characters long.", k))
+	}
+
+	return nil, nil
+}
diff --git a/azurerm/internal/services/mysql/validate/mysql_test.go b/azurerm/internal/services/mysql/validate/mysql_test.go
new file mode 100644
index 000000000000..3e919164fb37
--- /dev/null
+++ b/azurerm/internal/services/mysql/validate/mysql_test.go
@@ -0,0 +1,106 @@
+package validate
+
+import (
+	"testing"
+)
+
+func TestValidateMysqlServerServerID(t *testing.T) {
+	testData := []struct {
+		input    string
+		expected bool
+	}{
+		{
+			// empty
+			input:    "",
+			expected: false,
+		},
+		{
+			// invalid
+			input:    "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
+			expected: false,
+		},
+		{
+			// valid
+			input:    "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.DBforMySQL/servers/test-mysql",
+			expected: true,
+		},
+	}
+
+	for _, v := range testData {
+		t.Logf("[DEBUG] Testing %q..", v.input)
+
+		_, errors := MysqlServerServerID(v.input, "name")
+		actual := len(errors) == 0
+		if v.expected != actual {
+			t.Fatalf("Expected %t but got %t", v.expected, actual)
+		}
+	}
+}
+
+func TestValidateMysqlServerServerName(t *testing.T) {
+	testData := []struct {
+		input    string
+		expected bool
+	}{
+		{
+			// empty
+			input:    "",
+			expected: false,
+		},
+		{
+			// basic example
+			input:    "ab-c",
+			expected: true,
+		},
+		{
+			// can't contain upper case letter
+			input:    "AbcD",
+			expected: false,
+		},
+		{
+			// can't start with a hyphen
+			input:    "-abc",
+			expected: false,
+		},
+		{
+			// can't contain underscore
+			input:    "ab_c",
+			expected: false,
+		},
+		{
+			// can't end with hyphen
+			input:    "abc-",
+			expected: false,
+		},
+		{
+			// can not be shorter than 3 characters
+			input:    "ab",
+			expected: false,
+		},
+		{
+			// can not be shorter than 3 characters (catching bad regex)
+			input:    "a",
+			expected: false,
+		},
+		{
+			// 63 chars
+			input:    "abcdefghijklmnopqrstuvwxyzabcdefabcdefghijklmnopqrstuvwxyzabcde",
+			expected: true,
+		},
+		{
+			// 64 chars
+			input:    "abcdefghijklmnopqrstuvwxyzabcdefabcdefghijklmnopqrstuvwxyzabcdef",
+			expected: false,
+		},
+	}
+
+	for _, v := range testData {
+		t.Logf("[DEBUG] Testing %q..", v.input)
+
+		_, errors := MysqlServerServerName(v.input, "name")
+		actual := len(errors) == 0
+		if v.expected != actual {
+			t.Fatalf("Expected %t but got %t", v.expected, actual)
+		}
+	}
+}
diff --git a/azurerm/internal/services/postgres/parse/postgres_test.go b/azurerm/internal/services/postgres/parse/postgres_test.go
index b3b2dcc1fb6b..ae2dfa439205 100644
--- a/azurerm/internal/services/postgres/parse/postgres_test.go
+++ b/azurerm/internal/services/postgres/parse/postgres_test.go
@@ -32,7 +32,7 @@ func TestAnalysisServicesServerId(t *testing.T) {
 		},
 		{
 			Name:     "Missing Servers Value",
-			Input:    "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.Web/servers/",
+			Input:    "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resGroup1/providers/Microsoft.DBforPostgreSQL/servers/",
 			Expected: nil,
 		},
 		{
diff --git a/azurerm/internal/services/postgres/postgresql_server_resource.go b/azurerm/internal/services/postgres/postgresql_server_resource.go
index 7f8cc2c45208..f9d1eeb3e24f 100644
--- a/azurerm/internal/services/postgres/postgresql_server_resource.go
+++ b/azurerm/internal/services/postgres/postgresql_server_resource.go
@@ -531,15 +531,15 @@ func resourceArmPostgreSQLServerRead(d *schema.ResourceData, meta interface{}) e
 	d.Set("name", resp.Name)
 	d.Set("resource_group_name", id.ResourceGroup)
 
+	if location := resp.Location; location != nil {
+		d.Set("location", azure.NormalizeLocation(*location))
+	}
+
 	if sku := resp.Sku; sku != nil {
 		d.Set("sku_name", sku.Name)
 	}
 
 	if props := resp.ServerProperties; props != nil {
-		if location := resp.Location; location != nil {
-			d.Set("location", azure.NormalizeLocation(*location))
-		}
-
 		d.Set("administrator_login", props.AdministratorLogin)
 		d.Set("ssl_enforcement", string(props.SslEnforcement))
 		d.Set("ssl_minimal_tls_version_enforced", props.MinimalTLSVersion)
diff --git a/website/docs/r/mysql_server.html.markdown b/website/docs/r/mysql_server.html.markdown
index 725ee963c2c6..c205512f5a12 100644
--- a/website/docs/r/mysql_server.html.markdown
+++ b/website/docs/r/mysql_server.html.markdown
@@ -14,28 +14,34 @@ Manages a MySQL Server.
 ## Example Usage
 
 ```hcl
+provider "azurerm" {
+  features {}
+}
+
 resource "azurerm_resource_group" "example" {
-  name     = "api-rg-pro"
+  name     = "example-resources"
   location = "West Europe"
 }
 
 resource "azurerm_mysql_server" "example" {
-  name                = "mysql-server-1"
+  name                = "example-mysqlserver"
   location            = azurerm_resource_group.example.location
   resource_group_name = azurerm_resource_group.example.name
 
-  sku_name = "B_Gen5_2"
-
-  storage_profile {
-    storage_mb            = 5120
-    backup_retention_days = 7
-    geo_redundant_backup  = "Disabled"
-  }
-
   administrator_login          = "mysqladminun"
   administrator_login_password = "H@Sh1CoR3!"
-  version                      = "5.7"
-  ssl_enforcement              = "Enabled"
+
+  sku_name   = "B_Gen5_2"
+  storage_mb = 5120
+  version    = "5.7"
+
+  auto_grow_enabled                 = true
+  backup_retention_days             = 7
+  geo_redundant_backup_enabled      = true
+  infrastructure_encryption_enabled = true
+  public_network_access_enabled     = false
+  ssl_enforcement_enabled           = true
+  ssl_minimal_tls_version_enforced  = "TLS1_2"
 }
 ```
 
@@ -51,31 +57,35 @@ The following arguments are supported:
 
 * `sku_name` - (Required) Specifies the SKU Name for this MySQL Server. The name of the SKU, follows the `tier` + `family` + `cores` pattern (e.g. `B_Gen4_1`, `GP_Gen5_8`). For more information see the [product documentation](https://docs.microsoft.com/en-us/rest/api/mysql/servers/create#sku).
 
-* `storage_profile` - (Required) A `storage_profile` block as defined below.
+* `version` - (Required) Specifies the version of MySQL to use. Valid values are `5.6`, `5.7`, and `8.0`. Changing this forces a new resource to be created.
+
+* `administrator_login` - (Optional) The Administrator Login for the MySQL Server. Required when `create_mode` is `Default`. Changing this forces a new resource to be created.
 
-* `administrator_login` - (Required) The Administrator Login for the MySQL Server. Changing this forces a new resource to be created.
+* `administrator_login_password` - (Optional) The Password associated with the `administrator_login` for the MySQL Server. Required when `create_mode` is `Default`.
 
-* `administrator_login_password` - (Required) The Password associated with the `administrator_login` for the MySQL Server.
+* `auto_grow_enabled` - (Optional) Enable/Disable auto-growing of the storage. Storage auto-grow prevents your server from running out of storage and becoming read-only. If storage auto grow is enabled, the storage automatically grows without impacting the workload. The default value if not explicitly specified is `true`.
 
-* `version` - (Required) Specifies the version of MySQL to use. Valid values are `5.6`, `5.7`, and `8.0`. Changing this forces a new resource to be created.
+* `backup_retention_days` - (Optional) Backup retention days for the server, supported values are between `7` and `35` days.
 
-* `ssl_enforcement` - (Required) Specifies if SSL should be enforced on connections. Possible values are `Enabled` and `Disabled`.
+* `create_mode` - (Optional) The creation mode. Can be used to restore or replicate existing servers. Possible values are `Default`, `Replica`, `GeoRestore`, and `PointInTimeRestore`. Defaults to `Default`.
 
-* `public_network_access_enabled` - (Optional) Should public network access be allowed for this server? Defaults to `true`.
+* `creation_source_server_id` - (Optional) For creation modes other than `Default`, the source server ID to use.
 
-* `tags` - (Optional) A mapping of tags to assign to the resource.
+* `geo_redundant_backup_enabled` - (Optional) Turn Geo-redundant server backups on/off. This allows you to choose between locally redundant or geo-redundant backup storage in the General Purpose and Memory Optimized tiers. When the backups are stored in geo-redundant backup storage, they are not only stored within the region in which your server is hosted, but are also replicated to a paired data center. This provides better protection and ability to restore your server in a different region in the event of a disaster. This is not supported for the Basic tier.
 
----
+* `infrastructure_encryption_enabled` - (Optional) Whether or not infrastructure is encrypted for this server. Defaults to `false`. Changing this forces a new resource to be created.
 
-`storage_profile` supports the following:
+* `public_network_access_enabled` - (Optional) Whether or not public network access is allowed for this server. Defaults to `true`.
 
-* `storage_mb` - (Required) Max storage allowed for a server. Possible values are between `5120` MB(5GB) and `1048576` MB(1TB) for the Basic SKU and between `5120` MB(5GB) and `4194304` MB(4TB) for General Purpose/Memory Optimized SKUs. For more information see the [product documentation](https://docs.microsoft.com/en-us/rest/api/mysql/servers/create#StorageProfile).
+* `restore_point_in_time` - (Optional) When `create_mode` is `PointInTimeRestore`, specifies the point in time to restore from `creation_source_server_id`.
 
-* `backup_retention_days` - (Optional) Backup retention days for the server, supported values are between `7` and `35` days.
+* `ssl_enforcement_enabled` - (Required) Specifies if SSL should be enforced on connections. Possible values are `true` and `false`.
+
+* `ssl_minimal_tls_version_enforced` - (Optional) The minimum TLS version to support on the sever. Possible values are `TLSEnforcementDisabled`, `TLS1_0`, `TLS1_1`, and `TLS1_2`. Defaults to `TLSEnforcementDisabled`.
 
-* `geo_redundant_backup` - (Optional) Enable Geo-redundant or not for server backup. Valid values for this property are `Enabled` or `Disabled`, not supported for the `basic` tier.
+* `storage_mb` - (Required) Max storage allowed for a server. Possible values are between `5120` MB(5GB) and `1048576` MB(1TB) for the Basic SKU and between `5120` MB(5GB) and `4194304` MB(4TB) for General Purpose/Memory Optimized SKUs. For more information see the [product documentation](https://docs.microsoft.com/en-us/rest/api/mysql/servers/create#StorageProfile).
 
-* `auto_grow` - (Optional) Defines whether autogrow is enabled or disabled for the storage. Valid values are `Enabled` or `Disabled`.
+* `tags` - (Optional) A mapping of tags to assign to the resource.
 
 ## Attributes Reference