From 6c4a9c0b2b856a43ae3309e752c3c6d90f978a32 Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Tue, 15 Jan 2019 18:59:17 -0800
Subject: [PATCH 01/45] WIP: Initial check-in for max_size_gb

---
 azurerm/helpers/azure/elasticpool.go      | 390 ++++++++++++++++++++++
 azurerm/resource_arm_mssql_elasticpool.go | 162 +++++++--
 2 files changed, 518 insertions(+), 34 deletions(-)
 create mode 100644 azurerm/helpers/azure/elasticpool.go

diff --git a/azurerm/helpers/azure/elasticpool.go b/azurerm/helpers/azure/elasticpool.go
new file mode 100644
index 000000000000..299740af7aeb
--- /dev/null
+++ b/azurerm/helpers/azure/elasticpool.go
@@ -0,0 +1,390 @@
+package azure
+
+import (
+	"fmt"
+	"math"
+)
+
+func BasicGetMaxSizeGB(DTUs int) float64 {
+	switch DTUs {
+	case 50:
+		return 4.8828125
+	case 100:
+		return 9.765625
+	case 200:
+		return 19.53125
+	case 300:
+		return 29.296875
+	case 400:
+		return 39.0625
+	case 800:
+		return 78.125
+	case 1200:
+		return 117.1875
+	case 1600:
+		return 156.25
+	}
+	// Invalid DTU
+	return -1
+}
+
+func BasicIsCapacityValid(capacity int) bool {
+	switch {
+	case capacity == 50:
+	case capacity == 100:
+	case capacity == 200:
+	case capacity == 300:
+	case capacity == 400:
+	case capacity == 800:
+	case capacity == 1200:
+	case capacity == 1600:
+	default:
+		return false
+	}
+
+	return true
+}
+
+func StandardGetMaxSizeGB(DTUs int) float64 {
+	switch DTUs {
+	case 50:
+		return 500
+	case 100:
+		return 750
+	case 200:
+		return 1000
+	case 300:
+		return 1250
+	case 400:
+		return 1500
+	case 800:
+		return 2000
+	case 1200:
+		return 2500
+	case 1600:
+		return 3000
+	case 2000:
+		return 3500
+	case 2500:
+		fallthrough
+	case 3000:
+		return 4000
+	}
+	// Invalid DTU
+	return -1
+}
+
+func StandardCapacityValid(capacity int) bool {
+	switch {
+	case capacity == 50:
+	case capacity == 100:
+	case capacity == 200:
+	case capacity == 300:
+	case capacity == 400:
+	case capacity == 800:
+	case capacity == 1200:
+	case capacity == 1600:
+	case capacity == 2000:
+	case capacity == 2500:
+	case capacity == 3000:
+	default:
+		return false
+	}
+
+	return true
+}
+
+func PremiumGetMaxSizeGB(DTUs int) float64 {
+	switch DTUs {
+	case 125:
+		fallthrough
+	case 250:
+		fallthrough
+	case 500:
+		fallthrough
+	case 1000:
+		return 1000
+	case 1500:
+		return 1500
+	case 2000:
+		return 2000
+	case 2500:
+		return 2500
+	case 3000:
+		return 3000
+	case 3500:
+		return 3500
+	case 4000:
+		return 4000
+	}
+	// Invalid DTU
+	return -1
+}
+
+func PremiumCapacityValid(capacity int) bool {
+	switch {
+	case capacity == 125:
+	case capacity == 250:
+	case capacity == 500:
+	case capacity == 1000:
+	case capacity == 1500:
+	case capacity == 2000:
+	case capacity == 2500:
+	case capacity == 3000:
+	case capacity == 3500:
+	case capacity == 4000:
+	default:
+		return false
+	}
+
+	return true
+}
+
+func GeneralPurposeGetMaxSizeGB(vCores int, SKU string) float64 {
+
+	if SKU == "gen4" {
+		switch vCores {
+		case 1:
+			return 512
+		case 2:
+			return 756
+		case 3:
+			fallthrough
+		case 4:
+			fallthrough
+		case 5:
+			return 1500
+		case 6:
+			fallthrough
+		case 7:
+			fallthrough
+		case 8:
+			fallthrough
+		case 9:
+			fallthrough
+		case 10:
+			return 2000
+		case 16:
+			return 3500
+		case 24:
+			return 4000
+		}
+		// Invalid vCore
+		return -1
+	} else if SKU == "gen5" {
+		switch vCores {
+		case 2:
+			return 512
+		case 4:
+			return 756
+		case 6:
+			fallthrough
+		case 8:
+			fallthrough
+		case 10:
+			return 1500
+		case 12:
+			fallthrough
+		case 14:
+			fallthrough
+		case 16:
+			return 2000
+		case 18:
+			fallthrough
+		case 20:
+			fallthrough
+		case 24:
+			return 3000
+		case 32:
+			fallthrough
+		case 40:
+			fallthrough
+		case 80:
+			return 4000
+		}
+		// Invalid vCore
+		return -1
+	}
+
+	// Invalid SKU
+	return -2
+}
+
+func GeneralPurposeCapacityValid(capacity int, family string) bool {
+	if family == "gen4" {
+		switch {
+		case capacity == 1:
+		case capacity == 2:
+		case capacity == 3:
+		case capacity == 4:
+		case capacity == 5:
+		case capacity == 6:
+		case capacity == 7:
+		case capacity == 8:
+		case capacity == 9:
+		case capacity == 10:
+		case capacity == 16:
+		case capacity == 24:
+		default:
+			return false
+		}
+
+		return true
+	}
+
+	if family == "gen5" {
+		switch {
+		case capacity == 2:
+		case capacity == 4:
+		case capacity == 6:
+		case capacity == 8:
+		case capacity == 10:
+		case capacity == 12:
+		case capacity == 14:
+		case capacity == 16:
+		case capacity == 18:
+		case capacity == 20:
+		case capacity == 24:
+		case capacity == 32:
+		case capacity == 40:
+		case capacity == 80:
+		default:
+			return false
+		}
+
+		return true
+	}
+
+	return false
+}
+
+func BusinessCriticalGetMaxSizeGB(vCores int, SKU string) float64 {
+
+	if SKU == "gen4" {
+		switch vCores {
+		case 2:
+			fallthrough
+		case 3:
+			fallthrough
+		case 4:
+			fallthrough
+		case 5:
+			fallthrough
+		case 6:
+			fallthrough
+		case 7:
+			fallthrough
+		case 8:
+			fallthrough
+		case 9:
+			fallthrough
+		case 10:
+			fallthrough
+		case 16:
+			fallthrough
+		case 24:
+			return 1000
+		}
+		// Invalid vCore
+		return -1
+	} else if SKU == "gen5" {
+		switch vCores {
+		case 4:
+			return 1000
+		case 6:
+			fallthrough
+		case 8:
+			fallthrough
+		case 10:
+			return 1500
+		case 12:
+			fallthrough
+		case 14:
+			fallthrough
+		case 16:
+			fallthrough
+		case 18:
+			fallthrough
+		case 20:
+			return 3000
+		case 24:
+			fallthrough
+		case 32:
+			fallthrough
+		case 40:
+			fallthrough
+		case 80:
+			return 4000
+		}
+		// Invalid vCore
+		return -1
+	}
+
+	// Invalid SKU
+	return -2
+}
+
+func BusinessCriticalCapacityValid(capacity int, family string) bool {
+	if family == "gen4" {
+		switch {
+		case capacity == 2:
+		case capacity == 3:
+		case capacity == 4:
+		case capacity == 5:
+		case capacity == 6:
+		case capacity == 7:
+		case capacity == 8:
+		case capacity == 9:
+		case capacity == 10:
+		case capacity == 16:
+		case capacity == 24:
+		default:
+			return false
+		}
+
+		return true
+	}
+
+	if family == "gen5" {
+		switch {
+		case capacity == 4:
+		case capacity == 6:
+		case capacity == 8:
+		case capacity == 10:
+		case capacity == 12:
+		case capacity == 14:
+		case capacity == 16:
+		case capacity == 18:
+		case capacity == 20:
+		case capacity == 24:
+		case capacity == 32:
+		case capacity == 40:
+		case capacity == 80:
+		default:
+			return false
+		}
+
+		return true
+	}
+
+	return false
+}
+
+func IsMaxGBValid(gbIncrement int64, maxSizeGB float64) (msg string, ok bool) {
+	// Get the increment for the value in bytes
+	// and the maxSizeGB in bytes
+	inc := 1073741824 * gbIncrement
+	max := 1073741824 * maxSizeGB
+
+	// Check to see if the resulting max_size_bytes value is an integral value
+	if max != math.Trunc(float64(max)) {
+		return "max_size_gb is not a valid value", false
+	}
+
+	// Check to see if the maxSizeGB follows the increment constraint
+	if max/float64(inc) != math.Trunc(float64(max/float64(inc))) {
+		return fmt.Sprintf("max_size_gb must be defined in increments of %d GB", gbIncrement), false
+	}
+
+	return "", true
+}
diff --git a/azurerm/resource_arm_mssql_elasticpool.go b/azurerm/resource_arm_mssql_elasticpool.go
index e3fc1cc1f3db..faa0a6e4d16c 100644
--- a/azurerm/resource_arm_mssql_elasticpool.go
+++ b/azurerm/resource_arm_mssql_elasticpool.go
@@ -158,11 +158,11 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 				},
 			},
 
-			"max_size_bytes": {
-				Type:         schema.TypeInt,
+			"max_size_gb": {
+				Type:         schema.TypeFloat,
 				Optional:     true,
 				Computed:     true,
-				ValidateFunc: validation.IntAtLeast(0),
+				ValidateFunc: validate.FloatAtLeast(0),
 			},
 
 			"zone_redundant": {
@@ -176,53 +176,146 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 		CustomizeDiff: func(diff *schema.ResourceDiff, v interface{}) error {
 
 			name, _ := diff.GetOk("sku.0.name")
+			tier, _ := diff.GetOk("sku.0.tier")
 			capacity, _ := diff.GetOk("sku.0.capacity")
+			maxSizeGb, _ := diff.GetOk("max_size_gb")
 			minCapacity, _ := diff.GetOk("per_database_settings.0.min_capacity")
 			maxCapacity, _ := diff.GetOk("per_database_settings.0.max_capacity")
 
-			if strings.HasPrefix(strings.ToLower(name.(string)), "gp_") {
+			// Basic Checks
+			if strings.ToLower(tier.(string)) == "basic" {
+
+				if !azure.BasicIsCapacityValid(capacity.(int)) {
+					return fmt.Errorf("Basic pricing tier must have a capacity of 50, 100, 200, 300, 400, 800, 1200 or 1600 DTUs")
+				}
 
-				if capacity.(int) > 24 {
-					return fmt.Errorf("GeneralPurpose pricing tier only supports upto 24 vCores")
+				// Basic SKU does not let you pick your max_size_GB they are fixed values
+				maxAllowedGB := azure.BasicGetMaxSizeGB(capacity.(int))
+
+				if maxSizeGb.(float64) != maxAllowedGB {
+					return fmt.Errorf("Basic pricing tier with a capacity of %d must have a max_size_gb of %.7f, got %.7f", capacity.(int), maxAllowedGB, maxSizeGb.(float64))
 				}
+			}
 
-				if capacity.(int) < 1 {
-					return fmt.Errorf("GeneralPurpose pricing tier must have a minimum of 1 vCores")
+			// Standard Checks
+			if strings.ToLower(tier.(string)) == "standard" {
+				if int(maxSizeGb.(float64)) < 50 {
+					return fmt.Errorf("Standard pricing tier must have a max_size_gb value equal to or greater than 50 GB, got %d GB", int(maxSizeGb.(float64)))
 				}
 
-				switch {
-				case capacity.(int) == 1:
-				case capacity.(int) == 2:
-				case capacity.(int) == 4:
-				case capacity.(int) == 8:
-				case capacity.(int) == 16:
-				case capacity.(int) == 24:
-				default:
-					return fmt.Errorf("GeneralPurpose pricing tier must have a capacity of 1, 2, 4, 8, 16, or 24 vCores")
+				if !azure.StandardCapacityValid(capacity.(int)) {
+					return fmt.Errorf("Standard pricing tier must have a capacity of 50, 100, 200, 300, 400, 800, 1200, 1600, 2000, 2500 or 3000 DTUs")
+				}
+
+				maxAllowedGB := azure.StandardGetMaxSizeGB(capacity.(int))
+
+				if maxSizeGb.(float64) > maxAllowedGB {
+					return fmt.Errorf("Standard pricing tier with a capacity of %d must have a max_size_gb no greater than %d, got %d", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
+				}
+
+				if err, ok := azure.IsMaxGBValid(50, maxSizeGb.(float64)); !ok {
+					return fmt.Errorf(err)
 				}
 			}
 
-			if strings.HasPrefix(strings.ToLower(name.(string)), "bc_") {
-				if capacity.(int) > 80 {
-					return fmt.Errorf("BusinessCritical pricing tier only supports upto 80 vCores")
+			// Premium Checks
+			if strings.ToLower(tier.(string)) == "premium" {
+				if int(maxSizeGb.(float64)) < 50 {
+					return fmt.Errorf("Premium pricing tier must have a max_size_gb value equal to or greater than 50 GB, got %d GB", int(maxSizeGb.(float64)))
+				}
+
+				if !azure.PremiumCapacityValid(capacity.(int)) {
+					return fmt.Errorf("Premium pricing tier must have a capacity of 125, 250, 500, 1000, 1500, 2000, 2500, 3000, 3500 or 4000 DTUs")
+				}
+
+				maxAllowedGB := azure.PremiumGetMaxSizeGB(capacity.(int))
+
+				if maxSizeGb.(float64) > maxAllowedGB {
+					return fmt.Errorf("Premium pricing tier with a capacity of %d must have a max_size_gb no greater than %d, got %d", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
+				}
+
+				if err, ok := azure.IsMaxGBValid(50, maxSizeGb.(float64)); !ok {
+					return fmt.Errorf(err)
+				}
+			}
+
+			// GeneralPurpose Checks
+			if strings.HasPrefix(strings.ToLower(name.(string)), "gp_") {
+				if int(maxSizeGb.(float64)) < 5 {
+					return fmt.Errorf("GeneralPurpose pricing tier must have a max_size_gb value equal to or greater than 5 GB, got %f GB", maxSizeGb.(float64))
 				}
 
-				if capacity.(int) < 2 {
-					return fmt.Errorf("BusinessCritical pricing tier must have a minimum of 2 vCores")
+				// Gen4 Checks
+				if strings.ToLower(tier.(string)) == "gen4" {
+
+					if !azure.GeneralPurposeCapacityValid(capacity.(int), "gen4") {
+						return fmt.Errorf("GeneralPurpose Gen4 pricing tier must have a capacity of 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 16 or 24 vCores")
+					}
+
+					maxAllowedGB := azure.GeneralPurposeGetMaxSizeGB(capacity.(int), "gen4")
+
+					if maxSizeGb.(float64) > maxAllowedGB {
+						return fmt.Errorf("GeneralPurpose Gen4 pricing tier with a capacity of %d vCores must have a max_size_gb between 5 GB and %d GB, got %f", capacity.(int), int(maxAllowedGB), maxSizeGb.(float64))
+					}
+
+					if err, ok := azure.IsMaxGBValid(1, maxSizeGb.(float64)); !ok {
+						return fmt.Errorf(err)
+					}
 				}
 
-				switch {
-				case capacity.(int) == 1:
-				case capacity.(int) == 2:
-				case capacity.(int) == 4:
-				case capacity.(int) == 8:
-				case capacity.(int) == 16:
-				case capacity.(int) == 24:
-				case capacity.(int) == 32:
-				case capacity.(int) == 40:
-				case capacity.(int) == 80:
-				default:
-					return fmt.Errorf("BusinessCritical pricing tier must have a capacity of 2, 4, 8, 16, 24, 32, 40, or 80 vCores")
+				// Gen5 Checks
+				if strings.ToLower(tier.(string)) == "gen5" {
+					if !azure.GeneralPurposeCapacityValid(capacity.(int), "gen5") {
+						return fmt.Errorf("GeneralPurpose Gen5 pricing tier must have a capacity of 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 24, 32, 40 or 80 vCores")
+					}
+
+					maxAllowedGB := azure.GeneralPurposeGetMaxSizeGB(capacity.(int), "gen5")
+
+					if maxSizeGb.(float64) > maxAllowedGB {
+						return fmt.Errorf("GeneralPurpose Gen5 pricing tier with a capacity of %d vCores must have a max_size_gb between 5 GB and %d GB, got %f", capacity.(int), int(maxAllowedGB), maxSizeGb.(float64))
+					}
+
+					if err, ok := azure.IsMaxGBValid(1, maxSizeGb.(float64)); !ok {
+						return fmt.Errorf(err)
+					}
+				}
+			}
+
+			// BusinessCritical Checks
+			if strings.HasPrefix(strings.ToLower(name.(string)), "bc_") {
+
+				// Gen4 Checks
+				if strings.ToLower(tier.(string)) == "gen4" {
+					if !azure.BusinessCriticalCapacityValid(capacity.(int), "gen4") {
+						return fmt.Errorf("BusinessCritical Gen4 pricing tier must have a capacity of 2, 3, 4, 5, 6, 7, 8, 9, 10, 16 or 24 vCores")
+					}
+
+					maxAllowedGB := azure.BusinessCriticalGetMaxSizeGB(capacity.(int), "gen4")
+
+					if maxSizeGb.(float64) > maxAllowedGB {
+						return fmt.Errorf("BusinessCritical Gen4 pricing tier with a capacity of %d vCores must have a max_size_gb between 5 GB and %d GB, got %f", capacity.(int), int(maxAllowedGB), maxSizeGb.(float64))
+					}
+
+					if err, ok := azure.IsMaxGBValid(1, maxSizeGb.(float64)); !ok {
+						return fmt.Errorf(err)
+					}
+				}
+
+				// Gen5 Checks
+				if strings.ToLower(tier.(string)) == "gen5" {
+					if !azure.BusinessCriticalCapacityValid(capacity.(int), "gen5") {
+						return fmt.Errorf("BusinessCritical Gen5 pricing tier must have a capacity of 4, 6, 8, 10, 12, 14, 16, 18, 20, 24, 32, 40 or 80 vCores")
+					}
+
+					maxAllowedGB := azure.BusinessCriticalGetMaxSizeGB(capacity.(int), "gen5")
+
+					if maxSizeGb.(float64) > maxAllowedGB {
+						return fmt.Errorf("BusinessCritical Gen5 pricing tier with a capacity of %d vCores must have a max_size_gb between 5 GB and %d GB, got %f", capacity.(int), int(maxAllowedGB), maxSizeGb.(float64))
+					}
+
+					if err, ok := azure.IsMaxGBValid(1, maxSizeGb.(float64)); !ok {
+						return fmt.Errorf(err)
+					}
 				}
 			}
 
@@ -280,6 +373,7 @@ func resourceArmMsSqlElasticPoolCreateUpdate(d *schema.ResourceData, meta interf
 	}
 
 	if v, ok := d.GetOk("max_size_bytes"); ok {
+		// Convert to Bytes here
 		elasticPool.MaxSizeBytes = utils.Int64(int64(v.(int)))
 	}
 

From e6a2bd3c78bccacce67647beb248c97b8ddc12af Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Wed, 16 Jan 2019 16:13:41 -0800
Subject: [PATCH 02/45] Finished adding validation for Elasticpool max_size_gb

---
 azurerm/helpers/azure/elasticpool.go      | 132 +++++++++++++++++-----
 azurerm/resource_arm_mssql_elasticpool.go | 118 +++++++++----------
 2 files changed, 154 insertions(+), 96 deletions(-)

diff --git a/azurerm/helpers/azure/elasticpool.go b/azurerm/helpers/azure/elasticpool.go
index 299740af7aeb..8f8855fa4e29 100644
--- a/azurerm/helpers/azure/elasticpool.go
+++ b/azurerm/helpers/azure/elasticpool.go
@@ -3,6 +3,7 @@ package azure
 import (
 	"fmt"
 	"math"
+	"strings"
 )
 
 func BasicGetMaxSizeGB(DTUs int) float64 {
@@ -31,18 +32,24 @@ func BasicGetMaxSizeGB(DTUs int) float64 {
 func BasicIsCapacityValid(capacity int) bool {
 	switch {
 	case capacity == 50:
+		fallthrough
 	case capacity == 100:
+		fallthrough
 	case capacity == 200:
+		fallthrough
 	case capacity == 300:
+		fallthrough
 	case capacity == 400:
+		fallthrough
 	case capacity == 800:
+		fallthrough
 	case capacity == 1200:
+		fallthrough
 	case capacity == 1600:
-	default:
-		return false
+		return true
 	}
 
-	return true
+	return false
 }
 
 func StandardGetMaxSizeGB(DTUs int) float64 {
@@ -77,21 +84,30 @@ func StandardGetMaxSizeGB(DTUs int) float64 {
 func StandardCapacityValid(capacity int) bool {
 	switch {
 	case capacity == 50:
+		fallthrough
 	case capacity == 100:
+		fallthrough
 	case capacity == 200:
+		fallthrough
 	case capacity == 300:
+		fallthrough
 	case capacity == 400:
+		fallthrough
 	case capacity == 800:
+		fallthrough
 	case capacity == 1200:
+		fallthrough
 	case capacity == 1600:
+		fallthrough
 	case capacity == 2000:
+		fallthrough
 	case capacity == 2500:
+		fallthrough
 	case capacity == 3000:
-	default:
-		return false
+		return true
 	}
 
-	return true
+	return false
 }
 
 func PremiumGetMaxSizeGB(DTUs int) float64 {
@@ -124,25 +140,33 @@ func PremiumGetMaxSizeGB(DTUs int) float64 {
 func PremiumCapacityValid(capacity int) bool {
 	switch {
 	case capacity == 125:
+		fallthrough
 	case capacity == 250:
+		fallthrough
 	case capacity == 500:
+		fallthrough
 	case capacity == 1000:
+		fallthrough
 	case capacity == 1500:
+		fallthrough
 	case capacity == 2000:
+		fallthrough
 	case capacity == 2500:
+		fallthrough
 	case capacity == 3000:
+		fallthrough
 	case capacity == 3500:
+		fallthrough
 	case capacity == 4000:
-	default:
-		return false
+		return true
 	}
 
-	return true
+	return false
 }
 
-func GeneralPurposeGetMaxSizeGB(vCores int, SKU string) float64 {
+func GeneralPurposeGetMaxSizeGB(vCores int, family string) float64 {
 
-	if SKU == "gen4" {
+	if family == "gen4" {
 		switch vCores {
 		case 1:
 			return 512
@@ -171,7 +195,9 @@ func GeneralPurposeGetMaxSizeGB(vCores int, SKU string) float64 {
 		}
 		// Invalid vCore
 		return -1
-	} else if SKU == "gen5" {
+	}
+
+	if family == "gen5" {
 		switch vCores {
 		case 2:
 			return 512
@@ -206,7 +232,7 @@ func GeneralPurposeGetMaxSizeGB(vCores int, SKU string) float64 {
 		return -1
 	}
 
-	// Invalid SKU
+	// Invalid family
 	return -2
 }
 
@@ -214,53 +240,75 @@ func GeneralPurposeCapacityValid(capacity int, family string) bool {
 	if family == "gen4" {
 		switch {
 		case capacity == 1:
+			fallthrough
 		case capacity == 2:
+			fallthrough
 		case capacity == 3:
+			fallthrough
 		case capacity == 4:
+			fallthrough
 		case capacity == 5:
+			fallthrough
 		case capacity == 6:
+			fallthrough
 		case capacity == 7:
+			fallthrough
 		case capacity == 8:
+			fallthrough
 		case capacity == 9:
+			fallthrough
 		case capacity == 10:
+			fallthrough
 		case capacity == 16:
+			fallthrough
 		case capacity == 24:
-		default:
-			return false
+			return true
 		}
 
-		return true
+		return false
 	}
 
 	if family == "gen5" {
 		switch {
 		case capacity == 2:
+			fallthrough
 		case capacity == 4:
+			fallthrough
 		case capacity == 6:
+			fallthrough
 		case capacity == 8:
+			fallthrough
 		case capacity == 10:
+			fallthrough
 		case capacity == 12:
+			fallthrough
 		case capacity == 14:
+			fallthrough
 		case capacity == 16:
+			fallthrough
 		case capacity == 18:
+			fallthrough
 		case capacity == 20:
+			fallthrough
 		case capacity == 24:
+			fallthrough
 		case capacity == 32:
+			fallthrough
 		case capacity == 40:
+			fallthrough
 		case capacity == 80:
-		default:
-			return false
+			return true
 		}
 
-		return true
+		return false
 	}
 
 	return false
 }
 
-func BusinessCriticalGetMaxSizeGB(vCores int, SKU string) float64 {
+func BusinessCriticalGetMaxSizeGB(vCores int, family string) float64 {
 
-	if SKU == "gen4" {
+	if family == "gen4" {
 		switch vCores {
 		case 2:
 			fallthrough
@@ -287,7 +335,9 @@ func BusinessCriticalGetMaxSizeGB(vCores int, SKU string) float64 {
 		}
 		// Invalid vCore
 		return -1
-	} else if SKU == "gen5" {
+	}
+
+	if family == "gen5" {
 		switch vCores {
 		case 4:
 			return 1000
@@ -320,7 +370,7 @@ func BusinessCriticalGetMaxSizeGB(vCores int, SKU string) float64 {
 		return -1
 	}
 
-	// Invalid SKU
+	// Invalid family
 	return -2
 }
 
@@ -328,43 +378,63 @@ func BusinessCriticalCapacityValid(capacity int, family string) bool {
 	if family == "gen4" {
 		switch {
 		case capacity == 2:
+			fallthrough
 		case capacity == 3:
+			fallthrough
 		case capacity == 4:
+			fallthrough
 		case capacity == 5:
+			fallthrough
 		case capacity == 6:
+			fallthrough
 		case capacity == 7:
+			fallthrough
 		case capacity == 8:
+			fallthrough
 		case capacity == 9:
+			fallthrough
 		case capacity == 10:
+			fallthrough
 		case capacity == 16:
+			fallthrough
 		case capacity == 24:
-		default:
-			return false
+			return true
 		}
 
-		return true
+		return false
 	}
 
 	if family == "gen5" {
 		switch {
 		case capacity == 4:
+			fallthrough
 		case capacity == 6:
+			fallthrough
 		case capacity == 8:
+			fallthrough
 		case capacity == 10:
+			fallthrough
 		case capacity == 12:
+			fallthrough
 		case capacity == 14:
+			fallthrough
 		case capacity == 16:
+			fallthrough
 		case capacity == 18:
+			fallthrough
 		case capacity == 20:
+			fallthrough
 		case capacity == 24:
+			fallthrough
 		case capacity == 32:
+			fallthrough
 		case capacity == 40:
+			fallthrough
 		case capacity == 80:
-		default:
-			return false
+			return true
 		}
 
-		return true
+		return false
 	}
 
 	return false
@@ -388,3 +458,7 @@ func IsMaxGBValid(gbIncrement int64, maxSizeGB float64) (msg string, ok bool) {
 
 	return "", true
 }
+
+func NameFamilyValid(name string, family string) bool {
+	return strings.Contains(strings.ToLower(name), strings.ToLower(family))
+}
diff --git a/azurerm/resource_arm_mssql_elasticpool.go b/azurerm/resource_arm_mssql_elasticpool.go
index faa0a6e4d16c..c1318a03352d 100644
--- a/azurerm/resource_arm_mssql_elasticpool.go
+++ b/azurerm/resource_arm_mssql_elasticpool.go
@@ -178,169 +178,153 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 			name, _ := diff.GetOk("sku.0.name")
 			tier, _ := diff.GetOk("sku.0.tier")
 			capacity, _ := diff.GetOk("sku.0.capacity")
+			family, _ := diff.GetOk("sku.0.family")
 			maxSizeGb, _ := diff.GetOk("max_size_gb")
 			minCapacity, _ := diff.GetOk("per_database_settings.0.min_capacity")
 			maxCapacity, _ := diff.GetOk("per_database_settings.0.max_capacity")
 
 			// Basic Checks
 			if strings.ToLower(tier.(string)) == "basic" {
-
 				if !azure.BasicIsCapacityValid(capacity.(int)) {
-					return fmt.Errorf("Basic pricing tier must have a capacity of 50, 100, 200, 300, 400, 800, 1200 or 1600 DTUs")
+					return fmt.Errorf("service tier 'Basic' must have a capacity of 50, 100, 200, 300, 400, 800, 1200 or 1600 DTUs")
 				}
 
 				// Basic SKU does not let you pick your max_size_GB they are fixed values
 				maxAllowedGB := azure.BasicGetMaxSizeGB(capacity.(int))
 
 				if maxSizeGb.(float64) != maxAllowedGB {
-					return fmt.Errorf("Basic pricing tier with a capacity of %d must have a max_size_gb of %.7f, got %.7f", capacity.(int), maxAllowedGB, maxSizeGb.(float64))
+					return fmt.Errorf("service tier 'Basic' with a capacity of %d must have a max_size_gb of %.7f GB, got %.7f GB", capacity.(int), maxAllowedGB, maxSizeGb.(float64))
 				}
 			}
 
 			// Standard Checks
 			if strings.ToLower(tier.(string)) == "standard" {
-				if int(maxSizeGb.(float64)) < 50 {
-					return fmt.Errorf("Standard pricing tier must have a max_size_gb value equal to or greater than 50 GB, got %d GB", int(maxSizeGb.(float64)))
-				}
-
 				if !azure.StandardCapacityValid(capacity.(int)) {
-					return fmt.Errorf("Standard pricing tier must have a capacity of 50, 100, 200, 300, 400, 800, 1200, 1600, 2000, 2500 or 3000 DTUs")
+					return fmt.Errorf("service tier 'Standard' must have a capacity of 50, 100, 200, 300, 400, 800, 1200, 1600, 2000, 2500 or 3000 DTUs")
 				}
 
 				maxAllowedGB := azure.StandardGetMaxSizeGB(capacity.(int))
 
 				if maxSizeGb.(float64) > maxAllowedGB {
-					return fmt.Errorf("Standard pricing tier with a capacity of %d must have a max_size_gb no greater than %d, got %d", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
-				}
-
-				if err, ok := azure.IsMaxGBValid(50, maxSizeGb.(float64)); !ok {
-					return fmt.Errorf(err)
+					return fmt.Errorf("service tier 'Standard' with a capacity of %d must have a max_size_gb no greater than %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
 				}
 			}
 
 			// Premium Checks
 			if strings.ToLower(tier.(string)) == "premium" {
-				if int(maxSizeGb.(float64)) < 50 {
-					return fmt.Errorf("Premium pricing tier must have a max_size_gb value equal to or greater than 50 GB, got %d GB", int(maxSizeGb.(float64)))
-				}
-
 				if !azure.PremiumCapacityValid(capacity.(int)) {
-					return fmt.Errorf("Premium pricing tier must have a capacity of 125, 250, 500, 1000, 1500, 2000, 2500, 3000, 3500 or 4000 DTUs")
+					return fmt.Errorf("service tier 'Premium' must have a capacity of 125, 250, 500, 1000, 1500, 2000, 2500, 3000, 3500 or 4000 DTUs")
 				}
 
 				maxAllowedGB := azure.PremiumGetMaxSizeGB(capacity.(int))
 
 				if maxSizeGb.(float64) > maxAllowedGB {
-					return fmt.Errorf("Premium pricing tier with a capacity of %d must have a max_size_gb no greater than %d, got %d", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
-				}
-
-				if err, ok := azure.IsMaxGBValid(50, maxSizeGb.(float64)); !ok {
-					return fmt.Errorf(err)
+					return fmt.Errorf("service tier 'Premium' with a capacity of %d must have a max_size_gb no greater than %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
 				}
 			}
 
 			// GeneralPurpose Checks
 			if strings.HasPrefix(strings.ToLower(name.(string)), "gp_") {
-				if int(maxSizeGb.(float64)) < 5 {
-					return fmt.Errorf("GeneralPurpose pricing tier must have a max_size_gb value equal to or greater than 5 GB, got %f GB", maxSizeGb.(float64))
-				}
-
 				// Gen4 Checks
-				if strings.ToLower(tier.(string)) == "gen4" {
-
+				if strings.ToLower(family.(string)) == "gen4" {
 					if !azure.GeneralPurposeCapacityValid(capacity.(int), "gen4") {
-						return fmt.Errorf("GeneralPurpose Gen4 pricing tier must have a capacity of 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 16 or 24 vCores")
+						return fmt.Errorf("service tier 'GeneralPurpose' Gen4 must have a capacity of 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 16 or 24 vCores")
 					}
 
 					maxAllowedGB := azure.GeneralPurposeGetMaxSizeGB(capacity.(int), "gen4")
 
 					if maxSizeGb.(float64) > maxAllowedGB {
-						return fmt.Errorf("GeneralPurpose Gen4 pricing tier with a capacity of %d vCores must have a max_size_gb between 5 GB and %d GB, got %f", capacity.(int), int(maxAllowedGB), maxSizeGb.(float64))
-					}
-
-					if err, ok := azure.IsMaxGBValid(1, maxSizeGb.(float64)); !ok {
-						return fmt.Errorf(err)
+						return fmt.Errorf("service tier 'GeneralPurpose' Gen4 with a capacity of %d vCores must have a max_size_gb between 5 GB and %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
 					}
 				}
 
 				// Gen5 Checks
-				if strings.ToLower(tier.(string)) == "gen5" {
+				if strings.ToLower(family.(string)) == "gen5" {
 					if !azure.GeneralPurposeCapacityValid(capacity.(int), "gen5") {
-						return fmt.Errorf("GeneralPurpose Gen5 pricing tier must have a capacity of 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 24, 32, 40 or 80 vCores")
+						return fmt.Errorf("service tier 'GeneralPurpose' Gen5 must have a capacity of 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 24, 32, 40 or 80 vCores")
 					}
 
 					maxAllowedGB := azure.GeneralPurposeGetMaxSizeGB(capacity.(int), "gen5")
 
 					if maxSizeGb.(float64) > maxAllowedGB {
-						return fmt.Errorf("GeneralPurpose Gen5 pricing tier with a capacity of %d vCores must have a max_size_gb between 5 GB and %d GB, got %f", capacity.(int), int(maxAllowedGB), maxSizeGb.(float64))
-					}
-
-					if err, ok := azure.IsMaxGBValid(1, maxSizeGb.(float64)); !ok {
-						return fmt.Errorf(err)
+						return fmt.Errorf("service tier 'GeneralPurpose' Gen5 with a capacity of %d vCores must have a max_size_gb between 5 GB and %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
 					}
 				}
 			}
 
 			// BusinessCritical Checks
 			if strings.HasPrefix(strings.ToLower(name.(string)), "bc_") {
-
 				// Gen4 Checks
-				if strings.ToLower(tier.(string)) == "gen4" {
+				if strings.ToLower(family.(string)) == "gen4" {
 					if !azure.BusinessCriticalCapacityValid(capacity.(int), "gen4") {
-						return fmt.Errorf("BusinessCritical Gen4 pricing tier must have a capacity of 2, 3, 4, 5, 6, 7, 8, 9, 10, 16 or 24 vCores")
+						return fmt.Errorf("service tier 'BusinessCritical' Gen4 must have a capacity of 2, 3, 4, 5, 6, 7, 8, 9, 10, 16 or 24 vCores")
 					}
 
 					maxAllowedGB := azure.BusinessCriticalGetMaxSizeGB(capacity.(int), "gen4")
 
 					if maxSizeGb.(float64) > maxAllowedGB {
-						return fmt.Errorf("BusinessCritical Gen4 pricing tier with a capacity of %d vCores must have a max_size_gb between 5 GB and %d GB, got %f", capacity.(int), int(maxAllowedGB), maxSizeGb.(float64))
-					}
-
-					if err, ok := azure.IsMaxGBValid(1, maxSizeGb.(float64)); !ok {
-						return fmt.Errorf(err)
+						return fmt.Errorf("service tier 'BusinessCritical' Gen4 with a capacity of %d vCores must have a max_size_gb between 5 GB and %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
 					}
 				}
 
 				// Gen5 Checks
-				if strings.ToLower(tier.(string)) == "gen5" {
+				if strings.ToLower(family.(string)) == "gen5" {
 					if !azure.BusinessCriticalCapacityValid(capacity.(int), "gen5") {
-						return fmt.Errorf("BusinessCritical Gen5 pricing tier must have a capacity of 4, 6, 8, 10, 12, 14, 16, 18, 20, 24, 32, 40 or 80 vCores")
+						return fmt.Errorf("service tier 'BusinessCritical' Gen5 must have a capacity of 4, 6, 8, 10, 12, 14, 16, 18, 20, 24, 32, 40 or 80 vCores")
 					}
 
 					maxAllowedGB := azure.BusinessCriticalGetMaxSizeGB(capacity.(int), "gen5")
 
 					if maxSizeGb.(float64) > maxAllowedGB {
-						return fmt.Errorf("BusinessCritical Gen5 pricing tier with a capacity of %d vCores must have a max_size_gb between 5 GB and %d GB, got %f", capacity.(int), int(maxAllowedGB), maxSizeGb.(float64))
-					}
-
-					if err, ok := azure.IsMaxGBValid(1, maxSizeGb.(float64)); !ok {
-						return fmt.Errorf(err)
+						return fmt.Errorf("service tier 'BusinessCritical' Gen5 with a capacity of %d vCores must have a max_size_gb between 5 GB and %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
 					}
 				}
 			}
 
-			// Additional checks based of SKU type...
+			// General Checks based off SKU type...
 			if strings.HasPrefix(strings.ToLower(name.(string)), "gp_") || strings.HasPrefix(strings.ToLower(name.(string)), "bc_") {
-				// vCore based
+				// vCore Based
+				if int(maxSizeGb.(float64)) < 5 {
+					return fmt.Errorf("service tier 'GeneralPurpose' and 'BusinessCritical' must have a max_size_gb value equal to or greater than 5 GB, got %d GB", int(maxSizeGb.(float64)))
+				}
+
+				if err, ok := azure.IsMaxGBValid(1, maxSizeGb.(float64)); !ok {
+					return fmt.Errorf(err)
+				}
+
+				if !azure.NameFamilyValid(name.(string), family.(string)) {
+					return fmt.Errorf("SKU has a name family mismatch, got name = %s, family = %s", name.(string), family.(string))
+				}
+
 				if maxCapacity.(float64) > float64(capacity.(int)) {
-					return fmt.Errorf("BusinessCritical and GeneralPurpose pricing tiers perDatabaseSettings maxCapacity must not be higher than the SKUs capacity value")
+					return fmt.Errorf("service tiers 'GeneralPurpose' and 'BusinessCritical' perDatabaseSettings maxCapacity must not be higher than the SKUs capacity value")
 				}
 
 				if minCapacity.(float64) > maxCapacity.(float64) {
 					return fmt.Errorf("perDatabaseSettings maxCapacity must be greater than or equal to the perDatabaseSettings minCapacity value")
 				}
 			} else {
-				// DTU based
+				// DTU Based
+				if strings.ToLower(tier.(string)) != "basic" {
+					if int(maxSizeGb.(float64)) < 50 {
+						return fmt.Errorf("service tiers 'Standard', and 'Premium' must have a max_size_gb value equal to or greater than 50 GB, got %d GB", int(maxSizeGb.(float64)))
+					}
+
+					if err, ok := azure.IsMaxGBValid(50, maxSizeGb.(float64)); !ok {
+						return fmt.Errorf(err)
+					}
+				}
+
 				if maxCapacity.(float64) != math.Trunc(maxCapacity.(float64)) {
-					return fmt.Errorf("BasicPool, StandardPool, and PremiumPool SKUs must have whole numbers as their maxCapacity")
+					return fmt.Errorf("service tiers 'Basic', 'Standard', and 'Premium' must have whole numbers as their maxCapacity")
 				}
 
 				if minCapacity.(float64) != math.Trunc(minCapacity.(float64)) {
-					return fmt.Errorf("BasicPool, StandardPool, and PremiumPool SKUs must have whole numbers as their minCapacity")
+					return fmt.Errorf("service tiers 'Basic', 'Standard', and 'Premium' must have whole numbers as their minCapacity")
 				}
 
 				if minCapacity.(float64) < 0.0 {
-					return fmt.Errorf("BasicPool, StandardPool, and PremiumPool SKUs per_database_settings min_capacity must be equal to or greater than zero")
+					return fmt.Errorf("service tiers 'Basic', 'Standard', and 'Premium' per_database_settings min_capacity must be equal to or greater than zero")
 				}
 			}
 
@@ -372,9 +356,9 @@ func resourceArmMsSqlElasticPoolCreateUpdate(d *schema.ResourceData, meta interf
 		},
 	}
 
-	if v, ok := d.GetOk("max_size_bytes"); ok {
-		// Convert to Bytes here
-		elasticPool.MaxSizeBytes = utils.Int64(int64(v.(int)))
+	if v, ok := d.GetOk("max_size_gb"); ok {
+		maxSizeBytes := v.(float64) * 1073741824
+		elasticPool.MaxSizeBytes = utils.Int64(int64(maxSizeBytes))
 	}
 
 	future, err := client.CreateOrUpdate(ctx, resGroup, serverName, elasticPoolName, elasticPool)

From 615fd79d9355f784bdd53f9bf80ed11a0b5184ad Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Wed, 16 Jan 2019 16:31:52 -0800
Subject: [PATCH 03/45] Added additional SKU check and updated docs

---
 azurerm/resource_arm_mssql_elasticpool.go      | 10 ++++++++++
 website/docs/r/mssql_elasticpool.html.markdown |  4 ++--
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/azurerm/resource_arm_mssql_elasticpool.go b/azurerm/resource_arm_mssql_elasticpool.go
index c1318a03352d..ab13f14f5056 100644
--- a/azurerm/resource_arm_mssql_elasticpool.go
+++ b/azurerm/resource_arm_mssql_elasticpool.go
@@ -225,6 +225,11 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 
 			// GeneralPurpose Checks
 			if strings.HasPrefix(strings.ToLower(name.(string)), "gp_") {
+				//General Checks
+				if strings.ToLower(tier.(string)) != "generalpurpose" {
+					return fmt.Errorf("mismatch between SKU name '%s' and tier '%s'", name.(string), tier.(string))
+				}
+
 				// Gen4 Checks
 				if strings.ToLower(family.(string)) == "gen4" {
 					if !azure.GeneralPurposeCapacityValid(capacity.(int), "gen4") {
@@ -254,6 +259,11 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 
 			// BusinessCritical Checks
 			if strings.HasPrefix(strings.ToLower(name.(string)), "bc_") {
+				//General Checks
+				if strings.ToLower(tier.(string)) != "businesscritical" {
+					return fmt.Errorf("mismatch between SKU name '%s' and tier '%s'", name.(string), tier.(string))
+				}
+
 				// Gen4 Checks
 				if strings.ToLower(family.(string)) == "gen4" {
 					if !azure.BusinessCriticalCapacityValid(capacity.(int), "gen4") {
diff --git a/website/docs/r/mssql_elasticpool.html.markdown b/website/docs/r/mssql_elasticpool.html.markdown
index e36bf783a163..ab2f7265ba96 100644
--- a/website/docs/r/mssql_elasticpool.html.markdown
+++ b/website/docs/r/mssql_elasticpool.html.markdown
@@ -32,7 +32,7 @@ resource "azurerm_mssql_elasticpool" "test" {
   resource_group_name = "${azurerm_resource_group.test.name}"
   location            = "${azurerm_resource_group.test.location}"
   server_name         = "${azurerm_sql_server.test.name}"
-  max_size_bytes      = 5368709120
+  max_size_gb         = 756
 
   sku {
     name     = "GP_Gen5"
@@ -64,7 +64,7 @@ The following arguments are supported:
 
 * `per_database_settings` - (Required) A `per_database_settings` block as defined below.
 
-* `max_size_bytes` - (Optional) The max data size of the elastic pool in bytes.
+* `max_size_gb` - (Optional) The max data size of the elastic pool in gigabytes.
 
 * `tags` - (Optional) A mapping of tags to assign to the resource.
 

From 8fcfb4a49c631347346bb806037f016037c3e32c Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Wed, 16 Jan 2019 17:10:29 -0800
Subject: [PATCH 04/45] Updated tests to use max_size_gb

---
 .../resource_arm_mssql_elasticpool_test.go    | 34 ++++++++++---------
 1 file changed, 18 insertions(+), 16 deletions(-)

diff --git a/azurerm/resource_arm_mssql_elasticpool_test.go b/azurerm/resource_arm_mssql_elasticpool_test.go
index dc55f31faf54..e3254c2c06fb 100644
--- a/azurerm/resource_arm_mssql_elasticpool_test.go
+++ b/azurerm/resource_arm_mssql_elasticpool_test.go
@@ -29,7 +29,7 @@ func TestAccAzureRMMsSqlElasticPool_basic_DTU(t *testing.T) {
 					resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "50"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.min_capacity", "0"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.max_capacity", "5"),
-					resource.TestCheckResourceAttrSet(resourceName, "max_size_bytes"),
+					resource.TestCheckResourceAttrSet(resourceName, "max_size_gb"),
 					resource.TestCheckResourceAttrSet(resourceName, "zone_redundant"),
 				),
 			},
@@ -56,14 +56,15 @@ func TestAccAzureRMMsSqlElasticPool_standard_DTU(t *testing.T) {
 					resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "50"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.min_capacity", "0"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.max_capacity", "50"),
-					resource.TestCheckResourceAttrSet(resourceName, "max_size_bytes"),
+					resource.TestCheckResourceAttrSet(resourceName, "max_size_gb"),
 					resource.TestCheckResourceAttrSet(resourceName, "zone_redundant"),
 				),
 			},
 			{
-				ResourceName:      resourceName,
-				ImportState:       true,
-				ImportStateVerify: true,
+				ResourceName:            resourceName,
+				ImportState:             true,
+				ImportStateVerify:       true,
+				ImportStateVerifyIgnore: []string{"max_size_gb"},
 			},
 		},
 	})
@@ -89,14 +90,15 @@ func TestAccAzureRMMsSqlElasticPool_basic_vCore(t *testing.T) {
 					resource.TestCheckResourceAttr(resourceName, "sku.0.family", "Gen5"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.min_capacity", "0.25"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.max_capacity", "4"),
-					resource.TestCheckResourceAttrSet(resourceName, "max_size_bytes"),
+					resource.TestCheckResourceAttrSet(resourceName, "max_size_gb"),
 					resource.TestCheckResourceAttrSet(resourceName, "zone_redundant"),
 				),
 			},
 			{
-				ResourceName:      resourceName,
-				ImportState:       true,
-				ImportStateVerify: true,
+				ResourceName:            resourceName,
+				ImportState:             true,
+				ImportStateVerify:       true,
+				ImportStateVerifyIgnore: []string{"max_size_gb"},
 			},
 		},
 	})
@@ -284,15 +286,15 @@ func testCheckAzureRMMsSqlElasticPoolDisappears(resourceName string) resource.Te
 }
 
 func testAccAzureRMMsSqlElasticPool_basic_DTU(rInt int, location string) string {
-	return testAccAzureRMMsSqlElasticPool_DTU_Template(rInt, location, "BasicPool", "Basic", 50, 5242880000, 0, 5)
+	return testAccAzureRMMsSqlElasticPool_DTU_Template(rInt, location, "BasicPool", "Basic", 50, 4.8828125, 0, 5)
 }
 
 func testAccAzureRMMsSqlElasticPool_standard_DTU(rInt int, location string) string {
-	return testAccAzureRMMsSqlElasticPool_DTU_Template(rInt, location, "StandardPool", "Standard", 50, 53687091200, 0, 50)
+	return testAccAzureRMMsSqlElasticPool_DTU_Template(rInt, location, "StandardPool", "Standard", 50, 50, 0, 50)
 }
 
 func testAccAzureRMMsSqlElasticPool_resize_DTU(rInt int, location string) string {
-	return testAccAzureRMMsSqlElasticPool_DTU_Template(rInt, location, "StandardPool", "Standard", 100, 107374182400, 50, 100)
+	return testAccAzureRMMsSqlElasticPool_DTU_Template(rInt, location, "StandardPool", "Standard", 100, 100, 50, 100)
 }
 
 func testAccAzureRMMsSqlElasticPool_basic_vCore(rInt int, location string) string {
@@ -324,7 +326,7 @@ resource "azurerm_mssql_elasticpool" "test" {
   resource_group_name = "${azurerm_resource_group.test.name}"
   location            = "${azurerm_resource_group.test.location}"
   server_name         = "${azurerm_sql_server.test.name}"
-  max_size_bytes      = 5368709120
+  max_size_gb         = 5
 
   sku {
     name     = "%[3]s"
@@ -341,7 +343,7 @@ resource "azurerm_mssql_elasticpool" "test" {
 `, rInt, location, skuName, skuTier, skuCapacity, skuFamily, databaseSettingsMin, databaseSettingsMax)
 }
 
-func testAccAzureRMMsSqlElasticPool_DTU_Template(rInt int, location string, skuName string, skuTier string, skuCapacity int, maxSizeBytes int, databaseSettingsMin int, databaseSettingsMax int) string {
+func testAccAzureRMMsSqlElasticPool_DTU_Template(rInt int, location string, skuName string, skuTier string, skuCapacity int, maxSizeGB float64, databaseSettingsMin int, databaseSettingsMax int) string {
 	return fmt.Sprintf(`
 resource "azurerm_resource_group" "test" {
   name     = "acctestRG-%[1]d"
@@ -362,7 +364,7 @@ resource "azurerm_mssql_elasticpool" "test" {
   resource_group_name = "${azurerm_resource_group.test.name}"
   location            = "${azurerm_resource_group.test.location}"
   server_name         = "${azurerm_sql_server.test.name}"
-  max_size_bytes      = %[6]d
+  max_size_gb         = %.7[6]f
   
   sku {
     name     = "%[3]s"
@@ -375,5 +377,5 @@ resource "azurerm_mssql_elasticpool" "test" {
     max_capacity = %[8]d
   }
 }
-`, rInt, location, skuName, skuTier, skuCapacity, maxSizeBytes, databaseSettingsMin, databaseSettingsMax)
+`, rInt, location, skuName, skuTier, skuCapacity, maxSizeGB, databaseSettingsMin, databaseSettingsMax)
 }

From 6ba07522dfbbb8ad040de004c2ee393721c1fc1a Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Wed, 16 Jan 2019 18:04:47 -0800
Subject: [PATCH 05/45] fix lint errors

---
 azurerm/helpers/azure/elasticpool.go | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/azurerm/helpers/azure/elasticpool.go b/azurerm/helpers/azure/elasticpool.go
index 8f8855fa4e29..a4a1abc36ee2 100644
--- a/azurerm/helpers/azure/elasticpool.go
+++ b/azurerm/helpers/azure/elasticpool.go
@@ -447,12 +447,12 @@ func IsMaxGBValid(gbIncrement int64, maxSizeGB float64) (msg string, ok bool) {
 	max := 1073741824 * maxSizeGB
 
 	// Check to see if the resulting max_size_bytes value is an integral value
-	if max != math.Trunc(float64(max)) {
+	if max != math.Trunc(max) {
 		return "max_size_gb is not a valid value", false
 	}
 
 	// Check to see if the maxSizeGB follows the increment constraint
-	if max/float64(inc) != math.Trunc(float64(max/float64(inc))) {
+	if max/float64(inc) != math.Trunc(max/float64(inc)) {
 		return fmt.Sprintf("max_size_gb must be defined in increments of %d GB", gbIncrement), false
 	}
 

From 3ccc0b4d94f424ea27092d62fc7be2ca693d47f8 Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Thu, 17 Jan 2019 16:06:42 -0800
Subject: [PATCH 06/45] Added additional Standard and Premium size check

---
 azurerm/helpers/azure/elasticpool.go      | 307 +++++++++++++---------
 azurerm/resource_arm_mssql_elasticpool.go |   8 +-
 2 files changed, 185 insertions(+), 130 deletions(-)

diff --git a/azurerm/helpers/azure/elasticpool.go b/azurerm/helpers/azure/elasticpool.go
index a4a1abc36ee2..09e459cca4ba 100644
--- a/azurerm/helpers/azure/elasticpool.go
+++ b/azurerm/helpers/azure/elasticpool.go
@@ -1,7 +1,6 @@
 package azure
 
 import (
-	"fmt"
 	"math"
 	"strings"
 )
@@ -30,22 +29,22 @@ func BasicGetMaxSizeGB(DTUs int) float64 {
 }
 
 func BasicIsCapacityValid(capacity int) bool {
-	switch {
-	case capacity == 50:
+	switch capacity {
+	case 50:
 		fallthrough
-	case capacity == 100:
+	case 100:
 		fallthrough
-	case capacity == 200:
+	case 200:
 		fallthrough
-	case capacity == 300:
+	case 300:
 		fallthrough
-	case capacity == 400:
+	case 400:
 		fallthrough
-	case capacity == 800:
+	case 800:
 		fallthrough
-	case capacity == 1200:
+	case 1200:
 		fallthrough
-	case capacity == 1600:
+	case 1600:
 		return true
 	}
 
@@ -59,51 +58,51 @@ func StandardGetMaxSizeGB(DTUs int) float64 {
 	case 100:
 		return 750
 	case 200:
-		return 1000
+		return 1024
 	case 300:
-		return 1250
+		return 1280
 	case 400:
-		return 1500
+		return 1536
 	case 800:
-		return 2000
+		return 2048
 	case 1200:
-		return 2500
+		return 2560
 	case 1600:
-		return 3000
+		return 3072
 	case 2000:
-		return 3500
+		return 3584
 	case 2500:
 		fallthrough
 	case 3000:
-		return 4000
+		return 4096
 	}
 	// Invalid DTU
 	return -1
 }
 
 func StandardCapacityValid(capacity int) bool {
-	switch {
-	case capacity == 50:
+	switch capacity {
+	case 50:
 		fallthrough
-	case capacity == 100:
+	case 100:
 		fallthrough
-	case capacity == 200:
+	case 200:
 		fallthrough
-	case capacity == 300:
+	case 300:
 		fallthrough
-	case capacity == 400:
+	case 400:
 		fallthrough
-	case capacity == 800:
+	case 800:
 		fallthrough
-	case capacity == 1200:
+	case 1200:
 		fallthrough
-	case capacity == 1600:
+	case 1600:
 		fallthrough
-	case capacity == 2000:
+	case 2000:
 		fallthrough
-	case capacity == 2500:
+	case 2500:
 		fallthrough
-	case capacity == 3000:
+	case 3000:
 		return true
 	}
 
@@ -119,45 +118,108 @@ func PremiumGetMaxSizeGB(DTUs int) float64 {
 	case 500:
 		fallthrough
 	case 1000:
-		return 1000
+		return 1024
 	case 1500:
-		return 1500
+		return 1536
 	case 2000:
-		return 2000
+		return 2048
 	case 2500:
-		return 2500
+		return 2560
 	case 3000:
-		return 3000
+		return 3072
 	case 3500:
-		return 3500
+		return 3584
 	case 4000:
-		return 4000
+		return 4096
 	}
 	// Invalid DTU
 	return -1
 }
 
 func PremiumCapacityValid(capacity int) bool {
-	switch {
-	case capacity == 125:
+	switch capacity {
+	case 125:
+		fallthrough
+	case 250:
+		fallthrough
+	case 500:
+		fallthrough
+	case 1000:
+		fallthrough
+	case 1500:
+		fallthrough
+	case 2000:
+		fallthrough
+	case 2500:
+		fallthrough
+	case 3000:
+		fallthrough
+	case 3500:
+		fallthrough
+	case 4000:
+		return true
+	}
+
+	return false
+}
+
+func StantardPremiumMaxGBValid(gb float64) bool {
+	switch gb {
+	case 50:
+		fallthrough
+	case 100:
+		fallthrough
+	case 150:
+		fallthrough
+	case 200:
+		fallthrough
+	case 250:
+		fallthrough
+	case 300:
+		fallthrough
+	case 400:
+		fallthrough
+	case 500:
+		fallthrough
+	case 750:
+		fallthrough
+	case 800:
+		fallthrough
+	case 1024:
+		fallthrough
+	case 1200:
 		fallthrough
-	case capacity == 250:
+	case 1280:
 		fallthrough
-	case capacity == 500:
+	case 1536:
 		fallthrough
-	case capacity == 1000:
+	case 1600:
+		fallthrough
+	case 1792:
+		fallthrough
+	case 2000:
+		fallthrough
+	case 2048:
+		fallthrough
+	case 2304:
+		fallthrough
+	case 2500:
 		fallthrough
-	case capacity == 1500:
+	case 2560:
 		fallthrough
-	case capacity == 2000:
+	case 2816:
 		fallthrough
-	case capacity == 2500:
+	case 3000:
+		fallthrough
+	case 3072:
 		fallthrough
-	case capacity == 3000:
+	case 3328:
 		fallthrough
-	case capacity == 3500:
+	case 3584:
 		fallthrough
-	case capacity == 4000:
+	case 3840:
+		fallthrough
+	case 4096:
 		return true
 	}
 
@@ -177,7 +239,7 @@ func GeneralPurposeGetMaxSizeGB(vCores int, family string) float64 {
 		case 4:
 			fallthrough
 		case 5:
-			return 1500
+			return 1536
 		case 6:
 			fallthrough
 		case 7:
@@ -187,11 +249,11 @@ func GeneralPurposeGetMaxSizeGB(vCores int, family string) float64 {
 		case 9:
 			fallthrough
 		case 10:
-			return 2000
+			return 2048
 		case 16:
-			return 3500
+			return 3584
 		case 24:
-			return 4000
+			return 4096
 		}
 		// Invalid vCore
 		return -1
@@ -208,25 +270,25 @@ func GeneralPurposeGetMaxSizeGB(vCores int, family string) float64 {
 		case 8:
 			fallthrough
 		case 10:
-			return 1500
+			return 1536
 		case 12:
 			fallthrough
 		case 14:
 			fallthrough
 		case 16:
-			return 2000
+			return 2048
 		case 18:
 			fallthrough
 		case 20:
 			fallthrough
 		case 24:
-			return 3000
+			return 3072
 		case 32:
 			fallthrough
 		case 40:
 			fallthrough
 		case 80:
-			return 4000
+			return 4096
 		}
 		// Invalid vCore
 		return -1
@@ -238,30 +300,30 @@ func GeneralPurposeGetMaxSizeGB(vCores int, family string) float64 {
 
 func GeneralPurposeCapacityValid(capacity int, family string) bool {
 	if family == "gen4" {
-		switch {
-		case capacity == 1:
+		switch capacity {
+		case 1:
 			fallthrough
-		case capacity == 2:
+		case 2:
 			fallthrough
-		case capacity == 3:
+		case 3:
 			fallthrough
-		case capacity == 4:
+		case 4:
 			fallthrough
-		case capacity == 5:
+		case 5:
 			fallthrough
-		case capacity == 6:
+		case 6:
 			fallthrough
-		case capacity == 7:
+		case 7:
 			fallthrough
-		case capacity == 8:
+		case 8:
 			fallthrough
-		case capacity == 9:
+		case 9:
 			fallthrough
-		case capacity == 10:
+		case 10:
 			fallthrough
-		case capacity == 16:
+		case 16:
 			fallthrough
-		case capacity == 24:
+		case 24:
 			return true
 		}
 
@@ -269,34 +331,34 @@ func GeneralPurposeCapacityValid(capacity int, family string) bool {
 	}
 
 	if family == "gen5" {
-		switch {
-		case capacity == 2:
+		switch capacity {
+		case 2:
 			fallthrough
-		case capacity == 4:
+		case 4:
 			fallthrough
-		case capacity == 6:
+		case 6:
 			fallthrough
-		case capacity == 8:
+		case 8:
 			fallthrough
-		case capacity == 10:
+		case 10:
 			fallthrough
-		case capacity == 12:
+		case 12:
 			fallthrough
-		case capacity == 14:
+		case 14:
 			fallthrough
-		case capacity == 16:
+		case 16:
 			fallthrough
-		case capacity == 18:
+		case 18:
 			fallthrough
-		case capacity == 20:
+		case 20:
 			fallthrough
-		case capacity == 24:
+		case 24:
 			fallthrough
-		case capacity == 32:
+		case 32:
 			fallthrough
-		case capacity == 40:
+		case 40:
 			fallthrough
-		case capacity == 80:
+		case 80:
 			return true
 		}
 
@@ -331,7 +393,7 @@ func BusinessCriticalGetMaxSizeGB(vCores int, family string) float64 {
 		case 16:
 			fallthrough
 		case 24:
-			return 1000
+			return 1024
 		}
 		// Invalid vCore
 		return -1
@@ -340,13 +402,13 @@ func BusinessCriticalGetMaxSizeGB(vCores int, family string) float64 {
 	if family == "gen5" {
 		switch vCores {
 		case 4:
-			return 1000
+			return 1024
 		case 6:
 			fallthrough
 		case 8:
 			fallthrough
 		case 10:
-			return 1500
+			return 1536
 		case 12:
 			fallthrough
 		case 14:
@@ -356,7 +418,7 @@ func BusinessCriticalGetMaxSizeGB(vCores int, family string) float64 {
 		case 18:
 			fallthrough
 		case 20:
-			return 3000
+			return 3072
 		case 24:
 			fallthrough
 		case 32:
@@ -364,7 +426,7 @@ func BusinessCriticalGetMaxSizeGB(vCores int, family string) float64 {
 		case 40:
 			fallthrough
 		case 80:
-			return 4000
+			return 4096
 		}
 		// Invalid vCore
 		return -1
@@ -376,28 +438,28 @@ func BusinessCriticalGetMaxSizeGB(vCores int, family string) float64 {
 
 func BusinessCriticalCapacityValid(capacity int, family string) bool {
 	if family == "gen4" {
-		switch {
-		case capacity == 2:
+		switch capacity {
+		case 2:
 			fallthrough
-		case capacity == 3:
+		case 3:
 			fallthrough
-		case capacity == 4:
+		case 4:
 			fallthrough
-		case capacity == 5:
+		case 5:
 			fallthrough
-		case capacity == 6:
+		case 6:
 			fallthrough
-		case capacity == 7:
+		case 7:
 			fallthrough
-		case capacity == 8:
+		case 8:
 			fallthrough
-		case capacity == 9:
+		case 9:
 			fallthrough
-		case capacity == 10:
+		case 10:
 			fallthrough
-		case capacity == 16:
+		case 16:
 			fallthrough
-		case capacity == 24:
+		case 24:
 			return true
 		}
 
@@ -405,32 +467,32 @@ func BusinessCriticalCapacityValid(capacity int, family string) bool {
 	}
 
 	if family == "gen5" {
-		switch {
-		case capacity == 4:
+		switch capacity {
+		case 4:
 			fallthrough
-		case capacity == 6:
+		case 6:
 			fallthrough
-		case capacity == 8:
+		case 8:
 			fallthrough
-		case capacity == 10:
+		case 10:
 			fallthrough
-		case capacity == 12:
+		case 12:
 			fallthrough
-		case capacity == 14:
+		case 14:
 			fallthrough
-		case capacity == 16:
+		case 16:
 			fallthrough
-		case capacity == 18:
+		case 18:
 			fallthrough
-		case capacity == 20:
+		case 20:
 			fallthrough
-		case capacity == 24:
+		case 24:
 			fallthrough
-		case capacity == 32:
+		case 32:
 			fallthrough
-		case capacity == 40:
+		case 40:
 			fallthrough
-		case capacity == 80:
+		case 80:
 			return true
 		}
 
@@ -440,23 +502,16 @@ func BusinessCriticalCapacityValid(capacity int, family string) bool {
 	return false
 }
 
-func IsMaxGBValid(gbIncrement int64, maxSizeGB float64) (msg string, ok bool) {
-	// Get the increment for the value in bytes
-	// and the maxSizeGB in bytes
-	inc := 1073741824 * gbIncrement
+func IsInt(maxSizeGB float64) bool {
+	// Get the maxSizeGB for the value in bytes
 	max := 1073741824 * maxSizeGB
 
 	// Check to see if the resulting max_size_bytes value is an integral value
 	if max != math.Trunc(max) {
-		return "max_size_gb is not a valid value", false
-	}
-
-	// Check to see if the maxSizeGB follows the increment constraint
-	if max/float64(inc) != math.Trunc(max/float64(inc)) {
-		return fmt.Sprintf("max_size_gb must be defined in increments of %d GB", gbIncrement), false
+		return false
 	}
 
-	return "", true
+	return true
 }
 
 func NameFamilyValid(name string, family string) bool {
diff --git a/azurerm/resource_arm_mssql_elasticpool.go b/azurerm/resource_arm_mssql_elasticpool.go
index ab13f14f5056..7bbb5bb609ee 100644
--- a/azurerm/resource_arm_mssql_elasticpool.go
+++ b/azurerm/resource_arm_mssql_elasticpool.go
@@ -298,8 +298,8 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 					return fmt.Errorf("service tier 'GeneralPurpose' and 'BusinessCritical' must have a max_size_gb value equal to or greater than 5 GB, got %d GB", int(maxSizeGb.(float64)))
 				}
 
-				if err, ok := azure.IsMaxGBValid(1, maxSizeGb.(float64)); !ok {
-					return fmt.Errorf(err)
+				if !azure.IsInt(maxSizeGb.(float64)) {
+					return fmt.Errorf("max_size_gb (%f) is not an whole number of bytes", maxSizeGb.(float64))
 				}
 
 				if !azure.NameFamilyValid(name.(string), family.(string)) {
@@ -320,8 +320,8 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 						return fmt.Errorf("service tiers 'Standard', and 'Premium' must have a max_size_gb value equal to or greater than 50 GB, got %d GB", int(maxSizeGb.(float64)))
 					}
 
-					if err, ok := azure.IsMaxGBValid(50, maxSizeGb.(float64)); !ok {
-						return fmt.Errorf(err)
+					if !azure.StantardPremiumMaxGBValid(maxSizeGb.(float64)) {
+						return fmt.Errorf("max_size_gb (%d) is not a valid value, valid max_size_gb values are 50, 100, 150, 200, 250, 300, 400, 500, 750, 800, 1024, 1200, 1280, 1536, 1600, 1792, 2000, 2048, 2304, 2500, 2560, 2816, 3000, 3072, 3328, 3584, 3840 or 4096", int(maxSizeGb.(float64)))
 					}
 				}
 

From 706e7a773d9255248fb9eadd37fe8387e8b53c33 Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Thu, 17 Jan 2019 17:18:05 -0800
Subject: [PATCH 07/45] Switched logic to use maps instead

---
 azurerm/helpers/azure/elasticpool.go      | 594 +++++-----------------
 azurerm/resource_arm_mssql_elasticpool.go |  52 +-
 2 files changed, 162 insertions(+), 484 deletions(-)

diff --git a/azurerm/helpers/azure/elasticpool.go b/azurerm/helpers/azure/elasticpool.go
index 09e459cca4ba..1c4a691959ce 100644
--- a/azurerm/helpers/azure/elasticpool.go
+++ b/azurerm/helpers/azure/elasticpool.go
@@ -5,504 +5,182 @@ import (
 	"strings"
 )
 
-func BasicGetMaxSizeGB(DTUs int) float64 {
-	switch DTUs {
-	case 50:
-		return 4.8828125
-	case 100:
-		return 9.765625
-	case 200:
-		return 19.53125
-	case 300:
-		return 29.296875
-	case 400:
-		return 39.0625
-	case 800:
-		return 78.125
-	case 1200:
-		return 117.1875
-	case 1600:
-		return 156.25
-	}
-	// Invalid DTU
-	return -1
+var basicMaxSize = map[int]float64{
+	50:   4.8828125,
+	100:  9.765625,
+	200:  19.53125,
+	300:  29.296875,
+	400:  39.0625,
+	800:  78.125,
+	1200: 117.1875,
+	1600: 156.25,
 }
 
-func BasicIsCapacityValid(capacity int) bool {
-	switch capacity {
-	case 50:
-		fallthrough
-	case 100:
-		fallthrough
-	case 200:
-		fallthrough
-	case 300:
-		fallthrough
-	case 400:
-		fallthrough
-	case 800:
-		fallthrough
-	case 1200:
-		fallthrough
-	case 1600:
-		return true
-	}
+var standardMaxSize = map[int]float64{
+	50:   500,
+	100:  750,
+	200:  1024,
+	300:  1280,
+	400:  1536,
+	800:  2048,
+	1200: 2560,
+	1600: 3072,
+	2000: 3584,
+	2500: 4096,
+	3000: 4096,
+}
 
-	return false
+var premiumMaxSize = map[int]float64{
+	125:  1024,
+	250:  1024,
+	500:  1024,
+	1000: 1024,
+	1500: 1536,
+	2000: 2048,
+	2500: 2560,
+	3000: 3072,
+	3500: 3584,
+	4000: 4096,
 }
 
-func StandardGetMaxSizeGB(DTUs int) float64 {
-	switch DTUs {
-	case 50:
-		return 500
-	case 100:
-		return 750
-	case 200:
-		return 1024
-	case 300:
-		return 1280
-	case 400:
-		return 1536
-	case 800:
-		return 2048
-	case 1200:
-		return 2560
-	case 1600:
-		return 3072
-	case 2000:
-		return 3584
-	case 2500:
-		fallthrough
-	case 3000:
-		return 4096
-	}
-	// Invalid DTU
-	return -1
+var supportedDTUMaxGBValues = map[float64]bool{
+	50:   true,
+	100:  true,
+	150:  true,
+	200:  true,
+	250:  true,
+	300:  true,
+	400:  true,
+	500:  true,
+	750:  true,
+	800:  true,
+	1024: true,
+	1200: true,
+	1280: true,
+	1536: true,
+	1600: true,
+	1792: true,
+	2000: true,
+	2048: true,
+	2304: true,
+	2500: true,
+	2560: true,
+	2816: true,
+	3000: true,
+	3072: true,
+	3328: true,
+	3584: true,
+	3840: true,
+	4096: true,
 }
 
-func StandardCapacityValid(capacity int) bool {
-	switch capacity {
-	case 50:
-		fallthrough
-	case 100:
-		fallthrough
-	case 200:
-		fallthrough
-	case 300:
-		fallthrough
-	case 400:
-		fallthrough
-	case 800:
-		fallthrough
-	case 1200:
-		fallthrough
-	case 1600:
-		fallthrough
-	case 2000:
-		fallthrough
-	case 2500:
-		fallthrough
-	case 3000:
-		return true
-	}
+var generalPurposeGen4MaxGB = map[int]float64{
+	1:  512,
+	2:  756,
+	3:  1536,
+	4:  1536,
+	5:  1536,
+	6:  2048,
+	7:  2048,
+	8:  2048,
+	9:  2048,
+	10: 2048,
+	16: 3584,
+	24: 4096,
+}
 
-	return false
+var generalPurposeGen5MaxGB = map[int]float64{
+	2:  512,
+	4:  756,
+	6:  1536,
+	8:  1536,
+	10: 1536,
+	12: 2048,
+	14: 2048,
+	16: 2048,
+	18: 3072,
+	20: 3072,
+	24: 3072,
+	32: 4096,
+	40: 4096,
+	80: 4096,
 }
 
-func PremiumGetMaxSizeGB(DTUs int) float64 {
-	switch DTUs {
-	case 125:
-		fallthrough
-	case 250:
-		fallthrough
-	case 500:
-		fallthrough
-	case 1000:
-		return 1024
-	case 1500:
-		return 1536
-	case 2000:
-		return 2048
-	case 2500:
-		return 2560
-	case 3000:
-		return 3072
-	case 3500:
-		return 3584
-	case 4000:
-		return 4096
-	}
-	// Invalid DTU
-	return -1
+var businessCriticalGen4MaxGB = map[int]float64{
+	2:  1024,
+	3:  1024,
+	4:  1024,
+	5:  1024,
+	6:  1024,
+	7:  1024,
+	8:  1024,
+	9:  1024,
+	10: 1024,
+	16: 1024,
+	24: 1024,
 }
 
-func PremiumCapacityValid(capacity int) bool {
-	switch capacity {
-	case 125:
-		fallthrough
-	case 250:
-		fallthrough
-	case 500:
-		fallthrough
-	case 1000:
-		fallthrough
-	case 1500:
-		fallthrough
-	case 2000:
-		fallthrough
-	case 2500:
-		fallthrough
-	case 3000:
-		fallthrough
-	case 3500:
-		fallthrough
-	case 4000:
-		return true
-	}
+var businessCriticalGen5MaxGB = map[int]float64{
+	4:  1024,
+	6:  1536,
+	8:  1536,
+	10: 1536,
+	12: 3072,
+	14: 3072,
+	16: 3072,
+	18: 3072,
+	20: 3072,
+	24: 4096,
+	32: 4096,
+	40: 4096,
+	80: 4096,
+}
 
-	return false
+func BasicGetMaxSizeGB(DTUs int) float64 {
+	return basicMaxSize[DTUs]
 }
 
-func StantardPremiumMaxGBValid(gb float64) bool {
-	switch gb {
-	case 50:
-		fallthrough
-	case 100:
-		fallthrough
-	case 150:
-		fallthrough
-	case 200:
-		fallthrough
-	case 250:
-		fallthrough
-	case 300:
-		fallthrough
-	case 400:
-		fallthrough
-	case 500:
-		fallthrough
-	case 750:
-		fallthrough
-	case 800:
-		fallthrough
-	case 1024:
-		fallthrough
-	case 1200:
-		fallthrough
-	case 1280:
-		fallthrough
-	case 1536:
-		fallthrough
-	case 1600:
-		fallthrough
-	case 1792:
-		fallthrough
-	case 2000:
-		fallthrough
-	case 2048:
-		fallthrough
-	case 2304:
-		fallthrough
-	case 2500:
-		fallthrough
-	case 2560:
-		fallthrough
-	case 2816:
-		fallthrough
-	case 3000:
-		fallthrough
-	case 3072:
-		fallthrough
-	case 3328:
-		fallthrough
-	case 3584:
-		fallthrough
-	case 3840:
-		fallthrough
-	case 4096:
-		return true
-	}
+func StandardGetMaxSizeGB(DTUs int) float64 {
+	return standardMaxSize[DTUs]
+}
+
+func PremiumGetMaxSizeGB(DTUs int) float64 {
+	return premiumMaxSize[DTUs]
+}
 
-	return false
+func StantardPremiumMaxGBValid(gb float64) bool {
+	return supportedDTUMaxGBValues[gb]
 }
 
 func GeneralPurposeGetMaxSizeGB(vCores int, family string) float64 {
 
 	if family == "gen4" {
-		switch vCores {
-		case 1:
-			return 512
-		case 2:
-			return 756
-		case 3:
-			fallthrough
-		case 4:
-			fallthrough
-		case 5:
-			return 1536
-		case 6:
-			fallthrough
-		case 7:
-			fallthrough
-		case 8:
-			fallthrough
-		case 9:
-			fallthrough
-		case 10:
-			return 2048
-		case 16:
-			return 3584
-		case 24:
-			return 4096
-		}
-		// Invalid vCore
-		return -1
+		return generalPurposeGen4MaxGB[vCores]
 	}
 
 	if family == "gen5" {
-		switch vCores {
-		case 2:
-			return 512
-		case 4:
-			return 756
-		case 6:
-			fallthrough
-		case 8:
-			fallthrough
-		case 10:
-			return 1536
-		case 12:
-			fallthrough
-		case 14:
-			fallthrough
-		case 16:
-			return 2048
-		case 18:
-			fallthrough
-		case 20:
-			fallthrough
-		case 24:
-			return 3072
-		case 32:
-			fallthrough
-		case 40:
-			fallthrough
-		case 80:
-			return 4096
-		}
-		// Invalid vCore
-		return -1
+		return generalPurposeGen5MaxGB[vCores]
 	}
 
 	// Invalid family
-	return -2
-}
-
-func GeneralPurposeCapacityValid(capacity int, family string) bool {
-	if family == "gen4" {
-		switch capacity {
-		case 1:
-			fallthrough
-		case 2:
-			fallthrough
-		case 3:
-			fallthrough
-		case 4:
-			fallthrough
-		case 5:
-			fallthrough
-		case 6:
-			fallthrough
-		case 7:
-			fallthrough
-		case 8:
-			fallthrough
-		case 9:
-			fallthrough
-		case 10:
-			fallthrough
-		case 16:
-			fallthrough
-		case 24:
-			return true
-		}
-
-		return false
-	}
-
-	if family == "gen5" {
-		switch capacity {
-		case 2:
-			fallthrough
-		case 4:
-			fallthrough
-		case 6:
-			fallthrough
-		case 8:
-			fallthrough
-		case 10:
-			fallthrough
-		case 12:
-			fallthrough
-		case 14:
-			fallthrough
-		case 16:
-			fallthrough
-		case 18:
-			fallthrough
-		case 20:
-			fallthrough
-		case 24:
-			fallthrough
-		case 32:
-			fallthrough
-		case 40:
-			fallthrough
-		case 80:
-			return true
-		}
-
-		return false
-	}
-
-	return false
+	return -1
 }
 
 func BusinessCriticalGetMaxSizeGB(vCores int, family string) float64 {
 
 	if family == "gen4" {
-		switch vCores {
-		case 2:
-			fallthrough
-		case 3:
-			fallthrough
-		case 4:
-			fallthrough
-		case 5:
-			fallthrough
-		case 6:
-			fallthrough
-		case 7:
-			fallthrough
-		case 8:
-			fallthrough
-		case 9:
-			fallthrough
-		case 10:
-			fallthrough
-		case 16:
-			fallthrough
-		case 24:
-			return 1024
-		}
-		// Invalid vCore
-		return -1
+		return businessCriticalGen4MaxGB[vCores]
 	}
 
 	if family == "gen5" {
-		switch vCores {
-		case 4:
-			return 1024
-		case 6:
-			fallthrough
-		case 8:
-			fallthrough
-		case 10:
-			return 1536
-		case 12:
-			fallthrough
-		case 14:
-			fallthrough
-		case 16:
-			fallthrough
-		case 18:
-			fallthrough
-		case 20:
-			return 3072
-		case 24:
-			fallthrough
-		case 32:
-			fallthrough
-		case 40:
-			fallthrough
-		case 80:
-			return 4096
-		}
-		// Invalid vCore
-		return -1
+		return businessCriticalGen5MaxGB[vCores]
 	}
 
 	// Invalid family
-	return -2
-}
-
-func BusinessCriticalCapacityValid(capacity int, family string) bool {
-	if family == "gen4" {
-		switch capacity {
-		case 2:
-			fallthrough
-		case 3:
-			fallthrough
-		case 4:
-			fallthrough
-		case 5:
-			fallthrough
-		case 6:
-			fallthrough
-		case 7:
-			fallthrough
-		case 8:
-			fallthrough
-		case 9:
-			fallthrough
-		case 10:
-			fallthrough
-		case 16:
-			fallthrough
-		case 24:
-			return true
-		}
-
-		return false
-	}
-
-	if family == "gen5" {
-		switch capacity {
-		case 4:
-			fallthrough
-		case 6:
-			fallthrough
-		case 8:
-			fallthrough
-		case 10:
-			fallthrough
-		case 12:
-			fallthrough
-		case 14:
-			fallthrough
-		case 16:
-			fallthrough
-		case 18:
-			fallthrough
-		case 20:
-			fallthrough
-		case 24:
-			fallthrough
-		case 32:
-			fallthrough
-		case 40:
-			fallthrough
-		case 80:
-			return true
-		}
-
-		return false
-	}
-
-	return false
+	return -1
 }
 
-func IsInt(maxSizeGB float64) bool {
+func IsIntAsBytes(maxSizeGB float64) bool {
 	// Get the maxSizeGB for the value in bytes
 	max := 1073741824 * maxSizeGB
 
diff --git a/azurerm/resource_arm_mssql_elasticpool.go b/azurerm/resource_arm_mssql_elasticpool.go
index 7bbb5bb609ee..4d2b5cfc6fbe 100644
--- a/azurerm/resource_arm_mssql_elasticpool.go
+++ b/azurerm/resource_arm_mssql_elasticpool.go
@@ -185,13 +185,13 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 
 			// Basic Checks
 			if strings.ToLower(tier.(string)) == "basic" {
-				if !azure.BasicIsCapacityValid(capacity.(int)) {
+				maxAllowedGB := azure.BasicGetMaxSizeGB(capacity.(int))
+
+				if maxAllowedGB == 0 {
 					return fmt.Errorf("service tier 'Basic' must have a capacity of 50, 100, 200, 300, 400, 800, 1200 or 1600 DTUs")
 				}
 
 				// Basic SKU does not let you pick your max_size_GB they are fixed values
-				maxAllowedGB := azure.BasicGetMaxSizeGB(capacity.(int))
-
 				if maxSizeGb.(float64) != maxAllowedGB {
 					return fmt.Errorf("service tier 'Basic' with a capacity of %d must have a max_size_gb of %.7f GB, got %.7f GB", capacity.(int), maxAllowedGB, maxSizeGb.(float64))
 				}
@@ -199,12 +199,12 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 
 			// Standard Checks
 			if strings.ToLower(tier.(string)) == "standard" {
-				if !azure.StandardCapacityValid(capacity.(int)) {
+				maxAllowedGB := azure.StandardGetMaxSizeGB(capacity.(int))
+
+				if maxAllowedGB == 0 {
 					return fmt.Errorf("service tier 'Standard' must have a capacity of 50, 100, 200, 300, 400, 800, 1200, 1600, 2000, 2500 or 3000 DTUs")
 				}
 
-				maxAllowedGB := azure.StandardGetMaxSizeGB(capacity.(int))
-
 				if maxSizeGb.(float64) > maxAllowedGB {
 					return fmt.Errorf("service tier 'Standard' with a capacity of %d must have a max_size_gb no greater than %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
 				}
@@ -212,12 +212,12 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 
 			// Premium Checks
 			if strings.ToLower(tier.(string)) == "premium" {
-				if !azure.PremiumCapacityValid(capacity.(int)) {
+				maxAllowedGB := azure.PremiumGetMaxSizeGB(capacity.(int))
+
+				if maxAllowedGB == 0 {
 					return fmt.Errorf("service tier 'Premium' must have a capacity of 125, 250, 500, 1000, 1500, 2000, 2500, 3000, 3500 or 4000 DTUs")
 				}
 
-				maxAllowedGB := azure.PremiumGetMaxSizeGB(capacity.(int))
-
 				if maxSizeGb.(float64) > maxAllowedGB {
 					return fmt.Errorf("service tier 'Premium' with a capacity of %d must have a max_size_gb no greater than %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
 				}
@@ -227,17 +227,17 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 			if strings.HasPrefix(strings.ToLower(name.(string)), "gp_") {
 				//General Checks
 				if strings.ToLower(tier.(string)) != "generalpurpose" {
-					return fmt.Errorf("mismatch between SKU name '%s' and tier '%s'", name.(string), tier.(string))
+					return fmt.Errorf("SKU has a name '%s' tier '%s' mismatch, expected 'GeneralPurpose'", name.(string), tier.(string))
 				}
 
 				// Gen4 Checks
 				if strings.ToLower(family.(string)) == "gen4" {
-					if !azure.GeneralPurposeCapacityValid(capacity.(int), "gen4") {
+					maxAllowedGB := azure.GeneralPurposeGetMaxSizeGB(capacity.(int), "gen4")
+
+					if maxAllowedGB == 0 {
 						return fmt.Errorf("service tier 'GeneralPurpose' Gen4 must have a capacity of 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 16 or 24 vCores")
 					}
 
-					maxAllowedGB := azure.GeneralPurposeGetMaxSizeGB(capacity.(int), "gen4")
-
 					if maxSizeGb.(float64) > maxAllowedGB {
 						return fmt.Errorf("service tier 'GeneralPurpose' Gen4 with a capacity of %d vCores must have a max_size_gb between 5 GB and %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
 					}
@@ -245,12 +245,12 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 
 				// Gen5 Checks
 				if strings.ToLower(family.(string)) == "gen5" {
-					if !azure.GeneralPurposeCapacityValid(capacity.(int), "gen5") {
+					maxAllowedGB := azure.GeneralPurposeGetMaxSizeGB(capacity.(int), "gen5")
+
+					if maxAllowedGB == 0 {
 						return fmt.Errorf("service tier 'GeneralPurpose' Gen5 must have a capacity of 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 24, 32, 40 or 80 vCores")
 					}
 
-					maxAllowedGB := azure.GeneralPurposeGetMaxSizeGB(capacity.(int), "gen5")
-
 					if maxSizeGb.(float64) > maxAllowedGB {
 						return fmt.Errorf("service tier 'GeneralPurpose' Gen5 with a capacity of %d vCores must have a max_size_gb between 5 GB and %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
 					}
@@ -261,17 +261,17 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 			if strings.HasPrefix(strings.ToLower(name.(string)), "bc_") {
 				//General Checks
 				if strings.ToLower(tier.(string)) != "businesscritical" {
-					return fmt.Errorf("mismatch between SKU name '%s' and tier '%s'", name.(string), tier.(string))
+					return fmt.Errorf("SKU has a name '%s' tier '%s' mismatch, expected 'BusinessCritical'", name.(string), tier.(string))
 				}
 
 				// Gen4 Checks
 				if strings.ToLower(family.(string)) == "gen4" {
-					if !azure.BusinessCriticalCapacityValid(capacity.(int), "gen4") {
+					maxAllowedGB := azure.BusinessCriticalGetMaxSizeGB(capacity.(int), "gen4")
+
+					if maxAllowedGB == 0 {
 						return fmt.Errorf("service tier 'BusinessCritical' Gen4 must have a capacity of 2, 3, 4, 5, 6, 7, 8, 9, 10, 16 or 24 vCores")
 					}
 
-					maxAllowedGB := azure.BusinessCriticalGetMaxSizeGB(capacity.(int), "gen4")
-
 					if maxSizeGb.(float64) > maxAllowedGB {
 						return fmt.Errorf("service tier 'BusinessCritical' Gen4 with a capacity of %d vCores must have a max_size_gb between 5 GB and %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
 					}
@@ -279,12 +279,12 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 
 				// Gen5 Checks
 				if strings.ToLower(family.(string)) == "gen5" {
-					if !azure.BusinessCriticalCapacityValid(capacity.(int), "gen5") {
+					maxAllowedGB := azure.BusinessCriticalGetMaxSizeGB(capacity.(int), "gen5")
+
+					if maxAllowedGB == 0 {
 						return fmt.Errorf("service tier 'BusinessCritical' Gen5 must have a capacity of 4, 6, 8, 10, 12, 14, 16, 18, 20, 24, 32, 40 or 80 vCores")
 					}
 
-					maxAllowedGB := azure.BusinessCriticalGetMaxSizeGB(capacity.(int), "gen5")
-
 					if maxSizeGb.(float64) > maxAllowedGB {
 						return fmt.Errorf("service tier 'BusinessCritical' Gen5 with a capacity of %d vCores must have a max_size_gb between 5 GB and %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
 					}
@@ -298,12 +298,12 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 					return fmt.Errorf("service tier 'GeneralPurpose' and 'BusinessCritical' must have a max_size_gb value equal to or greater than 5 GB, got %d GB", int(maxSizeGb.(float64)))
 				}
 
-				if !azure.IsInt(maxSizeGb.(float64)) {
+				if !azure.IsIntAsBytes(maxSizeGb.(float64)) {
 					return fmt.Errorf("max_size_gb (%f) is not an whole number of bytes", maxSizeGb.(float64))
 				}
 
 				if !azure.NameFamilyValid(name.(string), family.(string)) {
-					return fmt.Errorf("SKU has a name family mismatch, got name = %s, family = %s", name.(string), family.(string))
+					return fmt.Errorf("SKU has a name '%s' family '%s' mismatch", name.(string), family.(string))
 				}
 
 				if maxCapacity.(float64) > float64(capacity.(int)) {
@@ -321,7 +321,7 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 					}
 
 					if !azure.StantardPremiumMaxGBValid(maxSizeGb.(float64)) {
-						return fmt.Errorf("max_size_gb (%d) is not a valid value, valid max_size_gb values are 50, 100, 150, 200, 250, 300, 400, 500, 750, 800, 1024, 1200, 1280, 1536, 1600, 1792, 2000, 2048, 2304, 2500, 2560, 2816, 3000, 3072, 3328, 3584, 3840 or 4096", int(maxSizeGb.(float64)))
+						return fmt.Errorf("max_size_gb (%d) is not a valid value, valid values are 50, 100, 150, 200, 250, 300, 400, 500, 750, 800, 1024, 1200, 1280, 1536, 1600, 1792, 2000, 2048, 2304, 2500, 2560, 2816, 3000, 3072, 3328, 3584, 3840 or 4096", int(maxSizeGb.(float64)))
 					}
 				}
 

From 541ee9ecaf68f6598abbbea7a58db4dc9156f95c Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Thu, 17 Jan 2019 18:21:43 -0800
Subject: [PATCH 08/45] Added values to error msgs

---
 azurerm/resource_arm_mssql_elasticpool.go | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/azurerm/resource_arm_mssql_elasticpool.go b/azurerm/resource_arm_mssql_elasticpool.go
index 4d2b5cfc6fbe..3c18ff736ee6 100644
--- a/azurerm/resource_arm_mssql_elasticpool.go
+++ b/azurerm/resource_arm_mssql_elasticpool.go
@@ -202,7 +202,7 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 				maxAllowedGB := azure.StandardGetMaxSizeGB(capacity.(int))
 
 				if maxAllowedGB == 0 {
-					return fmt.Errorf("service tier 'Standard' must have a capacity of 50, 100, 200, 300, 400, 800, 1200, 1600, 2000, 2500 or 3000 DTUs")
+					return fmt.Errorf("service tier 'Standard' must have a capacity(%d) of 50, 100, 200, 300, 400, 800, 1200, 1600, 2000, 2500 or 3000 DTUs", capacity.(int))
 				}
 
 				if maxSizeGb.(float64) > maxAllowedGB {
@@ -215,7 +215,7 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 				maxAllowedGB := azure.PremiumGetMaxSizeGB(capacity.(int))
 
 				if maxAllowedGB == 0 {
-					return fmt.Errorf("service tier 'Premium' must have a capacity of 125, 250, 500, 1000, 1500, 2000, 2500, 3000, 3500 or 4000 DTUs")
+					return fmt.Errorf("service tier 'Premium' must have a capacity(%d) of 125, 250, 500, 1000, 1500, 2000, 2500, 3000, 3500 or 4000 DTUs", capacity.(int))
 				}
 
 				if maxSizeGb.(float64) > maxAllowedGB {
@@ -235,7 +235,7 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 					maxAllowedGB := azure.GeneralPurposeGetMaxSizeGB(capacity.(int), "gen4")
 
 					if maxAllowedGB == 0 {
-						return fmt.Errorf("service tier 'GeneralPurpose' Gen4 must have a capacity of 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 16 or 24 vCores")
+						return fmt.Errorf("service tier 'GeneralPurpose' Gen4 must have a capacity(%d) of 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 16 or 24 vCores", capacity.(int))
 					}
 
 					if maxSizeGb.(float64) > maxAllowedGB {
@@ -248,7 +248,7 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 					maxAllowedGB := azure.GeneralPurposeGetMaxSizeGB(capacity.(int), "gen5")
 
 					if maxAllowedGB == 0 {
-						return fmt.Errorf("service tier 'GeneralPurpose' Gen5 must have a capacity of 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 24, 32, 40 or 80 vCores")
+						return fmt.Errorf("service tier 'GeneralPurpose' Gen5 must have a capacity(%d) of 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 24, 32, 40 or 80 vCores", capacity.(int))
 					}
 
 					if maxSizeGb.(float64) > maxAllowedGB {
@@ -269,7 +269,7 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 					maxAllowedGB := azure.BusinessCriticalGetMaxSizeGB(capacity.(int), "gen4")
 
 					if maxAllowedGB == 0 {
-						return fmt.Errorf("service tier 'BusinessCritical' Gen4 must have a capacity of 2, 3, 4, 5, 6, 7, 8, 9, 10, 16 or 24 vCores")
+						return fmt.Errorf("service tier 'BusinessCritical' Gen4 must have a capacity(%D) of 2, 3, 4, 5, 6, 7, 8, 9, 10, 16 or 24 vCores", capacity.(int))
 					}
 
 					if maxSizeGb.(float64) > maxAllowedGB {
@@ -282,7 +282,7 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 					maxAllowedGB := azure.BusinessCriticalGetMaxSizeGB(capacity.(int), "gen5")
 
 					if maxAllowedGB == 0 {
-						return fmt.Errorf("service tier 'BusinessCritical' Gen5 must have a capacity of 4, 6, 8, 10, 12, 14, 16, 18, 20, 24, 32, 40 or 80 vCores")
+						return fmt.Errorf("service tier 'BusinessCritical' Gen5 must have a capacity(%d) of 4, 6, 8, 10, 12, 14, 16, 18, 20, 24, 32, 40 or 80 vCores", capacity.(int))
 					}
 
 					if maxSizeGb.(float64) > maxAllowedGB {

From 92cd03af2e3f4307808b909ac6617171bc583922 Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Thu, 17 Jan 2019 18:23:01 -0800
Subject: [PATCH 09/45] fix format casing

---
 azurerm/resource_arm_mssql_elasticpool.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/azurerm/resource_arm_mssql_elasticpool.go b/azurerm/resource_arm_mssql_elasticpool.go
index 3c18ff736ee6..53d21c17fc65 100644
--- a/azurerm/resource_arm_mssql_elasticpool.go
+++ b/azurerm/resource_arm_mssql_elasticpool.go
@@ -269,7 +269,7 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 					maxAllowedGB := azure.BusinessCriticalGetMaxSizeGB(capacity.(int), "gen4")
 
 					if maxAllowedGB == 0 {
-						return fmt.Errorf("service tier 'BusinessCritical' Gen4 must have a capacity(%D) of 2, 3, 4, 5, 6, 7, 8, 9, 10, 16 or 24 vCores", capacity.(int))
+						return fmt.Errorf("service tier 'BusinessCritical' Gen4 must have a capacity(%d) of 2, 3, 4, 5, 6, 7, 8, 9, 10, 16 or 24 vCores", capacity.(int))
 					}
 
 					if maxSizeGb.(float64) > maxAllowedGB {

From 82897827d89462339b2c58feaf1dd68ccca88feb Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Fri, 18 Jan 2019 14:40:27 -0800
Subject: [PATCH 10/45] Addressed PR comments and updated some func names

---
 azurerm/helpers/azure/elasticpool.go      | 56 +++++++++++------------
 azurerm/resource_arm_mssql_elasticpool.go | 52 ++++++++++-----------
 2 files changed, 54 insertions(+), 54 deletions(-)

diff --git a/azurerm/helpers/azure/elasticpool.go b/azurerm/helpers/azure/elasticpool.go
index 1c4a691959ce..f2e6bcbd583b 100644
--- a/azurerm/helpers/azure/elasticpool.go
+++ b/azurerm/helpers/azure/elasticpool.go
@@ -5,7 +5,7 @@ import (
 	"strings"
 )
 
-var basicMaxSize = map[int]float64{
+var basicDTUMaxGB = map[int]float64{
 	50:   4.8828125,
 	100:  9.765625,
 	200:  19.53125,
@@ -16,7 +16,7 @@ var basicMaxSize = map[int]float64{
 	1600: 156.25,
 }
 
-var standardMaxSize = map[int]float64{
+var standardDTUMaxGB = map[int]float64{
 	50:   500,
 	100:  750,
 	200:  1024,
@@ -30,7 +30,7 @@ var standardMaxSize = map[int]float64{
 	3000: 4096,
 }
 
-var premiumMaxSize = map[int]float64{
+var premiumDTUMaxGB = map[int]float64{
 	125:  1024,
 	250:  1024,
 	500:  1024,
@@ -43,7 +43,7 @@ var premiumMaxSize = map[int]float64{
 	4000: 4096,
 }
 
-var supportedDTUMaxGBValues = map[float64]bool{
+var supportedMaxGBValues = map[float64]bool{
 	50:   true,
 	100:  true,
 	150:  true,
@@ -74,7 +74,7 @@ var supportedDTUMaxGBValues = map[float64]bool{
 	4096: true,
 }
 
-var generalPurposeGen4MaxGB = map[int]float64{
+var generalPurposeGen4vCoreMaxGB = map[int]float64{
 	1:  512,
 	2:  756,
 	3:  1536,
@@ -89,7 +89,7 @@ var generalPurposeGen4MaxGB = map[int]float64{
 	24: 4096,
 }
 
-var generalPurposeGen5MaxGB = map[int]float64{
+var generalPurposeGen5vCoreMaxGB = map[int]float64{
 	2:  512,
 	4:  756,
 	6:  1536,
@@ -106,7 +106,7 @@ var generalPurposeGen5MaxGB = map[int]float64{
 	80: 4096,
 }
 
-var businessCriticalGen4MaxGB = map[int]float64{
+var businessCriticalGen4vCoreMaxGB = map[int]float64{
 	2:  1024,
 	3:  1024,
 	4:  1024,
@@ -120,7 +120,7 @@ var businessCriticalGen4MaxGB = map[int]float64{
 	24: 1024,
 }
 
-var businessCriticalGen5MaxGB = map[int]float64{
+var businessCriticalGen5vCoreMaxGB = map[int]float64{
 	4:  1024,
 	6:  1536,
 	8:  1536,
@@ -137,55 +137,55 @@ var businessCriticalGen5MaxGB = map[int]float64{
 }
 
 func BasicGetMaxSizeGB(DTUs int) float64 {
-	return basicMaxSize[DTUs]
+	return basicDTUMaxGB[DTUs]
 }
 
 func StandardGetMaxSizeGB(DTUs int) float64 {
-	return standardMaxSize[DTUs]
+	return standardDTUMaxGB[DTUs]
 }
 
 func PremiumGetMaxSizeGB(DTUs int) float64 {
-	return premiumMaxSize[DTUs]
+	return premiumDTUMaxGB[DTUs]
 }
 
-func StantardPremiumMaxGBValid(gb float64) bool {
-	return supportedDTUMaxGBValues[gb]
+func StandardPremiumMaxGBValid(gb float64) bool {
+	return supportedMaxGBValues[gb]
 }
 
 func GeneralPurposeGetMaxSizeGB(vCores int, family string) float64 {
+	maxGB := 0.0
 
-	if family == "gen4" {
-		return generalPurposeGen4MaxGB[vCores]
+	if strings.EqualFold(family, "Gen4") {
+		maxGB = generalPurposeGen4vCoreMaxGB[vCores]
 	}
 
-	if family == "gen5" {
-		return generalPurposeGen5MaxGB[vCores]
+	if strings.EqualFold(family, "Gen5") {
+		maxGB = generalPurposeGen5vCoreMaxGB[vCores]
 	}
 
-	// Invalid family
-	return -1
+	return maxGB
 }
 
 func BusinessCriticalGetMaxSizeGB(vCores int, family string) float64 {
+	maxGB := 0.0
 
-	if family == "gen4" {
-		return businessCriticalGen4MaxGB[vCores]
+	if strings.EqualFold(family, "Gen4") {
+		maxGB = businessCriticalGen4vCoreMaxGB[vCores]
 	}
 
-	if family == "gen5" {
-		return businessCriticalGen5MaxGB[vCores]
+	if strings.EqualFold(family, "Gen5") {
+		maxGB = businessCriticalGen5vCoreMaxGB[vCores]
 	}
 
-	// Invalid family
-	return -1
+	return maxGB
 }
 
-func IsIntAsBytes(maxSizeGB float64) bool {
+func IsIntAsBytes(maxGB float64) bool {
 	// Get the maxSizeGB for the value in bytes
-	max := 1073741824 * maxSizeGB
+	maxBytes := 1073741824 * maxGB
 
 	// Check to see if the resulting max_size_bytes value is an integral value
-	if max != math.Trunc(max) {
+	if maxBytes != math.Trunc(maxBytes) {
 		return false
 	}
 
diff --git a/azurerm/resource_arm_mssql_elasticpool.go b/azurerm/resource_arm_mssql_elasticpool.go
index 53d21c17fc65..0fca1ff3cdb1 100644
--- a/azurerm/resource_arm_mssql_elasticpool.go
+++ b/azurerm/resource_arm_mssql_elasticpool.go
@@ -184,7 +184,7 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 			maxCapacity, _ := diff.GetOk("per_database_settings.0.max_capacity")
 
 			// Basic Checks
-			if strings.ToLower(tier.(string)) == "basic" {
+			if strings.EqualFold(tier.(string), "Basic") {
 				maxAllowedGB := azure.BasicGetMaxSizeGB(capacity.(int))
 
 				if maxAllowedGB == 0 {
@@ -193,12 +193,12 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 
 				// Basic SKU does not let you pick your max_size_GB they are fixed values
 				if maxSizeGb.(float64) != maxAllowedGB {
-					return fmt.Errorf("service tier 'Basic' with a capacity of %d must have a max_size_gb of %.7f GB, got %.7f GB", capacity.(int), maxAllowedGB, maxSizeGb.(float64))
+					return fmt.Errorf("service tier 'Basic' with a capacity of %d must have a 'max_size_gb' of %.7f GB, got %.7f GB", capacity.(int), maxAllowedGB, maxSizeGb.(float64))
 				}
 			}
 
 			// Standard Checks
-			if strings.ToLower(tier.(string)) == "standard" {
+			if strings.EqualFold(tier.(string), "Standard") {
 				maxAllowedGB := azure.StandardGetMaxSizeGB(capacity.(int))
 
 				if maxAllowedGB == 0 {
@@ -206,12 +206,12 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 				}
 
 				if maxSizeGb.(float64) > maxAllowedGB {
-					return fmt.Errorf("service tier 'Standard' with a capacity of %d must have a max_size_gb no greater than %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
+					return fmt.Errorf("service tier 'Standard' with a capacity of %d must have a 'max_size_gb' no greater than %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
 				}
 			}
 
 			// Premium Checks
-			if strings.ToLower(tier.(string)) == "premium" {
+			if strings.EqualFold(tier.(string), "Premium") {
 				maxAllowedGB := azure.PremiumGetMaxSizeGB(capacity.(int))
 
 				if maxAllowedGB == 0 {
@@ -219,40 +219,40 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 				}
 
 				if maxSizeGb.(float64) > maxAllowedGB {
-					return fmt.Errorf("service tier 'Premium' with a capacity of %d must have a max_size_gb no greater than %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
+					return fmt.Errorf("service tier 'Premium' with a capacity of %d must have a 'max_size_gb' no greater than %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
 				}
 			}
 
 			// GeneralPurpose Checks
 			if strings.HasPrefix(strings.ToLower(name.(string)), "gp_") {
 				//General Checks
-				if strings.ToLower(tier.(string)) != "generalpurpose" {
+				if !strings.EqualFold(tier.(string), "GeneralPurpose") {
 					return fmt.Errorf("SKU has a name '%s' tier '%s' mismatch, expected 'GeneralPurpose'", name.(string), tier.(string))
 				}
 
 				// Gen4 Checks
-				if strings.ToLower(family.(string)) == "gen4" {
-					maxAllowedGB := azure.GeneralPurposeGetMaxSizeGB(capacity.(int), "gen4")
+				if strings.EqualFold(family.(string), "Gen4") {
+					maxAllowedGB := azure.GeneralPurposeGetMaxSizeGB(capacity.(int), "Gen4")
 
 					if maxAllowedGB == 0 {
 						return fmt.Errorf("service tier 'GeneralPurpose' Gen4 must have a capacity(%d) of 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 16 or 24 vCores", capacity.(int))
 					}
 
 					if maxSizeGb.(float64) > maxAllowedGB {
-						return fmt.Errorf("service tier 'GeneralPurpose' Gen4 with a capacity of %d vCores must have a max_size_gb between 5 GB and %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
+						return fmt.Errorf("service tier 'GeneralPurpose' Gen4 with a capacity of %d vCores must have a 'max_size_gb' between 5 GB and %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
 					}
 				}
 
 				// Gen5 Checks
-				if strings.ToLower(family.(string)) == "gen5" {
-					maxAllowedGB := azure.GeneralPurposeGetMaxSizeGB(capacity.(int), "gen5")
+				if strings.EqualFold(family.(string), "Gen5") {
+					maxAllowedGB := azure.GeneralPurposeGetMaxSizeGB(capacity.(int), "Gen5")
 
 					if maxAllowedGB == 0 {
 						return fmt.Errorf("service tier 'GeneralPurpose' Gen5 must have a capacity(%d) of 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 24, 32, 40 or 80 vCores", capacity.(int))
 					}
 
 					if maxSizeGb.(float64) > maxAllowedGB {
-						return fmt.Errorf("service tier 'GeneralPurpose' Gen5 with a capacity of %d vCores must have a max_size_gb between 5 GB and %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
+						return fmt.Errorf("service tier 'GeneralPurpose' Gen5 with a capacity of %d vCores must have a 'max_size_gb' between 5 GB and %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
 					}
 				}
 			}
@@ -260,33 +260,33 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 			// BusinessCritical Checks
 			if strings.HasPrefix(strings.ToLower(name.(string)), "bc_") {
 				//General Checks
-				if strings.ToLower(tier.(string)) != "businesscritical" {
+				if !strings.EqualFold(tier.(string), "BusinessCritical") {
 					return fmt.Errorf("SKU has a name '%s' tier '%s' mismatch, expected 'BusinessCritical'", name.(string), tier.(string))
 				}
 
 				// Gen4 Checks
-				if strings.ToLower(family.(string)) == "gen4" {
-					maxAllowedGB := azure.BusinessCriticalGetMaxSizeGB(capacity.(int), "gen4")
+				if strings.EqualFold(family.(string), "Gen4") {
+					maxAllowedGB := azure.BusinessCriticalGetMaxSizeGB(capacity.(int), "Gen4")
 
 					if maxAllowedGB == 0 {
 						return fmt.Errorf("service tier 'BusinessCritical' Gen4 must have a capacity(%d) of 2, 3, 4, 5, 6, 7, 8, 9, 10, 16 or 24 vCores", capacity.(int))
 					}
 
 					if maxSizeGb.(float64) > maxAllowedGB {
-						return fmt.Errorf("service tier 'BusinessCritical' Gen4 with a capacity of %d vCores must have a max_size_gb between 5 GB and %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
+						return fmt.Errorf("service tier 'BusinessCritical' Gen4 with a capacity of %d vCores must have a 'max_size_gb' between 5 GB and %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
 					}
 				}
 
 				// Gen5 Checks
-				if strings.ToLower(family.(string)) == "gen5" {
-					maxAllowedGB := azure.BusinessCriticalGetMaxSizeGB(capacity.(int), "gen5")
+				if strings.EqualFold(family.(string), "Gen5") {
+					maxAllowedGB := azure.BusinessCriticalGetMaxSizeGB(capacity.(int), "Gen5")
 
 					if maxAllowedGB == 0 {
 						return fmt.Errorf("service tier 'BusinessCritical' Gen5 must have a capacity(%d) of 4, 6, 8, 10, 12, 14, 16, 18, 20, 24, 32, 40 or 80 vCores", capacity.(int))
 					}
 
 					if maxSizeGb.(float64) > maxAllowedGB {
-						return fmt.Errorf("service tier 'BusinessCritical' Gen5 with a capacity of %d vCores must have a max_size_gb between 5 GB and %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
+						return fmt.Errorf("service tier 'BusinessCritical' Gen5 with a capacity of %d vCores must have a 'max_size_gb' between 5 GB and %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
 					}
 				}
 			}
@@ -295,7 +295,7 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 			if strings.HasPrefix(strings.ToLower(name.(string)), "gp_") || strings.HasPrefix(strings.ToLower(name.(string)), "bc_") {
 				// vCore Based
 				if int(maxSizeGb.(float64)) < 5 {
-					return fmt.Errorf("service tier 'GeneralPurpose' and 'BusinessCritical' must have a max_size_gb value equal to or greater than 5 GB, got %d GB", int(maxSizeGb.(float64)))
+					return fmt.Errorf("service tier 'GeneralPurpose' and 'BusinessCritical' must have a 'max_size_gb' value equal to or greater than 5 GB, got %d GB", int(maxSizeGb.(float64)))
 				}
 
 				if !azure.IsIntAsBytes(maxSizeGb.(float64)) {
@@ -315,13 +315,13 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 				}
 			} else {
 				// DTU Based
-				if strings.ToLower(tier.(string)) != "basic" {
+				if strings.EqualFold(tier.(string), "Basic") {
 					if int(maxSizeGb.(float64)) < 50 {
-						return fmt.Errorf("service tiers 'Standard', and 'Premium' must have a max_size_gb value equal to or greater than 50 GB, got %d GB", int(maxSizeGb.(float64)))
+						return fmt.Errorf("service tiers 'Standard', and 'Premium' must have a 'max_size_gb' value equal to or greater than 50 GB, got %d GB", int(maxSizeGb.(float64)))
 					}
 
-					if !azure.StantardPremiumMaxGBValid(maxSizeGb.(float64)) {
-						return fmt.Errorf("max_size_gb (%d) is not a valid value, valid values are 50, 100, 150, 200, 250, 300, 400, 500, 750, 800, 1024, 1200, 1280, 1536, 1600, 1792, 2000, 2048, 2304, 2500, 2560, 2816, 3000, 3072, 3328, 3584, 3840 or 4096", int(maxSizeGb.(float64)))
+					if !azure.StandardPremiumMaxGBValid(maxSizeGb.(float64)) {
+						return fmt.Errorf("'max_size_gb'(%d) is not a valid value, valid values are 50, 100, 150, 200, 250, 300, 400, 500, 750, 800, 1024, 1200, 1280, 1536, 1600, 1792, 2000, 2048, 2304, 2500, 2560, 2816, 3000, 3072, 3328, 3584, 3840 or 4096", int(maxSizeGb.(float64)))
 					}
 				}
 
@@ -425,7 +425,7 @@ func resourceArmMsSqlElasticPoolRead(d *schema.ResourceData, meta interface{}) e
 	}
 
 	if properties := resp.ElasticPoolProperties; properties != nil {
-		d.Set("max_size_bytes", properties.MaxSizeBytes)
+		d.Set("max_size_gb", float64(*properties.MaxSizeBytes/int64(1073741824)))
 		d.Set("zone_redundant", properties.ZoneRedundant)
 
 		//todo remove in 2.0

From 028c5b136d72c4322b27ee68a44d567b7cced28d Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Fri, 18 Jan 2019 15:54:12 -0800
Subject: [PATCH 11/45] Fixed lint errors and remove helper function

---
 azurerm/helpers/azure/elasticpool.go      | 13 -------------
 azurerm/resource_arm_mssql_elasticpool.go |  4 ++--
 2 files changed, 2 insertions(+), 15 deletions(-)

diff --git a/azurerm/helpers/azure/elasticpool.go b/azurerm/helpers/azure/elasticpool.go
index f2e6bcbd583b..01fc9c7269d6 100644
--- a/azurerm/helpers/azure/elasticpool.go
+++ b/azurerm/helpers/azure/elasticpool.go
@@ -1,7 +1,6 @@
 package azure
 
 import (
-	"math"
 	"strings"
 )
 
@@ -180,18 +179,6 @@ func BusinessCriticalGetMaxSizeGB(vCores int, family string) float64 {
 	return maxGB
 }
 
-func IsIntAsBytes(maxGB float64) bool {
-	// Get the maxSizeGB for the value in bytes
-	maxBytes := 1073741824 * maxGB
-
-	// Check to see if the resulting max_size_bytes value is an integral value
-	if maxBytes != math.Trunc(maxBytes) {
-		return false
-	}
-
-	return true
-}
-
 func NameFamilyValid(name string, family string) bool {
 	return strings.Contains(strings.ToLower(name), strings.ToLower(family))
 }
diff --git a/azurerm/resource_arm_mssql_elasticpool.go b/azurerm/resource_arm_mssql_elasticpool.go
index 0fca1ff3cdb1..acfd51e59887 100644
--- a/azurerm/resource_arm_mssql_elasticpool.go
+++ b/azurerm/resource_arm_mssql_elasticpool.go
@@ -298,8 +298,8 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 					return fmt.Errorf("service tier 'GeneralPurpose' and 'BusinessCritical' must have a 'max_size_gb' value equal to or greater than 5 GB, got %d GB", int(maxSizeGb.(float64)))
 				}
 
-				if !azure.IsIntAsBytes(maxSizeGb.(float64)) {
-					return fmt.Errorf("max_size_gb (%f) is not an whole number of bytes", maxSizeGb.(float64))
+				if maxSizeGb.(float64) != math.Trunc(maxSizeGb.(float64)) {
+					return fmt.Errorf("'max_size_gb' must be a whole number, got %f GB", maxSizeGb.(float64))
 				}
 
 				if !azure.NameFamilyValid(name.(string), family.(string)) {

From ee38137a20618b69e5f6cb97e0ef4462ae8984f7 Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Fri, 18 Jan 2019 16:19:20 -0800
Subject: [PATCH 12/45] Fixed test issue

---
 azurerm/resource_arm_mssql_elasticpool.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/azurerm/resource_arm_mssql_elasticpool.go b/azurerm/resource_arm_mssql_elasticpool.go
index acfd51e59887..35cd15182888 100644
--- a/azurerm/resource_arm_mssql_elasticpool.go
+++ b/azurerm/resource_arm_mssql_elasticpool.go
@@ -315,7 +315,7 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 				}
 			} else {
 				// DTU Based
-				if strings.EqualFold(tier.(string), "Basic") {
+				if !strings.EqualFold(tier.(string), "Basic") {
 					if int(maxSizeGb.(float64)) < 50 {
 						return fmt.Errorf("service tiers 'Standard', and 'Premium' must have a 'max_size_gb' value equal to or greater than 50 GB, got %d GB", int(maxSizeGb.(float64)))
 					}

From 9635e5c41af3a0d997ae43f75346aa2894d25833 Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Fri, 18 Jan 2019 16:51:31 -0800
Subject: [PATCH 13/45] Had to special case Basic tier for setting max_size_gb

---
 azurerm/resource_arm_mssql_elasticpool.go | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/azurerm/resource_arm_mssql_elasticpool.go b/azurerm/resource_arm_mssql_elasticpool.go
index 35cd15182888..de226d683c21 100644
--- a/azurerm/resource_arm_mssql_elasticpool.go
+++ b/azurerm/resource_arm_mssql_elasticpool.go
@@ -425,7 +425,13 @@ func resourceArmMsSqlElasticPoolRead(d *schema.ResourceData, meta interface{}) e
 	}
 
 	if properties := resp.ElasticPoolProperties; properties != nil {
-		d.Set("max_size_gb", float64(*properties.MaxSizeBytes/int64(1073741824)))
+		// Basic tier does not return max_size_bytes, so we need to skip setting this
+		// value if the pricing tier is equal to Basic
+		if tier, ok := d.GetOk("sku.0.tier"); ok {
+			if !strings.EqualFold(tier.(string), "Basic") {
+				d.Set("max_size_gb", float64(*properties.MaxSizeBytes/int64(1073741824)))
+			}
+		}
 		d.Set("zone_redundant", properties.ZoneRedundant)
 
 		//todo remove in 2.0

From 4b2a43f7706007f41dfb1ff592287de2e8df01ab Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Wed, 23 Jan 2019 17:02:36 -0800
Subject: [PATCH 14/45] Added Name Tier combo validation

---
 azurerm/resource_arm_mssql_elasticpool.go | 31 +++++++++++++++--------
 1 file changed, 21 insertions(+), 10 deletions(-)

diff --git a/azurerm/resource_arm_mssql_elasticpool.go b/azurerm/resource_arm_mssql_elasticpool.go
index de226d683c21..26dda0834aef 100644
--- a/azurerm/resource_arm_mssql_elasticpool.go
+++ b/azurerm/resource_arm_mssql_elasticpool.go
@@ -225,11 +225,6 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 
 			// GeneralPurpose Checks
 			if strings.HasPrefix(strings.ToLower(name.(string)), "gp_") {
-				//General Checks
-				if !strings.EqualFold(tier.(string), "GeneralPurpose") {
-					return fmt.Errorf("SKU has a name '%s' tier '%s' mismatch, expected 'GeneralPurpose'", name.(string), tier.(string))
-				}
-
 				// Gen4 Checks
 				if strings.EqualFold(family.(string), "Gen4") {
 					maxAllowedGB := azure.GeneralPurposeGetMaxSizeGB(capacity.(int), "Gen4")
@@ -259,11 +254,6 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 
 			// BusinessCritical Checks
 			if strings.HasPrefix(strings.ToLower(name.(string)), "bc_") {
-				//General Checks
-				if !strings.EqualFold(tier.(string), "BusinessCritical") {
-					return fmt.Errorf("SKU has a name '%s' tier '%s' mismatch, expected 'BusinessCritical'", name.(string), tier.(string))
-				}
-
 				// Gen4 Checks
 				if strings.EqualFold(family.(string), "Gen4") {
 					maxAllowedGB := azure.BusinessCriticalGetMaxSizeGB(capacity.(int), "Gen4")
@@ -338,6 +328,27 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 				}
 			}
 
+			// Validate Name Tier combos for all SKUs
+			if strings.EqualFold(name.(string), "BasicPool") && !strings.EqualFold(tier.(string), "Basic") {
+				return fmt.Errorf("SKU has a name '%s' tier '%s' mismatch, expected 'tier' to be 'Basic'", name.(string), tier.(string))
+			}
+
+			if strings.EqualFold(name.(string), "StandardPool") && !strings.EqualFold(tier.(string), "Standard") {
+				return fmt.Errorf("SKU has a name '%s' tier '%s' mismatch, expected 'tier' to be 'Standard'", name.(string), tier.(string))
+			}
+
+			if strings.EqualFold(name.(string), "PremiumPool") && !strings.EqualFold(tier.(string), "Premium") {
+				return fmt.Errorf("SKU has a name '%s' tier '%s' mismatch, expected 'tier' to be 'Premium'", name.(string), tier.(string))
+			}
+
+			if strings.HasPrefix(strings.ToLower(name.(string)), "gp_") && !strings.EqualFold(tier.(string), "GeneralPurpose") {
+				return fmt.Errorf("SKU has a name '%s' tier '%s' mismatch, expected 'tier' to be 'GeneralPurpose'", name.(string), tier.(string))
+			}
+
+			if strings.HasPrefix(strings.ToLower(name.(string)), "bc_") && !strings.EqualFold(tier.(string), "BusinessCritical") {
+				return fmt.Errorf("SKU has a name '%s' tier '%s' mismatch, expected 'tier' to be 'BusinessCritical'", name.(string), tier.(string))
+			}
+
 			return nil
 		},
 	}

From 9b5352e0b6f80c2c840a2c089efe66180176188c Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Wed, 23 Jan 2019 18:01:29 -0800
Subject: [PATCH 15/45] Updated to auto-fill tier based of name attribute

---
 azurerm/helpers/azure/elasticpool.go          | 26 ++++++++++
 azurerm/helpers/suppress/string.go            | 12 +++++
 azurerm/resource_arm_mssql_elasticpool.go     | 49 +++++++++++--------
 .../docs/r/mssql_elasticpool.html.markdown    |  4 +-
 4 files changed, 69 insertions(+), 22 deletions(-)

diff --git a/azurerm/helpers/azure/elasticpool.go b/azurerm/helpers/azure/elasticpool.go
index 01fc9c7269d6..bdeb5c98dd9f 100644
--- a/azurerm/helpers/azure/elasticpool.go
+++ b/azurerm/helpers/azure/elasticpool.go
@@ -182,3 +182,29 @@ func BusinessCriticalGetMaxSizeGB(vCores int, family string) float64 {
 func NameFamilyValid(name string, family string) bool {
 	return strings.Contains(strings.ToLower(name), strings.ToLower(family))
 }
+
+func GetTier(name string) string {
+	validTier := ""
+
+	if strings.EqualFold(name, "BasicPool") {
+		validTier = "Basic"
+	}
+
+	if strings.EqualFold(name, "StandardPool") {
+		validTier = "Standard"
+	}
+
+	if strings.EqualFold(name, "PremiumPool") {
+		validTier = "Premium"
+	}
+
+	if strings.HasPrefix(strings.ToLower(name), "gp_") {
+		validTier = "GeneralPurpose"
+	}
+
+	if strings.HasPrefix(strings.ToLower(name), "bc_") {
+		validTier = "BusinessCritical"
+	}
+
+	return validTier
+}
diff --git a/azurerm/helpers/suppress/string.go b/azurerm/helpers/suppress/string.go
index 9c9615102c49..67a245ce2925 100644
--- a/azurerm/helpers/suppress/string.go
+++ b/azurerm/helpers/suppress/string.go
@@ -9,3 +9,15 @@ import (
 func CaseDifference(_, old, new string, _ *schema.ResourceData) bool {
 	return strings.ToLower(old) == strings.ToLower(new)
 }
+
+func IgnoreIfNotSet(_, old, new string, _ *schema.ResourceData) bool {
+	retBool := false
+
+	if new == "" {
+		retBool = true
+	} else {
+		retBool = strings.EqualFold(old, new)
+	}
+
+	return retBool
+}
diff --git a/azurerm/resource_arm_mssql_elasticpool.go b/azurerm/resource_arm_mssql_elasticpool.go
index 26dda0834aef..d465e8f70173 100644
--- a/azurerm/resource_arm_mssql_elasticpool.go
+++ b/azurerm/resource_arm_mssql_elasticpool.go
@@ -73,7 +73,7 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 
 						"tier": {
 							Type:     schema.TypeString,
-							Required: true,
+							Optional: true,
 							ValidateFunc: validation.StringInSlice([]string{
 								"Basic",
 								"Standard",
@@ -81,7 +81,7 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 								"GeneralPurpose",
 								"BusinessCritical",
 							}, true),
-							DiffSuppressFunc: suppress.CaseDifference,
+							DiffSuppressFunc: suppress.IgnoreIfNotSet,
 						},
 
 						"family": {
@@ -184,7 +184,7 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 			maxCapacity, _ := diff.GetOk("per_database_settings.0.max_capacity")
 
 			// Basic Checks
-			if strings.EqualFold(tier.(string), "Basic") {
+			if strings.EqualFold(name.(string), "BasicPool") {
 				maxAllowedGB := azure.BasicGetMaxSizeGB(capacity.(int))
 
 				if maxAllowedGB == 0 {
@@ -198,7 +198,7 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 			}
 
 			// Standard Checks
-			if strings.EqualFold(tier.(string), "Standard") {
+			if strings.EqualFold(name.(string), "StandardPool") {
 				maxAllowedGB := azure.StandardGetMaxSizeGB(capacity.(int))
 
 				if maxAllowedGB == 0 {
@@ -211,7 +211,7 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 			}
 
 			// Premium Checks
-			if strings.EqualFold(tier.(string), "Premium") {
+			if strings.EqualFold(name.(string), "PremiumPool") {
 				maxAllowedGB := azure.PremiumGetMaxSizeGB(capacity.(int))
 
 				if maxAllowedGB == 0 {
@@ -305,7 +305,7 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 				}
 			} else {
 				// DTU Based
-				if !strings.EqualFold(tier.(string), "Basic") {
+				if !strings.EqualFold(name.(string), "BasicPool") {
 					if int(maxSizeGb.(float64)) < 50 {
 						return fmt.Errorf("service tiers 'Standard', and 'Premium' must have a 'max_size_gb' value equal to or greater than 50 GB, got %d GB", int(maxSizeGb.(float64)))
 					}
@@ -329,24 +329,28 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 			}
 
 			// Validate Name Tier combos for all SKUs
-			if strings.EqualFold(name.(string), "BasicPool") && !strings.EqualFold(tier.(string), "Basic") {
-				return fmt.Errorf("SKU has a name '%s' tier '%s' mismatch, expected 'tier' to be 'Basic'", name.(string), tier.(string))
-			}
+			// Do not validate the tier if it is set to nothing
+			// We will auto-fill the value in the expand func
+			if tier.(string) != "" {
+				if strings.EqualFold(name.(string), "BasicPool") && !strings.EqualFold(tier.(string), "Basic") {
+					return fmt.Errorf("SKU has a name '%s' tier '%s' mismatch, expected 'tier' to be 'Basic'", name.(string), tier.(string))
+				}
 
-			if strings.EqualFold(name.(string), "StandardPool") && !strings.EqualFold(tier.(string), "Standard") {
-				return fmt.Errorf("SKU has a name '%s' tier '%s' mismatch, expected 'tier' to be 'Standard'", name.(string), tier.(string))
-			}
+				if strings.EqualFold(name.(string), "StandardPool") && !strings.EqualFold(tier.(string), "Standard") {
+					return fmt.Errorf("SKU has a name '%s' tier '%s' mismatch, expected 'tier' to be 'Standard'", name.(string), tier.(string))
+				}
 
-			if strings.EqualFold(name.(string), "PremiumPool") && !strings.EqualFold(tier.(string), "Premium") {
-				return fmt.Errorf("SKU has a name '%s' tier '%s' mismatch, expected 'tier' to be 'Premium'", name.(string), tier.(string))
-			}
+				if strings.EqualFold(name.(string), "PremiumPool") && !strings.EqualFold(tier.(string), "Premium") {
+					return fmt.Errorf("SKU has a name '%s' tier '%s' mismatch, expected 'tier' to be 'Premium'", name.(string), tier.(string))
+				}
 
-			if strings.HasPrefix(strings.ToLower(name.(string)), "gp_") && !strings.EqualFold(tier.(string), "GeneralPurpose") {
-				return fmt.Errorf("SKU has a name '%s' tier '%s' mismatch, expected 'tier' to be 'GeneralPurpose'", name.(string), tier.(string))
-			}
+				if strings.HasPrefix(strings.ToLower(name.(string)), "gp_") && !strings.EqualFold(tier.(string), "GeneralPurpose") {
+					return fmt.Errorf("SKU has a name '%s' tier '%s' mismatch, expected 'tier' to be 'GeneralPurpose'", name.(string), tier.(string))
+				}
 
-			if strings.HasPrefix(strings.ToLower(name.(string)), "bc_") && !strings.EqualFold(tier.(string), "BusinessCritical") {
-				return fmt.Errorf("SKU has a name '%s' tier '%s' mismatch, expected 'tier' to be 'BusinessCritical'", name.(string), tier.(string))
+				if strings.HasPrefix(strings.ToLower(name.(string)), "bc_") && !strings.EqualFold(tier.(string), "BusinessCritical") {
+					return fmt.Errorf("SKU has a name '%s' tier '%s' mismatch, expected 'tier' to be 'BusinessCritical'", name.(string), tier.(string))
+				}
 			}
 
 			return nil
@@ -504,6 +508,11 @@ func expandAzureRmMsSqlElasticPoolSku(d *schema.ResourceData) *sql.Sku {
 	family := sku["family"].(string)
 	capacity := sku["capacity"].(int)
 
+	// Auto fill tier based off name
+	if tier == "" {
+		tier = azure.GetTier(name)
+	}
+
 	return &sql.Sku{
 		Name:     utils.String(name),
 		Tier:     utils.String(tier),
diff --git a/website/docs/r/mssql_elasticpool.html.markdown b/website/docs/r/mssql_elasticpool.html.markdown
index ab2f7265ba96..02db30327f5f 100644
--- a/website/docs/r/mssql_elasticpool.html.markdown
+++ b/website/docs/r/mssql_elasticpool.html.markdown
@@ -76,9 +76,9 @@ The following arguments are supported:
 
 * `capacity` - (Required) The scale up/out capacity, representing server's compute units. For more information see the documentation for your Elasticpool configuration: [vCore-based](https://docs.microsoft.com/en-us/azure/sql-database/sql-database-vcore-resource-limits-elastic-pools) or [DTU-based](https://docs.microsoft.com/en-us/azure/sql-database/sql-database-dtu-resource-limits-elastic-pools).
 
-* `tier` - (Required) The tier of the particular SKU. Possible values are `GeneralPurpose`, `BusinessCritical`, `Basic`, `Standard`, or `Premium`. For more information see the documentation for your Elasticpool configuration: [vCore-based](https://docs.microsoft.com/en-us/azure/sql-database/sql-database-vcore-resource-limits-elastic-pools) or [DTU-based](https://docs.microsoft.com/en-us/azure/sql-database/sql-database-dtu-resource-limits-elastic-pools).
+* `tier` - (Optional) The tier of the particular SKU. Possible values are `GeneralPurpose`, `BusinessCritical`, `Basic`, `Standard`, or `Premium`. For more information see the documentation for your Elasticpool configuration: [vCore-based](https://docs.microsoft.com/en-us/azure/sql-database/sql-database-vcore-resource-limits-elastic-pools) or [DTU-based](https://docs.microsoft.com/en-us/azure/sql-database/sql-database-dtu-resource-limits-elastic-pools).
 
-* `family` - (Required) The `family` of hardware `Gen4` or `Gen5`.
+* `family` - (Optional) The `family` of hardware `Gen4` or `Gen5`.
 
 ---
 

From 0b5dd6d390b58a6a573e0335cf2861231a5f2743 Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Thu, 24 Jan 2019 18:55:39 -0800
Subject: [PATCH 16/45] Added auto-fill attributes for Tier and Family

---
 azurerm/helpers/azure/elasticpool.go          |  15 +++
 azurerm/resource_arm_mssql_elasticpool.go     | 109 ++++++++++--------
 .../docs/r/mssql_elasticpool.html.markdown    |   2 -
 3 files changed, 78 insertions(+), 48 deletions(-)

diff --git a/azurerm/helpers/azure/elasticpool.go b/azurerm/helpers/azure/elasticpool.go
index bdeb5c98dd9f..25c7c4d8c352 100644
--- a/azurerm/helpers/azure/elasticpool.go
+++ b/azurerm/helpers/azure/elasticpool.go
@@ -208,3 +208,18 @@ func GetTier(name string) string {
 
 	return validTier
 }
+
+func GetFamily(name string) string {
+	if !strings.HasPrefix(strings.ToLower(name), "gp_") && !strings.HasPrefix(strings.ToLower(name), "bc_") {
+		return ""
+	}
+
+	nameFamily := name[3:len(name)]
+	retFamily := "Gen4"
+
+	if strings.EqualFold(nameFamily, "Gen5") {
+		retFamily = "Gen5"
+	}
+
+	return retFamily
+}
diff --git a/azurerm/resource_arm_mssql_elasticpool.go b/azurerm/resource_arm_mssql_elasticpool.go
index d465e8f70173..9a6486e450c0 100644
--- a/azurerm/resource_arm_mssql_elasticpool.go
+++ b/azurerm/resource_arm_mssql_elasticpool.go
@@ -74,6 +74,7 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 						"tier": {
 							Type:     schema.TypeString,
 							Optional: true,
+							Default:  "",
 							ValidateFunc: validation.StringInSlice([]string{
 								"Basic",
 								"Standard",
@@ -87,11 +88,12 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 						"family": {
 							Type:     schema.TypeString,
 							Optional: true,
+							Default:  "",
 							ValidateFunc: validation.StringInSlice([]string{
 								"Gen4",
 								"Gen5",
 							}, true),
-							DiffSuppressFunc: suppress.CaseDifference,
+							DiffSuppressFunc: suppress.IgnoreIfNotSet,
 						},
 					},
 				},
@@ -176,24 +178,33 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 		CustomizeDiff: func(diff *schema.ResourceDiff, v interface{}) error {
 
 			name, _ := diff.GetOk("sku.0.name")
-			tier, _ := diff.GetOk("sku.0.tier")
+			tier, _ := diff.GetOkExists("sku.0.tier")
 			capacity, _ := diff.GetOk("sku.0.capacity")
-			family, _ := diff.GetOk("sku.0.family")
+			family, _ := diff.GetOkExists("sku.0.family")
 			maxSizeGb, _ := diff.GetOk("max_size_gb")
 			minCapacity, _ := diff.GetOk("per_database_settings.0.min_capacity")
 			maxCapacity, _ := diff.GetOk("per_database_settings.0.max_capacity")
 
+			// Set default auto-fill value for family value
+			tmpFamily := azure.GetFamily(name.(string))
+
+			// If family is deifined in the config file use that
+			// value instead of the auto-fill value
+			if family.(string) != "" {
+				tmpFamily = family.(string)
+			}
+
 			// Basic Checks
 			if strings.EqualFold(name.(string), "BasicPool") {
 				maxAllowedGB := azure.BasicGetMaxSizeGB(capacity.(int))
 
 				if maxAllowedGB == 0 {
-					return fmt.Errorf("service tier 'Basic' must have a capacity of 50, 100, 200, 300, 400, 800, 1200 or 1600 DTUs")
+					return fmt.Errorf("service tier 'Basic' must have a 'capacity'(%d) of 50, 100, 200, 300, 400, 800, 1200 or 1600 DTUs", capacity.(int))
 				}
 
 				// Basic SKU does not let you pick your max_size_GB they are fixed values
 				if maxSizeGb.(float64) != maxAllowedGB {
-					return fmt.Errorf("service tier 'Basic' with a capacity of %d must have a 'max_size_gb' of %.7f GB, got %.7f GB", capacity.(int), maxAllowedGB, maxSizeGb.(float64))
+					return fmt.Errorf("service tier 'Basic' with a 'capacity' of %d must have a 'max_size_gb' of %.7f GB, got %.7f GB", capacity.(int), maxAllowedGB, maxSizeGb.(float64))
 				}
 			}
 
@@ -202,11 +213,11 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 				maxAllowedGB := azure.StandardGetMaxSizeGB(capacity.(int))
 
 				if maxAllowedGB == 0 {
-					return fmt.Errorf("service tier 'Standard' must have a capacity(%d) of 50, 100, 200, 300, 400, 800, 1200, 1600, 2000, 2500 or 3000 DTUs", capacity.(int))
+					return fmt.Errorf("service tier 'Standard' must have a 'capacity'(%d) of 50, 100, 200, 300, 400, 800, 1200, 1600, 2000, 2500 or 3000 DTUs", capacity.(int))
 				}
 
 				if maxSizeGb.(float64) > maxAllowedGB {
-					return fmt.Errorf("service tier 'Standard' with a capacity of %d must have a 'max_size_gb' no greater than %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
+					return fmt.Errorf("service tier 'Standard' with a 'capacity' of %d must have a 'max_size_gb' no greater than %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
 				}
 			}
 
@@ -215,39 +226,39 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 				maxAllowedGB := azure.PremiumGetMaxSizeGB(capacity.(int))
 
 				if maxAllowedGB == 0 {
-					return fmt.Errorf("service tier 'Premium' must have a capacity(%d) of 125, 250, 500, 1000, 1500, 2000, 2500, 3000, 3500 or 4000 DTUs", capacity.(int))
+					return fmt.Errorf("service tier 'Premium' must have a 'capacity'(%d) of 125, 250, 500, 1000, 1500, 2000, 2500, 3000, 3500 or 4000 DTUs", capacity.(int))
 				}
 
 				if maxSizeGb.(float64) > maxAllowedGB {
-					return fmt.Errorf("service tier 'Premium' with a capacity of %d must have a 'max_size_gb' no greater than %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
+					return fmt.Errorf("service tier 'Premium' with a 'capacity' of %d must have a 'max_size_gb' no greater than %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
 				}
 			}
 
 			// GeneralPurpose Checks
 			if strings.HasPrefix(strings.ToLower(name.(string)), "gp_") {
 				// Gen4 Checks
-				if strings.EqualFold(family.(string), "Gen4") {
-					maxAllowedGB := azure.GeneralPurposeGetMaxSizeGB(capacity.(int), "Gen4")
+				if strings.EqualFold(tmpFamily, "Gen4") {
+					maxAllowedGB := azure.GeneralPurposeGetMaxSizeGB(capacity.(int), tmpFamily)
 
 					if maxAllowedGB == 0 {
-						return fmt.Errorf("service tier 'GeneralPurpose' Gen4 must have a capacity(%d) of 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 16 or 24 vCores", capacity.(int))
+						return fmt.Errorf("service tier 'GeneralPurpose' Gen4 must have a 'capacity'(%d) of 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 16 or 24 vCores", capacity.(int))
 					}
 
 					if maxSizeGb.(float64) > maxAllowedGB {
-						return fmt.Errorf("service tier 'GeneralPurpose' Gen4 with a capacity of %d vCores must have a 'max_size_gb' between 5 GB and %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
+						return fmt.Errorf("service tier 'GeneralPurpose' Gen4 with a 'capacity' of %d vCores must have a 'max_size_gb' between 5 GB and %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
 					}
 				}
 
 				// Gen5 Checks
-				if strings.EqualFold(family.(string), "Gen5") {
-					maxAllowedGB := azure.GeneralPurposeGetMaxSizeGB(capacity.(int), "Gen5")
+				if strings.EqualFold(tmpFamily, "Gen5") {
+					maxAllowedGB := azure.GeneralPurposeGetMaxSizeGB(capacity.(int), tmpFamily)
 
 					if maxAllowedGB == 0 {
-						return fmt.Errorf("service tier 'GeneralPurpose' Gen5 must have a capacity(%d) of 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 24, 32, 40 or 80 vCores", capacity.(int))
+						return fmt.Errorf("service tier 'GeneralPurpose' Gen5 must have a 'capacity'(%d) of 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 24, 32, 40 or 80 vCores", capacity.(int))
 					}
 
 					if maxSizeGb.(float64) > maxAllowedGB {
-						return fmt.Errorf("service tier 'GeneralPurpose' Gen5 with a capacity of %d vCores must have a 'max_size_gb' between 5 GB and %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
+						return fmt.Errorf("service tier 'GeneralPurpose' Gen5 with a 'capacity' of %d vCores must have a 'max_size_gb' between 5 GB and %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
 					}
 				}
 			}
@@ -255,28 +266,28 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 			// BusinessCritical Checks
 			if strings.HasPrefix(strings.ToLower(name.(string)), "bc_") {
 				// Gen4 Checks
-				if strings.EqualFold(family.(string), "Gen4") {
-					maxAllowedGB := azure.BusinessCriticalGetMaxSizeGB(capacity.(int), "Gen4")
+				if strings.EqualFold(tmpFamily, "Gen4") {
+					maxAllowedGB := azure.BusinessCriticalGetMaxSizeGB(capacity.(int), tmpFamily)
 
 					if maxAllowedGB == 0 {
-						return fmt.Errorf("service tier 'BusinessCritical' Gen4 must have a capacity(%d) of 2, 3, 4, 5, 6, 7, 8, 9, 10, 16 or 24 vCores", capacity.(int))
+						return fmt.Errorf("service tier 'BusinessCritical' Gen4 must have a 'capacity'(%d) of 2, 3, 4, 5, 6, 7, 8, 9, 10, 16 or 24 vCores", capacity.(int))
 					}
 
 					if maxSizeGb.(float64) > maxAllowedGB {
-						return fmt.Errorf("service tier 'BusinessCritical' Gen4 with a capacity of %d vCores must have a 'max_size_gb' between 5 GB and %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
+						return fmt.Errorf("service tier 'BusinessCritical' Gen4 with a 'capacity' of %d vCores must have a 'max_size_gb' between 5 GB and %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
 					}
 				}
 
 				// Gen5 Checks
-				if strings.EqualFold(family.(string), "Gen5") {
-					maxAllowedGB := azure.BusinessCriticalGetMaxSizeGB(capacity.(int), "Gen5")
+				if strings.EqualFold(tmpFamily, "Gen5") {
+					maxAllowedGB := azure.BusinessCriticalGetMaxSizeGB(capacity.(int), tmpFamily)
 
 					if maxAllowedGB == 0 {
-						return fmt.Errorf("service tier 'BusinessCritical' Gen5 must have a capacity(%d) of 4, 6, 8, 10, 12, 14, 16, 18, 20, 24, 32, 40 or 80 vCores", capacity.(int))
+						return fmt.Errorf("service tier 'BusinessCritical' Gen5 must have a 'capacity'(%d) of 4, 6, 8, 10, 12, 14, 16, 18, 20, 24, 32, 40 or 80 vCores", capacity.(int))
 					}
 
 					if maxSizeGb.(float64) > maxAllowedGB {
-						return fmt.Errorf("service tier 'BusinessCritical' Gen5 with a capacity of %d vCores must have a 'max_size_gb' between 5 GB and %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
+						return fmt.Errorf("service tier 'BusinessCritical' Gen5 with a 'capacity' of %d vCores must have a 'max_size_gb' between 5 GB and %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
 					}
 				}
 			}
@@ -292,16 +303,21 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 					return fmt.Errorf("'max_size_gb' must be a whole number, got %f GB", maxSizeGb.(float64))
 				}
 
-				if !azure.NameFamilyValid(name.(string), family.(string)) {
-					return fmt.Errorf("SKU has a name '%s' family '%s' mismatch", name.(string), family.(string))
+				// If family is not in the config skip this check
+				// we will auto-fill this attribute with the correct value
+				// in the expand func
+				if family.(string) != "" {
+					if !azure.NameFamilyValid(name.(string), family.(string)) {
+						return fmt.Errorf("Mismatch between SKU name '%s' and family '%s', expected '%s'", name.(string), family.(string), azure.GetFamily(name.(string)))
+					}
 				}
 
 				if maxCapacity.(float64) > float64(capacity.(int)) {
-					return fmt.Errorf("service tiers 'GeneralPurpose' and 'BusinessCritical' perDatabaseSettings maxCapacity must not be higher than the SKUs capacity value")
+					return fmt.Errorf("service tiers 'GeneralPurpose' and 'BusinessCritical' perDatabaseSettings maxCapacity must not be higher than the SKUs 'capacity'(%d) value", capacity.(int))
 				}
 
 				if minCapacity.(float64) > maxCapacity.(float64) {
-					return fmt.Errorf("perDatabaseSettings maxCapacity must be greater than or equal to the perDatabaseSettings minCapacity value")
+					return fmt.Errorf("perDatabaseSettings maxCapacity must be greater than or equal to the perDatabaseSettings 'minCapacity' value")
 				}
 			} else {
 				// DTU Based
@@ -315,41 +331,45 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 					}
 				}
 
+				if family.(string) != "" {
+					return fmt.Errorf("Invalid attribute 'family' (%s) for service tiers 'Basic', 'Standard', and 'Premium', remove the 'family' attribute from the configuration file", family.(string))
+				}
+
 				if maxCapacity.(float64) != math.Trunc(maxCapacity.(float64)) {
-					return fmt.Errorf("service tiers 'Basic', 'Standard', and 'Premium' must have whole numbers as their maxCapacity")
+					return fmt.Errorf("service tiers 'Basic', 'Standard', and 'Premium' must have whole numbers as their 'maxCapacity'")
 				}
 
 				if minCapacity.(float64) != math.Trunc(minCapacity.(float64)) {
-					return fmt.Errorf("service tiers 'Basic', 'Standard', and 'Premium' must have whole numbers as their minCapacity")
+					return fmt.Errorf("service tiers 'Basic', 'Standard', and 'Premium' must have whole numbers as their 'minCapacity'")
 				}
 
 				if minCapacity.(float64) < 0.0 {
-					return fmt.Errorf("service tiers 'Basic', 'Standard', and 'Premium' per_database_settings min_capacity must be equal to or greater than zero")
+					return fmt.Errorf("service tiers 'Basic', 'Standard', and 'Premium' per_database_settings 'min_capacity' must be equal to or greater than zero")
 				}
 			}
 
 			// Validate Name Tier combos for all SKUs
-			// Do not validate the tier if it is set to nothing
+			// Do not validate the tier if it is empty
 			// We will auto-fill the value in the expand func
 			if tier.(string) != "" {
 				if strings.EqualFold(name.(string), "BasicPool") && !strings.EqualFold(tier.(string), "Basic") {
-					return fmt.Errorf("SKU has a name '%s' tier '%s' mismatch, expected 'tier' to be 'Basic'", name.(string), tier.(string))
+					return fmt.Errorf("Mismatch between SKU name '%s' and tier '%s', expected 'tier' to be 'Basic'", name.(string), tier.(string))
 				}
 
 				if strings.EqualFold(name.(string), "StandardPool") && !strings.EqualFold(tier.(string), "Standard") {
-					return fmt.Errorf("SKU has a name '%s' tier '%s' mismatch, expected 'tier' to be 'Standard'", name.(string), tier.(string))
+					return fmt.Errorf("Mismatch between SKU name '%s' and tier '%s', expected 'tier' to be 'Standard'", name.(string), tier.(string))
 				}
 
 				if strings.EqualFold(name.(string), "PremiumPool") && !strings.EqualFold(tier.(string), "Premium") {
-					return fmt.Errorf("SKU has a name '%s' tier '%s' mismatch, expected 'tier' to be 'Premium'", name.(string), tier.(string))
+					return fmt.Errorf("Mismatch between SKU name '%s' and tier '%s', expected 'tier' to be 'Premium'", name.(string), tier.(string))
 				}
 
 				if strings.HasPrefix(strings.ToLower(name.(string)), "gp_") && !strings.EqualFold(tier.(string), "GeneralPurpose") {
-					return fmt.Errorf("SKU has a name '%s' tier '%s' mismatch, expected 'tier' to be 'GeneralPurpose'", name.(string), tier.(string))
+					return fmt.Errorf("Mismatch between SKU name '%s' and tier '%s', expected 'tier' to be 'GeneralPurpose'", name.(string), tier.(string))
 				}
 
 				if strings.HasPrefix(strings.ToLower(name.(string)), "bc_") && !strings.EqualFold(tier.(string), "BusinessCritical") {
-					return fmt.Errorf("SKU has a name '%s' tier '%s' mismatch, expected 'tier' to be 'BusinessCritical'", name.(string), tier.(string))
+					return fmt.Errorf("Mismatch between SKU name '%s' tier '%s', expected 'tier' to be 'BusinessCritical'", name.(string), tier.(string))
 				}
 			}
 
@@ -513,6 +533,11 @@ func expandAzureRmMsSqlElasticPoolSku(d *schema.ResourceData) *sql.Sku {
 		tier = azure.GetTier(name)
 	}
 
+	// Auto fill family based off name
+	if family == "" {
+		family = azure.GetFamily(name)
+	}
+
 	return &sql.Sku{
 		Name:     utils.String(name),
 		Tier:     utils.String(tier),
@@ -528,14 +553,6 @@ func flattenAzureRmMsSqlElasticPoolSku(resp *sql.Sku) []interface{} {
 		values["name"] = *name
 	}
 
-	if tier := resp.Tier; tier != nil {
-		values["tier"] = *tier
-	}
-
-	if family := resp.Family; family != nil {
-		values["family"] = *family
-	}
-
 	if capacity := resp.Capacity; capacity != nil {
 		values["capacity"] = *capacity
 	}
diff --git a/website/docs/r/mssql_elasticpool.html.markdown b/website/docs/r/mssql_elasticpool.html.markdown
index 02db30327f5f..19bc786d3b41 100644
--- a/website/docs/r/mssql_elasticpool.html.markdown
+++ b/website/docs/r/mssql_elasticpool.html.markdown
@@ -37,8 +37,6 @@ resource "azurerm_mssql_elasticpool" "test" {
   sku {
     name     = "GP_Gen5"
     capacity = 4
-    tier     = "GeneralPurpose"
-    family   = "Gen5"
   }
 
   per_database_settings {

From 8a86194aaa5dd1570d80dab2956611ecee1e27db Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Thu, 24 Jan 2019 19:06:53 -0800
Subject: [PATCH 17/45] Added Test cases for DTU and vCore autofill

---
 .../resource_arm_mssql_elasticpool_test.go    | 141 ++++++++++++++++++
 1 file changed, 141 insertions(+)

diff --git a/azurerm/resource_arm_mssql_elasticpool_test.go b/azurerm/resource_arm_mssql_elasticpool_test.go
index e3254c2c06fb..89a9184b0aed 100644
--- a/azurerm/resource_arm_mssql_elasticpool_test.go
+++ b/azurerm/resource_arm_mssql_elasticpool_test.go
@@ -37,6 +37,33 @@ func TestAccAzureRMMsSqlElasticPool_basic_DTU(t *testing.T) {
 	})
 }
 
+func TestAccAzureRMMsSqlElasticPool_basic_DTU_AutoFill(t *testing.T) {
+	resourceName := "azurerm_mssql_elasticpool.test"
+	ri := tf.AccRandTimeInt()
+	config := testAccAzureRMMsSqlElasticPool_basic_DTU_AutoFill(ri, testLocation())
+
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck:     func() { testAccPreCheck(t) },
+		Providers:    testAccProviders,
+		CheckDestroy: testCheckAzureRMMsSqlElasticPoolDestroy,
+		Steps: []resource.TestStep{
+			{
+				Config: config,
+				Check: resource.ComposeTestCheckFunc(
+					testCheckAzureRMMsSqlElasticPoolExists(resourceName),
+					resource.TestCheckResourceAttr(resourceName, "sku.0.name", "BasicPool"),
+					resource.TestCheckResourceAttr(resourceName, "sku.0.tier", "Basic"),
+					resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "50"),
+					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.min_capacity", "0"),
+					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.max_capacity", "5"),
+					resource.TestCheckResourceAttrSet(resourceName, "max_size_gb"),
+					resource.TestCheckResourceAttrSet(resourceName, "zone_redundant"),
+				),
+			},
+		},
+	})
+}
+
 func TestAccAzureRMMsSqlElasticPool_standard_DTU(t *testing.T) {
 	resourceName := "azurerm_mssql_elasticpool.test"
 	ri := tf.AccRandTimeInt()
@@ -104,6 +131,40 @@ func TestAccAzureRMMsSqlElasticPool_basic_vCore(t *testing.T) {
 	})
 }
 
+func TestAccAzureRMMsSqlElasticPool_basic_vCore_AutoFill(t *testing.T) {
+	resourceName := "azurerm_mssql_elasticpool.test"
+	ri := tf.AccRandTimeInt()
+	config := testAccAzureRMMsSqlElasticPool_basic_vCore_AutoFill(ri, testLocation())
+
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck:     func() { testAccPreCheck(t) },
+		Providers:    testAccProviders,
+		CheckDestroy: testCheckAzureRMMsSqlElasticPoolDestroy,
+		Steps: []resource.TestStep{
+			{
+				Config: config,
+				Check: resource.ComposeTestCheckFunc(
+					testCheckAzureRMMsSqlElasticPoolExists(resourceName),
+					resource.TestCheckResourceAttr(resourceName, "sku.0.name", "GP_Gen5"),
+					resource.TestCheckResourceAttr(resourceName, "sku.0.tier", "GeneralPurpose"),
+					resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "4"),
+					resource.TestCheckResourceAttr(resourceName, "sku.0.family", "Gen5"),
+					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.min_capacity", "0.25"),
+					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.max_capacity", "4"),
+					resource.TestCheckResourceAttrSet(resourceName, "max_size_gb"),
+					resource.TestCheckResourceAttrSet(resourceName, "zone_redundant"),
+				),
+			},
+			{
+				ResourceName:            resourceName,
+				ImportState:             true,
+				ImportStateVerify:       true,
+				ImportStateVerifyIgnore: []string{"max_size_gb"},
+			},
+		},
+	})
+}
+
 func TestAccAzureRMMsSqlElasticPool_disappears(t *testing.T) {
 	resourceName := "azurerm_mssql_elasticpool.test"
 	ri := tf.AccRandTimeInt()
@@ -289,6 +350,10 @@ func testAccAzureRMMsSqlElasticPool_basic_DTU(rInt int, location string) string
 	return testAccAzureRMMsSqlElasticPool_DTU_Template(rInt, location, "BasicPool", "Basic", 50, 4.8828125, 0, 5)
 }
 
+func testAccAzureRMMsSqlElasticPool_basic_DTU_AutoFill(rInt int, location string) string {
+	return testAccAzureRMMsSqlElasticPool_DTU_AutoFill_Template(rInt, location, "BasicPool", 50, 4.8828125, 0, 5)
+}
+
 func testAccAzureRMMsSqlElasticPool_standard_DTU(rInt int, location string) string {
 	return testAccAzureRMMsSqlElasticPool_DTU_Template(rInt, location, "StandardPool", "Standard", 50, 50, 0, 50)
 }
@@ -301,6 +366,10 @@ func testAccAzureRMMsSqlElasticPool_basic_vCore(rInt int, location string) strin
 	return testAccAzureRMMsSqlElasticPool_vCore_Template(rInt, location, "GP_Gen5", "GeneralPurpose", 4, "Gen5", 0.25, 4)
 }
 
+func testAccAzureRMMsSqlElasticPool_basic_vCore_AutoFill(rInt int, location string) string {
+	return testAccAzureRMMsSqlElasticPool_vCore_AutoFill_Template(rInt, location, "GP_Gen5", 4, 0.25, 4)
+}
+
 func testAccAzureRMMsSqlElasticPool_resize_vCore(rInt int, location string) string {
 	return testAccAzureRMMsSqlElasticPool_vCore_Template(rInt, location, "GP_Gen5", "GeneralPurpose", 8, "Gen5", 0, 8)
 }
@@ -343,6 +412,42 @@ resource "azurerm_mssql_elasticpool" "test" {
 `, rInt, location, skuName, skuTier, skuCapacity, skuFamily, databaseSettingsMin, databaseSettingsMax)
 }
 
+func testAccAzureRMMsSqlElasticPool_vCore_AutoFill_Template(rInt int, location string, skuName string, skuCapacity int, databaseSettingsMin float64, databaseSettingsMax float64) string {
+	return fmt.Sprintf(`
+resource "azurerm_resource_group" "test" {
+  name     = "acctestRG-%[1]d"
+  location = "%s"
+}
+
+resource "azurerm_sql_server" "test" {
+  name                         = "acctest%[1]d"
+  resource_group_name          = "${azurerm_resource_group.test.name}"
+  location                     = "${azurerm_resource_group.test.location}"
+  version                      = "12.0"
+  administrator_login          = "4dm1n157r470r"
+  administrator_login_password = "4-v3ry-53cr37-p455w0rd"
+}
+
+resource "azurerm_mssql_elasticpool" "test" {
+  name                = "acctest-pool-vcore-%[1]d"
+  resource_group_name = "${azurerm_resource_group.test.name}"
+  location            = "${azurerm_resource_group.test.location}"
+  server_name         = "${azurerm_sql_server.test.name}"
+  max_size_gb         = 5
+
+  sku {
+    name     = "%[3]s"
+    capacity = %[4]d
+  }
+
+  per_database_settings {
+    min_capacity = %.2[5]f
+    max_capacity = %.2[6]f
+  }
+}
+`, rInt, location, skuName, skuCapacity, databaseSettingsMin, databaseSettingsMax)
+}
+
 func testAccAzureRMMsSqlElasticPool_DTU_Template(rInt int, location string, skuName string, skuTier string, skuCapacity int, maxSizeGB float64, databaseSettingsMin int, databaseSettingsMax int) string {
 	return fmt.Sprintf(`
 resource "azurerm_resource_group" "test" {
@@ -379,3 +484,39 @@ resource "azurerm_mssql_elasticpool" "test" {
 }
 `, rInt, location, skuName, skuTier, skuCapacity, maxSizeGB, databaseSettingsMin, databaseSettingsMax)
 }
+
+func testAccAzureRMMsSqlElasticPool_DTU_AutoFill_Template(rInt int, location string, skuName string, skuCapacity int, maxSizeGB float64, databaseSettingsMin int, databaseSettingsMax int) string {
+	return fmt.Sprintf(`
+resource "azurerm_resource_group" "test" {
+  name     = "acctestRG-%[1]d"
+  location = "%s"
+}
+
+resource "azurerm_sql_server" "test" {
+  name                         = "acctest%[1]d"
+  resource_group_name          = "${azurerm_resource_group.test.name}"
+  location                     = "${azurerm_resource_group.test.location}"
+  version                      = "12.0"
+  administrator_login          = "4dm1n157r470r"
+  administrator_login_password = "4-v3ry-53cr37-p455w0rd"
+}
+
+resource "azurerm_mssql_elasticpool" "test" {
+  name                = "acctest-pool-dtu-%[1]d"
+  resource_group_name = "${azurerm_resource_group.test.name}"
+  location            = "${azurerm_resource_group.test.location}"
+  server_name         = "${azurerm_sql_server.test.name}"
+  max_size_gb         = %.7[5]f
+  
+  sku {
+    name     = "%[3]s"
+    capacity = %[4]d
+  }
+
+  per_database_settings {
+    min_capacity = %[6]d
+    max_capacity = %[7]d
+  }
+}
+`, rInt, location, skuName, skuCapacity, maxSizeGB, databaseSettingsMin, databaseSettingsMax)
+}

From 2c4cb793eb5ab04aaa5f0537d72566aaef6838b1 Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Thu, 24 Jan 2019 19:11:11 -0800
Subject: [PATCH 18/45] Update for lint errors

---
 azurerm/helpers/azure/elasticpool.go | 2 +-
 azurerm/helpers/suppress/string.go   | 8 +++-----
 2 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/azurerm/helpers/azure/elasticpool.go b/azurerm/helpers/azure/elasticpool.go
index 25c7c4d8c352..eaef9351ab69 100644
--- a/azurerm/helpers/azure/elasticpool.go
+++ b/azurerm/helpers/azure/elasticpool.go
@@ -214,7 +214,7 @@ func GetFamily(name string) string {
 		return ""
 	}
 
-	nameFamily := name[3:len(name)]
+	nameFamily := name[3:]
 	retFamily := "Gen4"
 
 	if strings.EqualFold(nameFamily, "Gen5") {
diff --git a/azurerm/helpers/suppress/string.go b/azurerm/helpers/suppress/string.go
index 67a245ce2925..1a7cb4f179b0 100644
--- a/azurerm/helpers/suppress/string.go
+++ b/azurerm/helpers/suppress/string.go
@@ -11,13 +11,11 @@ func CaseDifference(_, old, new string, _ *schema.ResourceData) bool {
 }
 
 func IgnoreIfNotSet(_, old, new string, _ *schema.ResourceData) bool {
-	retBool := false
-
 	if new == "" {
-		retBool = true
+		return true
 	} else {
-		retBool = strings.EqualFold(old, new)
+		return strings.EqualFold(old, new)
 	}
 
-	return retBool
+	return false
 }

From a589be8484bf98267e81663656d216c3d37ce078 Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Thu, 24 Jan 2019 19:30:26 -0800
Subject: [PATCH 19/45] Update tests

---
 .../resource_arm_mssql_elasticpool_test.go    | 28 +++++++++----------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/azurerm/resource_arm_mssql_elasticpool_test.go b/azurerm/resource_arm_mssql_elasticpool_test.go
index 89a9184b0aed..1df2e3296b98 100644
--- a/azurerm/resource_arm_mssql_elasticpool_test.go
+++ b/azurerm/resource_arm_mssql_elasticpool_test.go
@@ -25,10 +25,10 @@ func TestAccAzureRMMsSqlElasticPool_basic_DTU(t *testing.T) {
 				Check: resource.ComposeTestCheckFunc(
 					testCheckAzureRMMsSqlElasticPoolExists(resourceName),
 					resource.TestCheckResourceAttr(resourceName, "sku.0.name", "BasicPool"),
-					resource.TestCheckResourceAttr(resourceName, "sku.0.tier", "Basic"),
 					resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "50"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.min_capacity", "0"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.max_capacity", "5"),
+					resource.TestCheckResourceAttrSet(resourceName, "sku.0.tier"),
 					resource.TestCheckResourceAttrSet(resourceName, "max_size_gb"),
 					resource.TestCheckResourceAttrSet(resourceName, "zone_redundant"),
 				),
@@ -52,10 +52,10 @@ func TestAccAzureRMMsSqlElasticPool_basic_DTU_AutoFill(t *testing.T) {
 				Check: resource.ComposeTestCheckFunc(
 					testCheckAzureRMMsSqlElasticPoolExists(resourceName),
 					resource.TestCheckResourceAttr(resourceName, "sku.0.name", "BasicPool"),
-					resource.TestCheckResourceAttr(resourceName, "sku.0.tier", "Basic"),
 					resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "50"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.min_capacity", "0"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.max_capacity", "5"),
+					resource.TestCheckResourceAttrSet(resourceName, "sku.0.tier"),
 					resource.TestCheckResourceAttrSet(resourceName, "max_size_gb"),
 					resource.TestCheckResourceAttrSet(resourceName, "zone_redundant"),
 				),
@@ -79,10 +79,10 @@ func TestAccAzureRMMsSqlElasticPool_standard_DTU(t *testing.T) {
 				Check: resource.ComposeTestCheckFunc(
 					testCheckAzureRMMsSqlElasticPoolExists(resourceName),
 					resource.TestCheckResourceAttr(resourceName, "sku.0.name", "StandardPool"),
-					resource.TestCheckResourceAttr(resourceName, "sku.0.tier", "Standard"),
 					resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "50"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.min_capacity", "0"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.max_capacity", "50"),
+					resource.TestCheckResourceAttrSet(resourceName, "sku.0.tier"),
 					resource.TestCheckResourceAttrSet(resourceName, "max_size_gb"),
 					resource.TestCheckResourceAttrSet(resourceName, "zone_redundant"),
 				),
@@ -112,11 +112,11 @@ func TestAccAzureRMMsSqlElasticPool_basic_vCore(t *testing.T) {
 				Check: resource.ComposeTestCheckFunc(
 					testCheckAzureRMMsSqlElasticPoolExists(resourceName),
 					resource.TestCheckResourceAttr(resourceName, "sku.0.name", "GP_Gen5"),
-					resource.TestCheckResourceAttr(resourceName, "sku.0.tier", "GeneralPurpose"),
 					resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "4"),
-					resource.TestCheckResourceAttr(resourceName, "sku.0.family", "Gen5"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.min_capacity", "0.25"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.max_capacity", "4"),
+					resource.TestCheckResourceAttrSet(resourceName, "sku.0.tier"),
+					resource.TestCheckResourceAttrSet(resourceName, "sku.0.family"),
 					resource.TestCheckResourceAttrSet(resourceName, "max_size_gb"),
 					resource.TestCheckResourceAttrSet(resourceName, "zone_redundant"),
 				),
@@ -146,11 +146,11 @@ func TestAccAzureRMMsSqlElasticPool_basic_vCore_AutoFill(t *testing.T) {
 				Check: resource.ComposeTestCheckFunc(
 					testCheckAzureRMMsSqlElasticPoolExists(resourceName),
 					resource.TestCheckResourceAttr(resourceName, "sku.0.name", "GP_Gen5"),
-					resource.TestCheckResourceAttr(resourceName, "sku.0.tier", "GeneralPurpose"),
 					resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "4"),
-					resource.TestCheckResourceAttr(resourceName, "sku.0.family", "Gen5"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.min_capacity", "0.25"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.max_capacity", "4"),
+					resource.TestCheckResourceAttrSet(resourceName, "sku.0.tier"),
+					resource.TestCheckResourceAttrSet(resourceName, "sku.0.family"),
 					resource.TestCheckResourceAttrSet(resourceName, "max_size_gb"),
 					resource.TestCheckResourceAttrSet(resourceName, "zone_redundant"),
 				),
@@ -180,10 +180,10 @@ func TestAccAzureRMMsSqlElasticPool_disappears(t *testing.T) {
 				Check: resource.ComposeTestCheckFunc(
 					testCheckAzureRMMsSqlElasticPoolExists(resourceName),
 					resource.TestCheckResourceAttr(resourceName, "sku.0.name", "StandardPool"),
-					resource.TestCheckResourceAttr(resourceName, "sku.0.tier", "Standard"),
 					resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "50"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.min_capacity", "0"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.max_capacity", "50"),
+					resource.TestCheckResourceAttrSet(resourceName, "sku.0.tier"),
 					testCheckAzureRMMsSqlElasticPoolDisappears(resourceName),
 				),
 				ExpectNonEmptyPlan: true,
@@ -209,10 +209,10 @@ func TestAccAzureRMMsSqlElasticPool_resize_DTU(t *testing.T) {
 				Check: resource.ComposeTestCheckFunc(
 					testCheckAzureRMMsSqlElasticPoolExists(resourceName),
 					resource.TestCheckResourceAttr(resourceName, "sku.0.name", "StandardPool"),
-					resource.TestCheckResourceAttr(resourceName, "sku.0.tier", "Standard"),
 					resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "50"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.min_capacity", "0"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.max_capacity", "50"),
+					resource.TestCheckResourceAttrSet(resourceName, "sku.0.tier"),
 				),
 			},
 			{
@@ -220,10 +220,10 @@ func TestAccAzureRMMsSqlElasticPool_resize_DTU(t *testing.T) {
 				Check: resource.ComposeTestCheckFunc(
 					testCheckAzureRMMsSqlElasticPoolExists(resourceName),
 					resource.TestCheckResourceAttr(resourceName, "sku.0.name", "StandardPool"),
-					resource.TestCheckResourceAttr(resourceName, "sku.0.tier", "Standard"),
 					resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "100"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.min_capacity", "50"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.max_capacity", "100"),
+					resource.TestCheckResourceAttrSet(resourceName, "sku.0.tier"),
 				),
 			},
 		},
@@ -247,11 +247,11 @@ func TestAccAzureRMMsSqlElasticPool_resize_vCore(t *testing.T) {
 				Check: resource.ComposeTestCheckFunc(
 					testCheckAzureRMMsSqlElasticPoolExists(resourceName),
 					resource.TestCheckResourceAttr(resourceName, "sku.0.name", "GP_Gen5"),
-					resource.TestCheckResourceAttr(resourceName, "sku.0.tier", "GeneralPurpose"),
 					resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "4"),
-					resource.TestCheckResourceAttr(resourceName, "sku.0.family", "Gen5"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.min_capacity", "0.25"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.max_capacity", "4"),
+					resource.TestCheckResourceAttrSet(resourceName, "sku.0.tier"),
+					resource.TestCheckResourceAttrSet(resourceName, "sku.0.family"),
 				),
 			},
 			{
@@ -259,11 +259,11 @@ func TestAccAzureRMMsSqlElasticPool_resize_vCore(t *testing.T) {
 				Check: resource.ComposeTestCheckFunc(
 					testCheckAzureRMMsSqlElasticPoolExists(resourceName),
 					resource.TestCheckResourceAttr(resourceName, "sku.0.name", "GP_Gen5"),
-					resource.TestCheckResourceAttr(resourceName, "sku.0.tier", "GeneralPurpose"),
 					resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "8"),
-					resource.TestCheckResourceAttr(resourceName, "sku.0.family", "Gen5"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.min_capacity", "0"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.max_capacity", "8"),
+					resource.TestCheckResourceAttrSet(resourceName, "sku.0.tier"),
+					resource.TestCheckResourceAttrSet(resourceName, "sku.0.family"),
 				),
 			},
 		},

From 41f04b5b388e013b916487e0b04b4fd117d4acd2 Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Thu, 24 Jan 2019 19:44:54 -0800
Subject: [PATCH 20/45] Fixed test cases

---
 azurerm/resource_arm_mssql_elasticpool_test.go | 14 --------------
 1 file changed, 14 deletions(-)

diff --git a/azurerm/resource_arm_mssql_elasticpool_test.go b/azurerm/resource_arm_mssql_elasticpool_test.go
index 1df2e3296b98..313e5bb0e322 100644
--- a/azurerm/resource_arm_mssql_elasticpool_test.go
+++ b/azurerm/resource_arm_mssql_elasticpool_test.go
@@ -28,7 +28,6 @@ func TestAccAzureRMMsSqlElasticPool_basic_DTU(t *testing.T) {
 					resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "50"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.min_capacity", "0"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.max_capacity", "5"),
-					resource.TestCheckResourceAttrSet(resourceName, "sku.0.tier"),
 					resource.TestCheckResourceAttrSet(resourceName, "max_size_gb"),
 					resource.TestCheckResourceAttrSet(resourceName, "zone_redundant"),
 				),
@@ -55,7 +54,6 @@ func TestAccAzureRMMsSqlElasticPool_basic_DTU_AutoFill(t *testing.T) {
 					resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "50"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.min_capacity", "0"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.max_capacity", "5"),
-					resource.TestCheckResourceAttrSet(resourceName, "sku.0.tier"),
 					resource.TestCheckResourceAttrSet(resourceName, "max_size_gb"),
 					resource.TestCheckResourceAttrSet(resourceName, "zone_redundant"),
 				),
@@ -82,7 +80,6 @@ func TestAccAzureRMMsSqlElasticPool_standard_DTU(t *testing.T) {
 					resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "50"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.min_capacity", "0"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.max_capacity", "50"),
-					resource.TestCheckResourceAttrSet(resourceName, "sku.0.tier"),
 					resource.TestCheckResourceAttrSet(resourceName, "max_size_gb"),
 					resource.TestCheckResourceAttrSet(resourceName, "zone_redundant"),
 				),
@@ -115,8 +112,6 @@ func TestAccAzureRMMsSqlElasticPool_basic_vCore(t *testing.T) {
 					resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "4"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.min_capacity", "0.25"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.max_capacity", "4"),
-					resource.TestCheckResourceAttrSet(resourceName, "sku.0.tier"),
-					resource.TestCheckResourceAttrSet(resourceName, "sku.0.family"),
 					resource.TestCheckResourceAttrSet(resourceName, "max_size_gb"),
 					resource.TestCheckResourceAttrSet(resourceName, "zone_redundant"),
 				),
@@ -149,8 +144,6 @@ func TestAccAzureRMMsSqlElasticPool_basic_vCore_AutoFill(t *testing.T) {
 					resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "4"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.min_capacity", "0.25"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.max_capacity", "4"),
-					resource.TestCheckResourceAttrSet(resourceName, "sku.0.tier"),
-					resource.TestCheckResourceAttrSet(resourceName, "sku.0.family"),
 					resource.TestCheckResourceAttrSet(resourceName, "max_size_gb"),
 					resource.TestCheckResourceAttrSet(resourceName, "zone_redundant"),
 				),
@@ -183,7 +176,6 @@ func TestAccAzureRMMsSqlElasticPool_disappears(t *testing.T) {
 					resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "50"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.min_capacity", "0"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.max_capacity", "50"),
-					resource.TestCheckResourceAttrSet(resourceName, "sku.0.tier"),
 					testCheckAzureRMMsSqlElasticPoolDisappears(resourceName),
 				),
 				ExpectNonEmptyPlan: true,
@@ -212,7 +204,6 @@ func TestAccAzureRMMsSqlElasticPool_resize_DTU(t *testing.T) {
 					resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "50"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.min_capacity", "0"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.max_capacity", "50"),
-					resource.TestCheckResourceAttrSet(resourceName, "sku.0.tier"),
 				),
 			},
 			{
@@ -223,7 +214,6 @@ func TestAccAzureRMMsSqlElasticPool_resize_DTU(t *testing.T) {
 					resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "100"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.min_capacity", "50"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.max_capacity", "100"),
-					resource.TestCheckResourceAttrSet(resourceName, "sku.0.tier"),
 				),
 			},
 		},
@@ -250,8 +240,6 @@ func TestAccAzureRMMsSqlElasticPool_resize_vCore(t *testing.T) {
 					resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "4"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.min_capacity", "0.25"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.max_capacity", "4"),
-					resource.TestCheckResourceAttrSet(resourceName, "sku.0.tier"),
-					resource.TestCheckResourceAttrSet(resourceName, "sku.0.family"),
 				),
 			},
 			{
@@ -262,8 +250,6 @@ func TestAccAzureRMMsSqlElasticPool_resize_vCore(t *testing.T) {
 					resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "8"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.min_capacity", "0"),
 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.max_capacity", "8"),
-					resource.TestCheckResourceAttrSet(resourceName, "sku.0.tier"),
-					resource.TestCheckResourceAttrSet(resourceName, "sku.0.family"),
 				),
 			},
 		},

From 0507be0994fde4259e5f95f9c3bc1306d39e8a77 Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Thu, 24 Jan 2019 20:00:10 -0800
Subject: [PATCH 21/45] Fix Lint error

---
 azurerm/helpers/suppress/string.go | 2 --
 1 file changed, 2 deletions(-)

diff --git a/azurerm/helpers/suppress/string.go b/azurerm/helpers/suppress/string.go
index 1a7cb4f179b0..1f9768433f18 100644
--- a/azurerm/helpers/suppress/string.go
+++ b/azurerm/helpers/suppress/string.go
@@ -16,6 +16,4 @@ func IgnoreIfNotSet(_, old, new string, _ *schema.ResourceData) bool {
 	} else {
 		return strings.EqualFold(old, new)
 	}
-
-	return false
 }

From 08522c48d42bd1bfdd6bde6b24fff5a61939dc13 Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Thu, 24 Jan 2019 20:11:51 -0800
Subject: [PATCH 22/45] Updated GetOkExists to GetOk

---
 azurerm/resource_arm_mssql_elasticpool.go | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/azurerm/resource_arm_mssql_elasticpool.go b/azurerm/resource_arm_mssql_elasticpool.go
index 9a6486e450c0..68773161ba62 100644
--- a/azurerm/resource_arm_mssql_elasticpool.go
+++ b/azurerm/resource_arm_mssql_elasticpool.go
@@ -178,9 +178,9 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 		CustomizeDiff: func(diff *schema.ResourceDiff, v interface{}) error {
 
 			name, _ := diff.GetOk("sku.0.name")
-			tier, _ := diff.GetOkExists("sku.0.tier")
+			tier, _ := diff.GetOk("sku.0.tier")
 			capacity, _ := diff.GetOk("sku.0.capacity")
-			family, _ := diff.GetOkExists("sku.0.family")
+			family, _ := diff.GetOk("sku.0.family")
 			maxSizeGb, _ := diff.GetOk("max_size_gb")
 			minCapacity, _ := diff.GetOk("per_database_settings.0.min_capacity")
 			maxCapacity, _ := diff.GetOk("per_database_settings.0.max_capacity")

From 70d8638fe532d48f09d924965d84fdde038cbec1 Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Fri, 25 Jan 2019 11:19:17 -0800
Subject: [PATCH 23/45] Revert Auto-fill functionality

---
 azurerm/resource_arm_mssql_elasticpool.go     |  82 +++++++------
 .../resource_arm_mssql_elasticpool_test.go    | 116 +++++++++---------
 .../docs/r/mssql_elasticpool.html.markdown    |   4 +-
 3 files changed, 108 insertions(+), 94 deletions(-)

diff --git a/azurerm/resource_arm_mssql_elasticpool.go b/azurerm/resource_arm_mssql_elasticpool.go
index 68773161ba62..97c8bc6a2b24 100644
--- a/azurerm/resource_arm_mssql_elasticpool.go
+++ b/azurerm/resource_arm_mssql_elasticpool.go
@@ -73,8 +73,7 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 
 						"tier": {
 							Type:     schema.TypeString,
-							Optional: true,
-							Default:  "",
+							Required: true,
 							ValidateFunc: validation.StringInSlice([]string{
 								"Basic",
 								"Standard",
@@ -82,18 +81,17 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 								"GeneralPurpose",
 								"BusinessCritical",
 							}, true),
-							DiffSuppressFunc: suppress.IgnoreIfNotSet,
+							DiffSuppressFunc: suppress.CaseDifference,
 						},
 
 						"family": {
 							Type:     schema.TypeString,
 							Optional: true,
-							Default:  "",
 							ValidateFunc: validation.StringInSlice([]string{
 								"Gen4",
 								"Gen5",
 							}, true),
-							DiffSuppressFunc: suppress.IgnoreIfNotSet,
+							DiffSuppressFunc: suppress.CaseDifference,
 						},
 					},
 				},
@@ -186,13 +184,13 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 			maxCapacity, _ := diff.GetOk("per_database_settings.0.max_capacity")
 
 			// Set default auto-fill value for family value
-			tmpFamily := azure.GetFamily(name.(string))
+			//tmpFamily := azure.GetFamily(name.(string))
 
 			// If family is deifined in the config file use that
 			// value instead of the auto-fill value
-			if family.(string) != "" {
-				tmpFamily = family.(string)
-			}
+			//if family.(string) != "" {
+			tmpFamily := family.(string)
+			//}
 
 			// Basic Checks
 			if strings.EqualFold(name.(string), "BasicPool") {
@@ -306,11 +304,11 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 				// If family is not in the config skip this check
 				// we will auto-fill this attribute with the correct value
 				// in the expand func
-				if family.(string) != "" {
-					if !azure.NameFamilyValid(name.(string), family.(string)) {
-						return fmt.Errorf("Mismatch between SKU name '%s' and family '%s', expected '%s'", name.(string), family.(string), azure.GetFamily(name.(string)))
-					}
+				// if family.(string) != "" {
+				if !azure.NameFamilyValid(name.(string), family.(string)) {
+					return fmt.Errorf("Mismatch between SKU name '%s' and family '%s', expected '%s'", name.(string), family.(string), azure.GetFamily(name.(string)))
 				}
+				// }
 
 				if maxCapacity.(float64) > float64(capacity.(int)) {
 					return fmt.Errorf("service tiers 'GeneralPurpose' and 'BusinessCritical' perDatabaseSettings maxCapacity must not be higher than the SKUs 'capacity'(%d) value", capacity.(int))
@@ -351,27 +349,27 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 			// Validate Name Tier combos for all SKUs
 			// Do not validate the tier if it is empty
 			// We will auto-fill the value in the expand func
-			if tier.(string) != "" {
-				if strings.EqualFold(name.(string), "BasicPool") && !strings.EqualFold(tier.(string), "Basic") {
-					return fmt.Errorf("Mismatch between SKU name '%s' and tier '%s', expected 'tier' to be 'Basic'", name.(string), tier.(string))
-				}
+			// if tier.(string) != "" {
+			if strings.EqualFold(name.(string), "BasicPool") && !strings.EqualFold(tier.(string), "Basic") {
+				return fmt.Errorf("Mismatch between SKU name '%s' and tier '%s', expected 'tier' to be 'Basic'", name.(string), tier.(string))
+			}
 
-				if strings.EqualFold(name.(string), "StandardPool") && !strings.EqualFold(tier.(string), "Standard") {
-					return fmt.Errorf("Mismatch between SKU name '%s' and tier '%s', expected 'tier' to be 'Standard'", name.(string), tier.(string))
-				}
+			if strings.EqualFold(name.(string), "StandardPool") && !strings.EqualFold(tier.(string), "Standard") {
+				return fmt.Errorf("Mismatch between SKU name '%s' and tier '%s', expected 'tier' to be 'Standard'", name.(string), tier.(string))
+			}
 
-				if strings.EqualFold(name.(string), "PremiumPool") && !strings.EqualFold(tier.(string), "Premium") {
-					return fmt.Errorf("Mismatch between SKU name '%s' and tier '%s', expected 'tier' to be 'Premium'", name.(string), tier.(string))
-				}
+			if strings.EqualFold(name.(string), "PremiumPool") && !strings.EqualFold(tier.(string), "Premium") {
+				return fmt.Errorf("Mismatch between SKU name '%s' and tier '%s', expected 'tier' to be 'Premium'", name.(string), tier.(string))
+			}
 
-				if strings.HasPrefix(strings.ToLower(name.(string)), "gp_") && !strings.EqualFold(tier.(string), "GeneralPurpose") {
-					return fmt.Errorf("Mismatch between SKU name '%s' and tier '%s', expected 'tier' to be 'GeneralPurpose'", name.(string), tier.(string))
-				}
+			if strings.HasPrefix(strings.ToLower(name.(string)), "gp_") && !strings.EqualFold(tier.(string), "GeneralPurpose") {
+				return fmt.Errorf("Mismatch between SKU name '%s' and tier '%s', expected 'tier' to be 'GeneralPurpose'", name.(string), tier.(string))
+			}
 
-				if strings.HasPrefix(strings.ToLower(name.(string)), "bc_") && !strings.EqualFold(tier.(string), "BusinessCritical") {
-					return fmt.Errorf("Mismatch between SKU name '%s' tier '%s', expected 'tier' to be 'BusinessCritical'", name.(string), tier.(string))
-				}
+			if strings.HasPrefix(strings.ToLower(name.(string)), "bc_") && !strings.EqualFold(tier.(string), "BusinessCritical") {
+				return fmt.Errorf("Mismatch between SKU name '%s' tier '%s', expected 'tier' to be 'BusinessCritical'", name.(string), tier.(string))
 			}
+			// }
 
 			return nil
 		},
@@ -528,15 +526,17 @@ func expandAzureRmMsSqlElasticPoolSku(d *schema.ResourceData) *sql.Sku {
 	family := sku["family"].(string)
 	capacity := sku["capacity"].(int)
 
-	// Auto fill tier based off name
-	if tier == "" {
-		tier = azure.GetTier(name)
-	}
+	// Leaving code here for release in 2.0
 
-	// Auto fill family based off name
-	if family == "" {
-		family = azure.GetFamily(name)
-	}
+	// // Auto fill tier based off name
+	// if tier == "" {
+	// 	tier = azure.GetTier(name)
+	// }
+
+	// // Auto fill family based off name
+	// if family == "" {
+	// 	family = azure.GetFamily(name)
+	// }
 
 	return &sql.Sku{
 		Name:     utils.String(name),
@@ -553,6 +553,14 @@ func flattenAzureRmMsSqlElasticPoolSku(resp *sql.Sku) []interface{} {
 		values["name"] = *name
 	}
 
+	if tier := resp.Tier; tier != nil {
+		values["tier"] = *tier
+	}
+
+	if family := resp.Family; family != nil {
+		values["family"] = *family
+	}
+
 	if capacity := resp.Capacity; capacity != nil {
 		values["capacity"] = *capacity
 	}
diff --git a/azurerm/resource_arm_mssql_elasticpool_test.go b/azurerm/resource_arm_mssql_elasticpool_test.go
index 313e5bb0e322..33d30d56e0f6 100644
--- a/azurerm/resource_arm_mssql_elasticpool_test.go
+++ b/azurerm/resource_arm_mssql_elasticpool_test.go
@@ -36,31 +36,33 @@ func TestAccAzureRMMsSqlElasticPool_basic_DTU(t *testing.T) {
 	})
 }
 
-func TestAccAzureRMMsSqlElasticPool_basic_DTU_AutoFill(t *testing.T) {
-	resourceName := "azurerm_mssql_elasticpool.test"
-	ri := tf.AccRandTimeInt()
-	config := testAccAzureRMMsSqlElasticPool_basic_DTU_AutoFill(ri, testLocation())
-
-	resource.ParallelTest(t, resource.TestCase{
-		PreCheck:     func() { testAccPreCheck(t) },
-		Providers:    testAccProviders,
-		CheckDestroy: testCheckAzureRMMsSqlElasticPoolDestroy,
-		Steps: []resource.TestStep{
-			{
-				Config: config,
-				Check: resource.ComposeTestCheckFunc(
-					testCheckAzureRMMsSqlElasticPoolExists(resourceName),
-					resource.TestCheckResourceAttr(resourceName, "sku.0.name", "BasicPool"),
-					resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "50"),
-					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.min_capacity", "0"),
-					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.max_capacity", "5"),
-					resource.TestCheckResourceAttrSet(resourceName, "max_size_gb"),
-					resource.TestCheckResourceAttrSet(resourceName, "zone_redundant"),
-				),
-			},
-		},
-	})
-}
+// Leaving this code here for release in 2.0
+
+// func TestAccAzureRMMsSqlElasticPool_basic_DTU_AutoFill(t *testing.T) {
+// 	resourceName := "azurerm_mssql_elasticpool.test"
+// 	ri := tf.AccRandTimeInt()
+// 	config := testAccAzureRMMsSqlElasticPool_basic_DTU_AutoFill(ri, testLocation())
+
+// 	resource.ParallelTest(t, resource.TestCase{
+// 		PreCheck:     func() { testAccPreCheck(t) },
+// 		Providers:    testAccProviders,
+// 		CheckDestroy: testCheckAzureRMMsSqlElasticPoolDestroy,
+// 		Steps: []resource.TestStep{
+// 			{
+// 				Config: config,
+// 				Check: resource.ComposeTestCheckFunc(
+// 					testCheckAzureRMMsSqlElasticPoolExists(resourceName),
+// 					resource.TestCheckResourceAttr(resourceName, "sku.0.name", "BasicPool"),
+// 					resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "50"),
+// 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.min_capacity", "0"),
+// 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.max_capacity", "5"),
+// 					resource.TestCheckResourceAttrSet(resourceName, "max_size_gb"),
+// 					resource.TestCheckResourceAttrSet(resourceName, "zone_redundant"),
+// 				),
+// 			},
+// 		},
+// 	})
+// }
 
 func TestAccAzureRMMsSqlElasticPool_standard_DTU(t *testing.T) {
 	resourceName := "azurerm_mssql_elasticpool.test"
@@ -126,37 +128,39 @@ func TestAccAzureRMMsSqlElasticPool_basic_vCore(t *testing.T) {
 	})
 }
 
-func TestAccAzureRMMsSqlElasticPool_basic_vCore_AutoFill(t *testing.T) {
-	resourceName := "azurerm_mssql_elasticpool.test"
-	ri := tf.AccRandTimeInt()
-	config := testAccAzureRMMsSqlElasticPool_basic_vCore_AutoFill(ri, testLocation())
-
-	resource.ParallelTest(t, resource.TestCase{
-		PreCheck:     func() { testAccPreCheck(t) },
-		Providers:    testAccProviders,
-		CheckDestroy: testCheckAzureRMMsSqlElasticPoolDestroy,
-		Steps: []resource.TestStep{
-			{
-				Config: config,
-				Check: resource.ComposeTestCheckFunc(
-					testCheckAzureRMMsSqlElasticPoolExists(resourceName),
-					resource.TestCheckResourceAttr(resourceName, "sku.0.name", "GP_Gen5"),
-					resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "4"),
-					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.min_capacity", "0.25"),
-					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.max_capacity", "4"),
-					resource.TestCheckResourceAttrSet(resourceName, "max_size_gb"),
-					resource.TestCheckResourceAttrSet(resourceName, "zone_redundant"),
-				),
-			},
-			{
-				ResourceName:            resourceName,
-				ImportState:             true,
-				ImportStateVerify:       true,
-				ImportStateVerifyIgnore: []string{"max_size_gb"},
-			},
-		},
-	})
-}
+// Leaving this code here for release in 2.0
+
+// func TestAccAzureRMMsSqlElasticPool_basic_vCore_AutoFill(t *testing.T) {
+// 	resourceName := "azurerm_mssql_elasticpool.test"
+// 	ri := tf.AccRandTimeInt()
+// 	config := testAccAzureRMMsSqlElasticPool_basic_vCore_AutoFill(ri, testLocation())
+
+// 	resource.ParallelTest(t, resource.TestCase{
+// 		PreCheck:     func() { testAccPreCheck(t) },
+// 		Providers:    testAccProviders,
+// 		CheckDestroy: testCheckAzureRMMsSqlElasticPoolDestroy,
+// 		Steps: []resource.TestStep{
+// 			{
+// 				Config: config,
+// 				Check: resource.ComposeTestCheckFunc(
+// 					testCheckAzureRMMsSqlElasticPoolExists(resourceName),
+// 					resource.TestCheckResourceAttr(resourceName, "sku.0.name", "GP_Gen5"),
+// 					resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "4"),
+// 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.min_capacity", "0.25"),
+// 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.max_capacity", "4"),
+// 					resource.TestCheckResourceAttrSet(resourceName, "max_size_gb"),
+// 					resource.TestCheckResourceAttrSet(resourceName, "zone_redundant"),
+// 				),
+// 			},
+// 			{
+// 				ResourceName:            resourceName,
+// 				ImportState:             true,
+// 				ImportStateVerify:       true,
+// 				ImportStateVerifyIgnore: []string{"max_size_gb"},
+// 			},
+// 		},
+// 	})
+// }
 
 func TestAccAzureRMMsSqlElasticPool_disappears(t *testing.T) {
 	resourceName := "azurerm_mssql_elasticpool.test"
diff --git a/website/docs/r/mssql_elasticpool.html.markdown b/website/docs/r/mssql_elasticpool.html.markdown
index 19bc786d3b41..50210e302048 100644
--- a/website/docs/r/mssql_elasticpool.html.markdown
+++ b/website/docs/r/mssql_elasticpool.html.markdown
@@ -36,6 +36,8 @@ resource "azurerm_mssql_elasticpool" "test" {
 
   sku {
     name     = "GP_Gen5"
+    tier     = "GeneralPurpose"
+    family   = "Gen5"
     capacity = 4
   }
 
@@ -74,7 +76,7 @@ The following arguments are supported:
 
 * `capacity` - (Required) The scale up/out capacity, representing server's compute units. For more information see the documentation for your Elasticpool configuration: [vCore-based](https://docs.microsoft.com/en-us/azure/sql-database/sql-database-vcore-resource-limits-elastic-pools) or [DTU-based](https://docs.microsoft.com/en-us/azure/sql-database/sql-database-dtu-resource-limits-elastic-pools).
 
-* `tier` - (Optional) The tier of the particular SKU. Possible values are `GeneralPurpose`, `BusinessCritical`, `Basic`, `Standard`, or `Premium`. For more information see the documentation for your Elasticpool configuration: [vCore-based](https://docs.microsoft.com/en-us/azure/sql-database/sql-database-vcore-resource-limits-elastic-pools) or [DTU-based](https://docs.microsoft.com/en-us/azure/sql-database/sql-database-dtu-resource-limits-elastic-pools).
+* `tier` - (Required) The tier of the particular SKU. Possible values are `GeneralPurpose`, `BusinessCritical`, `Basic`, `Standard`, or `Premium`. For more information see the documentation for your Elasticpool configuration: [vCore-based](https://docs.microsoft.com/en-us/azure/sql-database/sql-database-vcore-resource-limits-elastic-pools) or [DTU-based](https://docs.microsoft.com/en-us/azure/sql-database/sql-database-dtu-resource-limits-elastic-pools).
 
 * `family` - (Optional) The `family` of hardware `Gen4` or `Gen5`.
 

From dd7d9684ced19726040fa86805d2c8a137707535 Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Fri, 25 Jan 2019 14:20:58 -0800
Subject: [PATCH 24/45] Fixing up after merge from master

---
 .../resource_arm_mssql_elasticpool_test.go    | 28 +++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/azurerm/resource_arm_mssql_elasticpool_test.go b/azurerm/resource_arm_mssql_elasticpool_test.go
index 162ba92e0918..e7759b4c5835 100644
--- a/azurerm/resource_arm_mssql_elasticpool_test.go
+++ b/azurerm/resource_arm_mssql_elasticpool_test.go
@@ -37,6 +37,34 @@ func TestAccAzureRMMsSqlElasticPool_basic_DTU(t *testing.T) {
 	})
 }
 
+// Leaving this code here for release in 2.0
+
+// func TestAccAzureRMMsSqlElasticPool_basic_DTU_AutoFill(t *testing.T) {
+// 	resourceName := "azurerm_mssql_elasticpool.test"
+// 	ri := tf.AccRandTimeInt()
+// 	config := testAccAzureRMMsSqlElasticPool_basic_DTU_AutoFill(ri, testLocation())
+
+// 	resource.ParallelTest(t, resource.TestCase{
+// 		PreCheck:     func() { testAccPreCheck(t) },
+// 		Providers:    testAccProviders,
+// 		CheckDestroy: testCheckAzureRMMsSqlElasticPoolDestroy,
+// 		Steps: []resource.TestStep{
+// 			{
+// 				Config: config,
+// 				Check: resource.ComposeTestCheckFunc(
+// 					testCheckAzureRMMsSqlElasticPoolExists(resourceName),
+// 					resource.TestCheckResourceAttr(resourceName, "sku.0.name", "BasicPool"),
+// 					resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "50"),
+// 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.min_capacity", "0"),
+// 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.max_capacity", "5"),
+// 					resource.TestCheckResourceAttrSet(resourceName, "max_size_gb"),
+// 					resource.TestCheckResourceAttrSet(resourceName, "zone_redundant"),
+// 				),
+// 			},
+// 		},
+// 	})
+// }
+
 func TestAccAzureRMMsSqlElasticPool_requiresImport(t *testing.T) {
 	if !requireResourcesToBeImported {
 		t.Skip("Skipping since resources aren't required to be imported")

From eb2f5d2e1b2bb8d4a9ceba37a030a18f4a6f7ee2 Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Fri, 25 Jan 2019 14:36:01 -0800
Subject: [PATCH 25/45] Fix lint errors

---
 .../resource_arm_mssql_elasticpool_test.go    | 144 +++++++++---------
 1 file changed, 72 insertions(+), 72 deletions(-)

diff --git a/azurerm/resource_arm_mssql_elasticpool_test.go b/azurerm/resource_arm_mssql_elasticpool_test.go
index e7759b4c5835..7f1dfc9c1e12 100644
--- a/azurerm/resource_arm_mssql_elasticpool_test.go
+++ b/azurerm/resource_arm_mssql_elasticpool_test.go
@@ -370,9 +370,9 @@ func testAccAzureRMMsSqlElasticPool_basic_DTU(rInt int, location string) string
 	return testAccAzureRMMsSqlElasticPool_DTU_Template(rInt, location, "BasicPool", "Basic", 50, 4.8828125, 0, 5)
 }
 
-func testAccAzureRMMsSqlElasticPool_basic_DTU_AutoFill(rInt int, location string) string {
-	return testAccAzureRMMsSqlElasticPool_DTU_AutoFill_Template(rInt, location, "BasicPool", 50, 4.8828125, 0, 5)
-}
+// func testAccAzureRMMsSqlElasticPool_basic_DTU_AutoFill(rInt int, location string) string {
+// 	return testAccAzureRMMsSqlElasticPool_DTU_AutoFill_Template(rInt, location, "BasicPool", 50, 4.8828125, 0, 5)
+// }
 
 func testAccAzureRMMsSqlElasticPool_requiresImport(rInt int, location string) string {
 	template := testAccAzureRMMsSqlElasticPool_DTU_Template(rInt, location, "BasicPool", "Basic", 50, 5242880000, 0, 5)
@@ -403,9 +403,9 @@ func testAccAzureRMMsSqlElasticPool_basic_vCore(rInt int, location string) strin
 	return testAccAzureRMMsSqlElasticPool_vCore_Template(rInt, location, "GP_Gen5", "GeneralPurpose", 4, "Gen5", 0.25, 4)
 }
 
-func testAccAzureRMMsSqlElasticPool_basic_vCore_AutoFill(rInt int, location string) string {
-	return testAccAzureRMMsSqlElasticPool_vCore_AutoFill_Template(rInt, location, "GP_Gen5", 4, 0.25, 4)
-}
+// func testAccAzureRMMsSqlElasticPool_basic_vCore_AutoFill(rInt int, location string) string {
+// 	return testAccAzureRMMsSqlElasticPool_vCore_AutoFill_Template(rInt, location, "GP_Gen5", 4, 0.25, 4)
+// }
 
 func testAccAzureRMMsSqlElasticPool_resize_vCore(rInt int, location string) string {
 	return testAccAzureRMMsSqlElasticPool_vCore_Template(rInt, location, "GP_Gen5", "GeneralPurpose", 8, "Gen5", 0, 8)
@@ -449,41 +449,41 @@ resource "azurerm_mssql_elasticpool" "test" {
 `, rInt, location, skuName, skuTier, skuCapacity, skuFamily, databaseSettingsMin, databaseSettingsMax)
 }
 
-func testAccAzureRMMsSqlElasticPool_vCore_AutoFill_Template(rInt int, location string, skuName string, skuCapacity int, databaseSettingsMin float64, databaseSettingsMax float64) string {
-	return fmt.Sprintf(`
-resource "azurerm_resource_group" "test" {
-  name     = "acctestRG-%[1]d"
-  location = "%s"
-}
-
-resource "azurerm_sql_server" "test" {
-  name                         = "acctest%[1]d"
-  resource_group_name          = "${azurerm_resource_group.test.name}"
-  location                     = "${azurerm_resource_group.test.location}"
-  version                      = "12.0"
-  administrator_login          = "4dm1n157r470r"
-  administrator_login_password = "4-v3ry-53cr37-p455w0rd"
-}
-
-resource "azurerm_mssql_elasticpool" "test" {
-  name                = "acctest-pool-vcore-%[1]d"
-  resource_group_name = "${azurerm_resource_group.test.name}"
-  location            = "${azurerm_resource_group.test.location}"
-  server_name         = "${azurerm_sql_server.test.name}"
-  max_size_gb         = 5
+// func testAccAzureRMMsSqlElasticPool_vCore_AutoFill_Template(rInt int, location string, skuName string, skuCapacity int, databaseSettingsMin float64, databaseSettingsMax float64) string {
+// 	return fmt.Sprintf(`
+// resource "azurerm_resource_group" "test" {
+//   name     = "acctestRG-%[1]d"
+//   location = "%s"
+// }
 
-  sku {
-    name     = "%[3]s"
-    capacity = %[4]d
-  }
+// resource "azurerm_sql_server" "test" {
+//   name                         = "acctest%[1]d"
+//   resource_group_name          = "${azurerm_resource_group.test.name}"
+//   location                     = "${azurerm_resource_group.test.location}"
+//   version                      = "12.0"
+//   administrator_login          = "4dm1n157r470r"
+//   administrator_login_password = "4-v3ry-53cr37-p455w0rd"
+// }
 
-  per_database_settings {
-    min_capacity = %.2[5]f
-    max_capacity = %.2[6]f
-  }
-}
-`, rInt, location, skuName, skuCapacity, databaseSettingsMin, databaseSettingsMax)
-}
+// resource "azurerm_mssql_elasticpool" "test" {
+//   name                = "acctest-pool-vcore-%[1]d"
+//   resource_group_name = "${azurerm_resource_group.test.name}"
+//   location            = "${azurerm_resource_group.test.location}"
+//   server_name         = "${azurerm_sql_server.test.name}"
+//   max_size_gb         = 5
+
+//   sku {
+//     name     = "%[3]s"
+//     capacity = %[4]d
+//   }
+
+//   per_database_settings {
+//     min_capacity = %.2[5]f
+//     max_capacity = %.2[6]f
+//   }
+// }
+// `, rInt, location, skuName, skuCapacity, databaseSettingsMin, databaseSettingsMax)
+// }
 
 func testAccAzureRMMsSqlElasticPool_DTU_Template(rInt int, location string, skuName string, skuTier string, skuCapacity int, maxSizeGB float64, databaseSettingsMin int, databaseSettingsMax int) string {
 	return fmt.Sprintf(`
@@ -522,38 +522,38 @@ resource "azurerm_mssql_elasticpool" "test" {
 `, rInt, location, skuName, skuTier, skuCapacity, maxSizeGB, databaseSettingsMin, databaseSettingsMax)
 }
 
-func testAccAzureRMMsSqlElasticPool_DTU_AutoFill_Template(rInt int, location string, skuName string, skuCapacity int, maxSizeGB float64, databaseSettingsMin int, databaseSettingsMax int) string {
-	return fmt.Sprintf(`
-resource "azurerm_resource_group" "test" {
-  name     = "acctestRG-%[1]d"
-  location = "%s"
-}
-
-resource "azurerm_sql_server" "test" {
-  name                         = "acctest%[1]d"
-  resource_group_name          = "${azurerm_resource_group.test.name}"
-  location                     = "${azurerm_resource_group.test.location}"
-  version                      = "12.0"
-  administrator_login          = "4dm1n157r470r"
-  administrator_login_password = "4-v3ry-53cr37-p455w0rd"
-}
+// func testAccAzureRMMsSqlElasticPool_DTU_AutoFill_Template(rInt int, location string, skuName string, skuCapacity int, maxSizeGB float64, databaseSettingsMin int, databaseSettingsMax int) string {
+// 	return fmt.Sprintf(`
+// resource "azurerm_resource_group" "test" {
+//   name     = "acctestRG-%[1]d"
+//   location = "%s"
+// }
 
-resource "azurerm_mssql_elasticpool" "test" {
-  name                = "acctest-pool-dtu-%[1]d"
-  resource_group_name = "${azurerm_resource_group.test.name}"
-  location            = "${azurerm_resource_group.test.location}"
-  server_name         = "${azurerm_sql_server.test.name}"
-  max_size_gb         = %.7[5]f
-  
-  sku {
-    name     = "%[3]s"
-    capacity = %[4]d
-  }
+// resource "azurerm_sql_server" "test" {
+//   name                         = "acctest%[1]d"
+//   resource_group_name          = "${azurerm_resource_group.test.name}"
+//   location                     = "${azurerm_resource_group.test.location}"
+//   version                      = "12.0"
+//   administrator_login          = "4dm1n157r470r"
+//   administrator_login_password = "4-v3ry-53cr37-p455w0rd"
+// }
 
-  per_database_settings {
-    min_capacity = %[6]d
-    max_capacity = %[7]d
-  }
-}
-`, rInt, location, skuName, skuCapacity, maxSizeGB, databaseSettingsMin, databaseSettingsMax)
-}
+// resource "azurerm_mssql_elasticpool" "test" {
+//   name                = "acctest-pool-dtu-%[1]d"
+//   resource_group_name = "${azurerm_resource_group.test.name}"
+//   location            = "${azurerm_resource_group.test.location}"
+//   server_name         = "${azurerm_sql_server.test.name}"
+//   max_size_gb         = %.7[5]f
+
+//   sku {
+//     name     = "%[3]s"
+//     capacity = %[4]d
+//   }
+
+//   per_database_settings {
+//     min_capacity = %[6]d
+//     max_capacity = %[7]d
+//   }
+// }
+// `, rInt, location, skuName, skuCapacity, maxSizeGB, databaseSettingsMin, databaseSettingsMax)
+// }

From faf2c8e523bc6f475d66ad2106db9a27ae4d2899 Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Fri, 25 Jan 2019 15:40:53 -0800
Subject: [PATCH 26/45] Removed commented code

---
 azurerm/resource_arm_mssql_elasticpool.go     |  47 +-----
 .../resource_arm_mssql_elasticpool_test.go    | 142 ------------------
 2 files changed, 8 insertions(+), 181 deletions(-)

diff --git a/azurerm/resource_arm_mssql_elasticpool.go b/azurerm/resource_arm_mssql_elasticpool.go
index d9107dcd7c53..4ca5fee72ec9 100644
--- a/azurerm/resource_arm_mssql_elasticpool.go
+++ b/azurerm/resource_arm_mssql_elasticpool.go
@@ -184,15 +184,6 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 			minCapacity, _ := diff.GetOk("per_database_settings.0.min_capacity")
 			maxCapacity, _ := diff.GetOk("per_database_settings.0.max_capacity")
 
-			// Set default auto-fill value for family value
-			//tmpFamily := azure.GetFamily(name.(string))
-
-			// If family is deifined in the config file use that
-			// value instead of the auto-fill value
-			//if family.(string) != "" {
-			tmpFamily := family.(string)
-			//}
-
 			// Basic Checks
 			if strings.EqualFold(name.(string), "BasicPool") {
 				maxAllowedGB := azure.BasicGetMaxSizeGB(capacity.(int))
@@ -236,8 +227,8 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 			// GeneralPurpose Checks
 			if strings.HasPrefix(strings.ToLower(name.(string)), "gp_") {
 				// Gen4 Checks
-				if strings.EqualFold(tmpFamily, "Gen4") {
-					maxAllowedGB := azure.GeneralPurposeGetMaxSizeGB(capacity.(int), tmpFamily)
+				if strings.EqualFold(family.(string), "Gen4") {
+					maxAllowedGB := azure.GeneralPurposeGetMaxSizeGB(capacity.(int), family.(string))
 
 					if maxAllowedGB == 0 {
 						return fmt.Errorf("service tier 'GeneralPurpose' Gen4 must have a 'capacity'(%d) of 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 16 or 24 vCores", capacity.(int))
@@ -249,8 +240,8 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 				}
 
 				// Gen5 Checks
-				if strings.EqualFold(tmpFamily, "Gen5") {
-					maxAllowedGB := azure.GeneralPurposeGetMaxSizeGB(capacity.(int), tmpFamily)
+				if strings.EqualFold(family.(string), "Gen5") {
+					maxAllowedGB := azure.GeneralPurposeGetMaxSizeGB(capacity.(int), family.(string))
 
 					if maxAllowedGB == 0 {
 						return fmt.Errorf("service tier 'GeneralPurpose' Gen5 must have a 'capacity'(%d) of 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 24, 32, 40 or 80 vCores", capacity.(int))
@@ -265,8 +256,8 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 			// BusinessCritical Checks
 			if strings.HasPrefix(strings.ToLower(name.(string)), "bc_") {
 				// Gen4 Checks
-				if strings.EqualFold(tmpFamily, "Gen4") {
-					maxAllowedGB := azure.BusinessCriticalGetMaxSizeGB(capacity.(int), tmpFamily)
+				if strings.EqualFold(family.(string), "Gen4") {
+					maxAllowedGB := azure.BusinessCriticalGetMaxSizeGB(capacity.(int), family.(string))
 
 					if maxAllowedGB == 0 {
 						return fmt.Errorf("service tier 'BusinessCritical' Gen4 must have a 'capacity'(%d) of 2, 3, 4, 5, 6, 7, 8, 9, 10, 16 or 24 vCores", capacity.(int))
@@ -278,8 +269,8 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 				}
 
 				// Gen5 Checks
-				if strings.EqualFold(tmpFamily, "Gen5") {
-					maxAllowedGB := azure.BusinessCriticalGetMaxSizeGB(capacity.(int), tmpFamily)
+				if strings.EqualFold(family.(string), "Gen5") {
+					maxAllowedGB := azure.BusinessCriticalGetMaxSizeGB(capacity.(int), family.(string))
 
 					if maxAllowedGB == 0 {
 						return fmt.Errorf("service tier 'BusinessCritical' Gen5 must have a 'capacity'(%d) of 4, 6, 8, 10, 12, 14, 16, 18, 20, 24, 32, 40 or 80 vCores", capacity.(int))
@@ -302,14 +293,9 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 					return fmt.Errorf("'max_size_gb' must be a whole number, got %f GB", maxSizeGb.(float64))
 				}
 
-				// If family is not in the config skip this check
-				// we will auto-fill this attribute with the correct value
-				// in the expand func
-				// if family.(string) != "" {
 				if !azure.NameFamilyValid(name.(string), family.(string)) {
 					return fmt.Errorf("Mismatch between SKU name '%s' and family '%s', expected '%s'", name.(string), family.(string), azure.GetFamily(name.(string)))
 				}
-				// }
 
 				if maxCapacity.(float64) > float64(capacity.(int)) {
 					return fmt.Errorf("service tiers 'GeneralPurpose' and 'BusinessCritical' perDatabaseSettings maxCapacity must not be higher than the SKUs 'capacity'(%d) value", capacity.(int))
@@ -347,10 +333,6 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 				}
 			}
 
-			// Validate Name Tier combos for all SKUs
-			// Do not validate the tier if it is empty
-			// We will auto-fill the value in the expand func
-			// if tier.(string) != "" {
 			if strings.EqualFold(name.(string), "BasicPool") && !strings.EqualFold(tier.(string), "Basic") {
 				return fmt.Errorf("Mismatch between SKU name '%s' and tier '%s', expected 'tier' to be 'Basic'", name.(string), tier.(string))
 			}
@@ -370,7 +352,6 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 			if strings.HasPrefix(strings.ToLower(name.(string)), "bc_") && !strings.EqualFold(tier.(string), "BusinessCritical") {
 				return fmt.Errorf("Mismatch between SKU name '%s' tier '%s', expected 'tier' to be 'BusinessCritical'", name.(string), tier.(string))
 			}
-			// }
 
 			return nil
 		},
@@ -541,18 +522,6 @@ func expandAzureRmMsSqlElasticPoolSku(d *schema.ResourceData) *sql.Sku {
 	family := sku["family"].(string)
 	capacity := sku["capacity"].(int)
 
-	// Leaving code here for release in 2.0
-
-	// // Auto fill tier based off name
-	// if tier == "" {
-	// 	tier = azure.GetTier(name)
-	// }
-
-	// // Auto fill family based off name
-	// if family == "" {
-	// 	family = azure.GetFamily(name)
-	// }
-
 	return &sql.Sku{
 		Name:     utils.String(name),
 		Tier:     utils.String(tier),
diff --git a/azurerm/resource_arm_mssql_elasticpool_test.go b/azurerm/resource_arm_mssql_elasticpool_test.go
index 7f1dfc9c1e12..a022c068056b 100644
--- a/azurerm/resource_arm_mssql_elasticpool_test.go
+++ b/azurerm/resource_arm_mssql_elasticpool_test.go
@@ -37,34 +37,6 @@ func TestAccAzureRMMsSqlElasticPool_basic_DTU(t *testing.T) {
 	})
 }
 
-// Leaving this code here for release in 2.0
-
-// func TestAccAzureRMMsSqlElasticPool_basic_DTU_AutoFill(t *testing.T) {
-// 	resourceName := "azurerm_mssql_elasticpool.test"
-// 	ri := tf.AccRandTimeInt()
-// 	config := testAccAzureRMMsSqlElasticPool_basic_DTU_AutoFill(ri, testLocation())
-
-// 	resource.ParallelTest(t, resource.TestCase{
-// 		PreCheck:     func() { testAccPreCheck(t) },
-// 		Providers:    testAccProviders,
-// 		CheckDestroy: testCheckAzureRMMsSqlElasticPoolDestroy,
-// 		Steps: []resource.TestStep{
-// 			{
-// 				Config: config,
-// 				Check: resource.ComposeTestCheckFunc(
-// 					testCheckAzureRMMsSqlElasticPoolExists(resourceName),
-// 					resource.TestCheckResourceAttr(resourceName, "sku.0.name", "BasicPool"),
-// 					resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "50"),
-// 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.min_capacity", "0"),
-// 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.max_capacity", "5"),
-// 					resource.TestCheckResourceAttrSet(resourceName, "max_size_gb"),
-// 					resource.TestCheckResourceAttrSet(resourceName, "zone_redundant"),
-// 				),
-// 			},
-// 		},
-// 	})
-// }
-
 func TestAccAzureRMMsSqlElasticPool_requiresImport(t *testing.T) {
 	if !requireResourcesToBeImported {
 		t.Skip("Skipping since resources aren't required to be imported")
@@ -158,40 +130,6 @@ func TestAccAzureRMMsSqlElasticPool_basic_vCore(t *testing.T) {
 	})
 }
 
-// Leaving this code here for release in 2.0
-
-// func TestAccAzureRMMsSqlElasticPool_basic_vCore_AutoFill(t *testing.T) {
-// 	resourceName := "azurerm_mssql_elasticpool.test"
-// 	ri := tf.AccRandTimeInt()
-// 	config := testAccAzureRMMsSqlElasticPool_basic_vCore_AutoFill(ri, testLocation())
-
-// 	resource.ParallelTest(t, resource.TestCase{
-// 		PreCheck:     func() { testAccPreCheck(t) },
-// 		Providers:    testAccProviders,
-// 		CheckDestroy: testCheckAzureRMMsSqlElasticPoolDestroy,
-// 		Steps: []resource.TestStep{
-// 			{
-// 				Config: config,
-// 				Check: resource.ComposeTestCheckFunc(
-// 					testCheckAzureRMMsSqlElasticPoolExists(resourceName),
-// 					resource.TestCheckResourceAttr(resourceName, "sku.0.name", "GP_Gen5"),
-// 					resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "4"),
-// 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.min_capacity", "0.25"),
-// 					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.max_capacity", "4"),
-// 					resource.TestCheckResourceAttrSet(resourceName, "max_size_gb"),
-// 					resource.TestCheckResourceAttrSet(resourceName, "zone_redundant"),
-// 				),
-// 			},
-// 			{
-// 				ResourceName:            resourceName,
-// 				ImportState:             true,
-// 				ImportStateVerify:       true,
-// 				ImportStateVerifyIgnore: []string{"max_size_gb"},
-// 			},
-// 		},
-// 	})
-// }
-
 func TestAccAzureRMMsSqlElasticPool_disappears(t *testing.T) {
 	resourceName := "azurerm_mssql_elasticpool.test"
 	ri := tf.AccRandTimeInt()
@@ -370,10 +308,6 @@ func testAccAzureRMMsSqlElasticPool_basic_DTU(rInt int, location string) string
 	return testAccAzureRMMsSqlElasticPool_DTU_Template(rInt, location, "BasicPool", "Basic", 50, 4.8828125, 0, 5)
 }
 
-// func testAccAzureRMMsSqlElasticPool_basic_DTU_AutoFill(rInt int, location string) string {
-// 	return testAccAzureRMMsSqlElasticPool_DTU_AutoFill_Template(rInt, location, "BasicPool", 50, 4.8828125, 0, 5)
-// }
-
 func testAccAzureRMMsSqlElasticPool_requiresImport(rInt int, location string) string {
 	template := testAccAzureRMMsSqlElasticPool_DTU_Template(rInt, location, "BasicPool", "Basic", 50, 5242880000, 0, 5)
 	return fmt.Sprintf(`
@@ -403,10 +337,6 @@ func testAccAzureRMMsSqlElasticPool_basic_vCore(rInt int, location string) strin
 	return testAccAzureRMMsSqlElasticPool_vCore_Template(rInt, location, "GP_Gen5", "GeneralPurpose", 4, "Gen5", 0.25, 4)
 }
 
-// func testAccAzureRMMsSqlElasticPool_basic_vCore_AutoFill(rInt int, location string) string {
-// 	return testAccAzureRMMsSqlElasticPool_vCore_AutoFill_Template(rInt, location, "GP_Gen5", 4, 0.25, 4)
-// }
-
 func testAccAzureRMMsSqlElasticPool_resize_vCore(rInt int, location string) string {
 	return testAccAzureRMMsSqlElasticPool_vCore_Template(rInt, location, "GP_Gen5", "GeneralPurpose", 8, "Gen5", 0, 8)
 }
@@ -449,42 +379,6 @@ resource "azurerm_mssql_elasticpool" "test" {
 `, rInt, location, skuName, skuTier, skuCapacity, skuFamily, databaseSettingsMin, databaseSettingsMax)
 }
 
-// func testAccAzureRMMsSqlElasticPool_vCore_AutoFill_Template(rInt int, location string, skuName string, skuCapacity int, databaseSettingsMin float64, databaseSettingsMax float64) string {
-// 	return fmt.Sprintf(`
-// resource "azurerm_resource_group" "test" {
-//   name     = "acctestRG-%[1]d"
-//   location = "%s"
-// }
-
-// resource "azurerm_sql_server" "test" {
-//   name                         = "acctest%[1]d"
-//   resource_group_name          = "${azurerm_resource_group.test.name}"
-//   location                     = "${azurerm_resource_group.test.location}"
-//   version                      = "12.0"
-//   administrator_login          = "4dm1n157r470r"
-//   administrator_login_password = "4-v3ry-53cr37-p455w0rd"
-// }
-
-// resource "azurerm_mssql_elasticpool" "test" {
-//   name                = "acctest-pool-vcore-%[1]d"
-//   resource_group_name = "${azurerm_resource_group.test.name}"
-//   location            = "${azurerm_resource_group.test.location}"
-//   server_name         = "${azurerm_sql_server.test.name}"
-//   max_size_gb         = 5
-
-//   sku {
-//     name     = "%[3]s"
-//     capacity = %[4]d
-//   }
-
-//   per_database_settings {
-//     min_capacity = %.2[5]f
-//     max_capacity = %.2[6]f
-//   }
-// }
-// `, rInt, location, skuName, skuCapacity, databaseSettingsMin, databaseSettingsMax)
-// }
-
 func testAccAzureRMMsSqlElasticPool_DTU_Template(rInt int, location string, skuName string, skuTier string, skuCapacity int, maxSizeGB float64, databaseSettingsMin int, databaseSettingsMax int) string {
 	return fmt.Sprintf(`
 resource "azurerm_resource_group" "test" {
@@ -521,39 +415,3 @@ resource "azurerm_mssql_elasticpool" "test" {
 }
 `, rInt, location, skuName, skuTier, skuCapacity, maxSizeGB, databaseSettingsMin, databaseSettingsMax)
 }
-
-// func testAccAzureRMMsSqlElasticPool_DTU_AutoFill_Template(rInt int, location string, skuName string, skuCapacity int, maxSizeGB float64, databaseSettingsMin int, databaseSettingsMax int) string {
-// 	return fmt.Sprintf(`
-// resource "azurerm_resource_group" "test" {
-//   name     = "acctestRG-%[1]d"
-//   location = "%s"
-// }
-
-// resource "azurerm_sql_server" "test" {
-//   name                         = "acctest%[1]d"
-//   resource_group_name          = "${azurerm_resource_group.test.name}"
-//   location                     = "${azurerm_resource_group.test.location}"
-//   version                      = "12.0"
-//   administrator_login          = "4dm1n157r470r"
-//   administrator_login_password = "4-v3ry-53cr37-p455w0rd"
-// }
-
-// resource "azurerm_mssql_elasticpool" "test" {
-//   name                = "acctest-pool-dtu-%[1]d"
-//   resource_group_name = "${azurerm_resource_group.test.name}"
-//   location            = "${azurerm_resource_group.test.location}"
-//   server_name         = "${azurerm_sql_server.test.name}"
-//   max_size_gb         = %.7[5]f
-
-//   sku {
-//     name     = "%[3]s"
-//     capacity = %[4]d
-//   }
-
-//   per_database_settings {
-//     min_capacity = %[6]d
-//     max_capacity = %[7]d
-//   }
-// }
-// `, rInt, location, skuName, skuCapacity, maxSizeGB, databaseSettingsMin, databaseSettingsMax)
-// }

From 39f411331ba4fa2c79399163a174f6f31d1af64a Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Mon, 28 Jan 2019 18:35:12 -0800
Subject: [PATCH 27/45] Exposed max_size_bytes, updated documentation, and
 added test case

---
 azurerm/resource_arm_mssql_elasticpool.go     | 36 +++++++--
 .../resource_arm_mssql_elasticpool_test.go    | 74 +++++++++++++++++++
 .../docs/r/mssql_elasticpool.html.markdown    |  2 +
 3 files changed, 105 insertions(+), 7 deletions(-)

diff --git a/azurerm/resource_arm_mssql_elasticpool.go b/azurerm/resource_arm_mssql_elasticpool.go
index 4ca5fee72ec9..520ac5af371c 100644
--- a/azurerm/resource_arm_mssql_elasticpool.go
+++ b/azurerm/resource_arm_mssql_elasticpool.go
@@ -159,11 +159,20 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 				},
 			},
 
+			"max_size_bytes": {
+				Type:          schema.TypeInt,
+				Optional:      true,
+				Computed:      true,
+				ConflictsWith: []string{"max_size_gb"},
+				ValidateFunc:  validation.IntAtLeast(0),
+			},
+
 			"max_size_gb": {
-				Type:         schema.TypeFloat,
-				Optional:     true,
-				Computed:     true,
-				ValidateFunc: validate.FloatAtLeast(0),
+				Type:          schema.TypeFloat,
+				Optional:      true,
+				Computed:      true,
+				ConflictsWith: []string{"max_size_bytes"},
+				ValidateFunc:  validate.FloatAtLeast(0),
 			},
 
 			"zone_redundant": {
@@ -180,10 +189,16 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 			tier, _ := diff.GetOk("sku.0.tier")
 			capacity, _ := diff.GetOk("sku.0.capacity")
 			family, _ := diff.GetOk("sku.0.family")
+			maxSizeBytes, _ := diff.GetOk("max_size_bytes")
 			maxSizeGb, _ := diff.GetOk("max_size_gb")
 			minCapacity, _ := diff.GetOk("per_database_settings.0.min_capacity")
 			maxCapacity, _ := diff.GetOk("per_database_settings.0.max_capacity")
 
+			// Convert Bytes to Gigabytes
+			if maxSizeBytes != 0 {
+				maxSizeGb = float64(maxSizeBytes.(int) / 1073741824)
+			}
+
 			// Basic Checks
 			if strings.EqualFold(name.(string), "BasicPool") {
 				maxAllowedGB := azure.BasicGetMaxSizeGB(capacity.(int))
@@ -395,9 +410,15 @@ func resourceArmMsSqlElasticPoolCreateUpdate(d *schema.ResourceData, meta interf
 		},
 	}
 
-	if v, ok := d.GetOk("max_size_gb"); ok {
-		maxSizeBytes := v.(float64) * 1073741824
-		elasticPool.MaxSizeBytes = utils.Int64(int64(maxSizeBytes))
+	if d.HasChange("max_size_gb") {
+		if v, ok := d.GetOk("max_size_gb"); ok {
+			maxSizeBytes := v.(float64) * 1073741824
+			elasticPool.MaxSizeBytes = utils.Int64(int64(maxSizeBytes))
+		}
+	} else {
+		if v, ok := d.GetOk("max_size_bytes"); ok {
+			elasticPool.MaxSizeBytes = utils.Int64(int64(v.(int)))
+		}
 	}
 
 	future, err := client.CreateOrUpdate(ctx, resGroup, serverName, elasticPoolName, elasticPool)
@@ -459,6 +480,7 @@ func resourceArmMsSqlElasticPoolRead(d *schema.ResourceData, meta interface{}) e
 		if tier, ok := d.GetOk("sku.0.tier"); ok {
 			if !strings.EqualFold(tier.(string), "Basic") {
 				d.Set("max_size_gb", float64(*properties.MaxSizeBytes/int64(1073741824)))
+				d.Set("max_size_bytes", properties.MaxSizeBytes)
 			}
 		}
 		d.Set("zone_redundant", properties.ZoneRedundant)
diff --git a/azurerm/resource_arm_mssql_elasticpool_test.go b/azurerm/resource_arm_mssql_elasticpool_test.go
index a022c068056b..4bb9d015e265 100644
--- a/azurerm/resource_arm_mssql_elasticpool_test.go
+++ b/azurerm/resource_arm_mssql_elasticpool_test.go
@@ -130,6 +130,38 @@ func TestAccAzureRMMsSqlElasticPool_basic_vCore(t *testing.T) {
 	})
 }
 
+func TestAccAzureRMMsSqlElasticPool_basic_vCore_MaxSizeBytes(t *testing.T) {
+	resourceName := "azurerm_mssql_elasticpool.test"
+	ri := tf.AccRandTimeInt()
+	config := testAccAzureRMMsSqlElasticPool_basic_vCore_MaxSizeBytes(ri, testLocation())
+
+	resource.ParallelTest(t, resource.TestCase{
+		PreCheck:     func() { testAccPreCheck(t) },
+		Providers:    testAccProviders,
+		CheckDestroy: testCheckAzureRMMsSqlElasticPoolDestroy,
+		Steps: []resource.TestStep{
+			{
+				Config: config,
+				Check: resource.ComposeTestCheckFunc(
+					testCheckAzureRMMsSqlElasticPoolExists(resourceName),
+					resource.TestCheckResourceAttr(resourceName, "sku.0.name", "GP_Gen5"),
+					resource.TestCheckResourceAttr(resourceName, "sku.0.capacity", "4"),
+					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.min_capacity", "0.25"),
+					resource.TestCheckResourceAttr(resourceName, "per_database_settings.0.max_capacity", "4"),
+					resource.TestCheckResourceAttr(resourceName, "max_size_bytes", "214748364800"),
+					resource.TestCheckResourceAttrSet(resourceName, "max_size_gb"),
+					resource.TestCheckResourceAttrSet(resourceName, "zone_redundant"),
+				),
+			},
+			{
+				ResourceName:            resourceName,
+				ImportState:             true,
+				ImportStateVerify:       true,
+				ImportStateVerifyIgnore: []string{"max_size_gb"},
+			},
+		},
+	})
+}
 func TestAccAzureRMMsSqlElasticPool_disappears(t *testing.T) {
 	resourceName := "azurerm_mssql_elasticpool.test"
 	ri := tf.AccRandTimeInt()
@@ -337,6 +369,10 @@ func testAccAzureRMMsSqlElasticPool_basic_vCore(rInt int, location string) strin
 	return testAccAzureRMMsSqlElasticPool_vCore_Template(rInt, location, "GP_Gen5", "GeneralPurpose", 4, "Gen5", 0.25, 4)
 }
 
+func testAccAzureRMMsSqlElasticPool_basic_vCore_MaxSizeBytes(rInt int, location string) string {
+	return testAccAzureRMMsSqlElasticPool_vCore_MaxSizeBytes_Template(rInt, location, "GP_Gen5", "GeneralPurpose", 4, "Gen5", 0.25, 4)
+}
+
 func testAccAzureRMMsSqlElasticPool_resize_vCore(rInt int, location string) string {
 	return testAccAzureRMMsSqlElasticPool_vCore_Template(rInt, location, "GP_Gen5", "GeneralPurpose", 8, "Gen5", 0, 8)
 }
@@ -379,6 +415,44 @@ resource "azurerm_mssql_elasticpool" "test" {
 `, rInt, location, skuName, skuTier, skuCapacity, skuFamily, databaseSettingsMin, databaseSettingsMax)
 }
 
+func testAccAzureRMMsSqlElasticPool_vCore_MaxSizeBytes_Template(rInt int, location string, skuName string, skuTier string, skuCapacity int, skuFamily string, databaseSettingsMin float64, databaseSettingsMax float64) string {
+	return fmt.Sprintf(`
+resource "azurerm_resource_group" "test" {
+  name     = "acctestRG-%[1]d"
+  location = "%s"
+}
+
+resource "azurerm_sql_server" "test" {
+  name                         = "acctest%[1]d"
+  resource_group_name          = "${azurerm_resource_group.test.name}"
+  location                     = "${azurerm_resource_group.test.location}"
+  version                      = "12.0"
+  administrator_login          = "4dm1n157r470r"
+  administrator_login_password = "4-v3ry-53cr37-p455w0rd"
+}
+
+resource "azurerm_mssql_elasticpool" "test" {
+  name                = "acctest-pool-vcore-%[1]d"
+  resource_group_name = "${azurerm_resource_group.test.name}"
+  location            = "${azurerm_resource_group.test.location}"
+  server_name         = "${azurerm_sql_server.test.name}"
+  max_size_bytes      = 214748364800
+
+  sku {
+    name     = "%[3]s"
+    tier     = "%[4]s"
+    capacity = %[5]d
+    family   = "%[6]s"
+  }
+
+  per_database_settings {
+    min_capacity = %.2[7]f
+    max_capacity = %.2[8]f
+  }
+}
+`, rInt, location, skuName, skuTier, skuCapacity, skuFamily, databaseSettingsMin, databaseSettingsMax)
+}
+
 func testAccAzureRMMsSqlElasticPool_DTU_Template(rInt int, location string, skuName string, skuTier string, skuCapacity int, maxSizeGB float64, databaseSettingsMin int, databaseSettingsMax int) string {
 	return fmt.Sprintf(`
 resource "azurerm_resource_group" "test" {
diff --git a/website/docs/r/mssql_elasticpool.html.markdown b/website/docs/r/mssql_elasticpool.html.markdown
index 50210e302048..abf651a6c55a 100644
--- a/website/docs/r/mssql_elasticpool.html.markdown
+++ b/website/docs/r/mssql_elasticpool.html.markdown
@@ -66,6 +66,8 @@ The following arguments are supported:
 
 * `max_size_gb` - (Optional) The max data size of the elastic pool in gigabytes.
 
+* `max_size_bytes` - (Optional) The max data size of the elastic pool in bytes.
+
 * `tags` - (Optional) A mapping of tags to assign to the resource.
 
 ---

From 0ab8771aed690632bf23de697151d6839a2ac121 Mon Sep 17 00:00:00 2001
From: kt <kt@katbyte.me>
Date: Tue, 29 Jan 2019 17:17:29 -0800
Subject: [PATCH 28/45] Update azurerm/resource_arm_mssql_elasticpool.go

Co-Authored-By: jeffreyCline <jcline@microsoft.com>
---
 azurerm/resource_arm_mssql_elasticpool.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/azurerm/resource_arm_mssql_elasticpool.go b/azurerm/resource_arm_mssql_elasticpool.go
index 520ac5af371c..4491a8ee28fd 100644
--- a/azurerm/resource_arm_mssql_elasticpool.go
+++ b/azurerm/resource_arm_mssql_elasticpool.go
@@ -196,7 +196,7 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 
 			// Convert Bytes to Gigabytes
 			if maxSizeBytes != 0 {
-				maxSizeGb = float64(maxSizeBytes.(int) / 1073741824)
+				maxSizeGb = float64(maxSizeBytes.(int) / 1024 / 1024 / 1024)
 			}
 
 			// Basic Checks

From f4b805cc13019dc3080cd95eeb840a70e52212fc Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Wed, 30 Jan 2019 17:23:46 -0800
Subject: [PATCH 29/45] Fixes for PR comments

---
 azurerm/helpers/azure/elasticpool.go          | 277 +++++++++---------
 azurerm/helpers/suppress/string.go            |   8 -
 azurerm/resource_arm_mssql_elasticpool.go     | 178 +++--------
 .../docs/r/mssql_elasticpool.html.markdown    |   4 +-
 4 files changed, 190 insertions(+), 277 deletions(-)

diff --git a/azurerm/helpers/azure/elasticpool.go b/azurerm/helpers/azure/elasticpool.go
index eaef9351ab69..83bd7910918b 100644
--- a/azurerm/helpers/azure/elasticpool.go
+++ b/azurerm/helpers/azure/elasticpool.go
@@ -1,45 +1,63 @@
 package azure
 
 import (
+	"fmt"
 	"strings"
 )
 
-var basicDTUMaxGB = map[int]float64{
-	50:   4.8828125,
-	100:  9.765625,
-	200:  19.53125,
-	300:  29.296875,
-	400:  39.0625,
-	800:  78.125,
-	1200: 117.1875,
-	1600: 156.25,
-}
+type ErrorType int
 
-var standardDTUMaxGB = map[int]float64{
-	50:   500,
-	100:  750,
-	200:  1024,
-	300:  1280,
-	400:  1536,
-	800:  2048,
-	1200: 2560,
-	1600: 3072,
-	2000: 3584,
-	2500: 4096,
-	3000: 4096,
-}
+const (
+	Capacity  ErrorType = 0
+	MaxSizeGB ErrorType = 1
+)
 
-var premiumDTUMaxGB = map[int]float64{
-	125:  1024,
-	250:  1024,
-	500:  1024,
-	1000: 1024,
-	1500: 1536,
-	2000: 2048,
-	2500: 2560,
-	3000: 3072,
-	3500: 3584,
-	4000: 4096,
+var getDTUErrorMsg = map[string]string{
+	"basicpool_capacity":     "service tier 'Basic' must have a 'capacity'(%d) of 50, 100, 200, 300, 400, 800, 1200 or 1600 DTUs",
+	"basicpool_maxSizeGB":    "service tier 'Basic' with a 'capacity' of %d must have a 'max_size_gb' of %.7f GB, got %.7f GB",
+	"standardpool_capacity":  "service tier 'Standard' must have a 'capacity'(%d) of 50, 100, 200, 300, 400, 800, 1200, 1600, 2000, 2500 or 3000 DTUs",
+	"standardpool_maxSizeGB": "service tier 'Standard' with a 'capacity' of %d must have a 'max_size_gb' no greater than %d GB, got %d GB",
+	"premiumpool_capacity":   "service tier 'Premium' must have a 'capacity'(%d) of 125, 250, 500, 1000, 1500, 2000, 2500, 3000, 3500 or 4000 DTUs",
+	"premiumpool_maxSizeGB":  "service tier 'Premium' with a 'capacity' of %d must have a 'max_size_gb' no greater than %d GB, got %d GB",
+}
+
+var getvCoreErrorMsg = map[string]string{
+	"generalpurpose_gen4_capacity":   "service tier 'GeneralPurpose' Gen4 must have a 'capacity'(%d) of 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 16 or 24 vCores",
+	"generalpurpose_gen5_capacity":   "service tier 'GeneralPurpose' Gen5 must have a 'capacity'(%d) of 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 24, 32, 40 or 80 vCores",
+	"businesscritical_gen4_capacity": "service tier 'BusinessCritical' Gen4 must have a 'capacity'(%d) of 2, 3, 4, 5, 6, 7, 8, 9, 10, 16 or 24 vCores",
+	"businesscritical_gen5_capacity": "service tier 'BusinessCritical' Gen5 must have a 'capacity'(%d) of 4, 6, 8, 10, 12, 14, 16, 18, 20, 24, 32, 40 or 80 vCores",
+}
+
+var getDTUMaxGB = map[string]float64{
+	"basicpool_50":      4.8828125,
+	"basicpool_100":     9.765625,
+	"basicpool_200":     19.53125,
+	"basicpool_300":     29.296875,
+	"basicpool_400":     39.0625,
+	"basicpool_800":     78.125,
+	"basicpool_1200":    117.1875,
+	"basicpool_1600":    156.25,
+	"standardpool_50":   500,
+	"standardpool_100":  750,
+	"standardpool_200":  1024,
+	"standardpool_300":  1280,
+	"standardpool_400":  1536,
+	"standardpool_800":  2048,
+	"standardpool_1200": 2560,
+	"standardpool_1600": 3072,
+	"standardpool_2000": 3584,
+	"standardpool_2500": 4096,
+	"standardpool_3000": 4096,
+	"premiumpool_125":   1024,
+	"premiumpool_250":   1024,
+	"premiumpool_500":   1024,
+	"premiumpool_1000":  1024,
+	"premiumpool_1500":  1536,
+	"premiumpool_2000":  2048,
+	"premiumpool_2500":  2560,
+	"premiumpool_3000":  3072,
+	"premiumpool_3500":  3584,
+	"premiumpool_4000":  4096,
 }
 
 var supportedMaxGBValues = map[float64]bool{
@@ -73,149 +91,134 @@ var supportedMaxGBValues = map[float64]bool{
 	4096: true,
 }
 
-var generalPurposeGen4vCoreMaxGB = map[int]float64{
-	1:  512,
-	2:  756,
-	3:  1536,
-	4:  1536,
-	5:  1536,
-	6:  2048,
-	7:  2048,
-	8:  2048,
-	9:  2048,
-	10: 2048,
-	16: 3584,
-	24: 4096,
-}
-
-var generalPurposeGen5vCoreMaxGB = map[int]float64{
-	2:  512,
-	4:  756,
-	6:  1536,
-	8:  1536,
-	10: 1536,
-	12: 2048,
-	14: 2048,
-	16: 2048,
-	18: 3072,
-	20: 3072,
-	24: 3072,
-	32: 4096,
-	40: 4096,
-	80: 4096,
-}
-
-var businessCriticalGen4vCoreMaxGB = map[int]float64{
-	2:  1024,
-	3:  1024,
-	4:  1024,
-	5:  1024,
-	6:  1024,
-	7:  1024,
-	8:  1024,
-	9:  1024,
-	10: 1024,
-	16: 1024,
-	24: 1024,
-}
-
-var businessCriticalGen5vCoreMaxGB = map[int]float64{
-	4:  1024,
-	6:  1536,
-	8:  1536,
-	10: 1536,
-	12: 3072,
-	14: 3072,
-	16: 3072,
-	18: 3072,
-	20: 3072,
-	24: 4096,
-	32: 4096,
-	40: 4096,
-	80: 4096,
-}
+var getvCoreMaxGB = map[string]float64{
+	"generalpurpose_gen4_1":    512,
+	"generalpurpose_gen4_2":    756,
+	"generalpurpose_gen4_3":    1536,
+	"generalpurpose_gen4_4":    1536,
+	"generalpurpose_gen4_5":    1536,
+	"generalpurpose_gen4_6":    2048,
+	"generalpurpose_gen4_7":    2048,
+	"generalpurpose_gen4_8":    2048,
+	"generalpurpose_gen4_9":    2048,
+	"generalpurpose_gen4_10":   2048,
+	"generalpurpose_gen4_16":   3584,
+	"generalpurpose_gen4_24":   4096,
+	"generalpurpose_gen5_2":    512,
+	"generalpurpose_gen5_4":    756,
+	"generalpurpose_gen5_6":    1536,
+	"generalpurpose_gen5_8":    1536,
+	"generalpurpose_gen5_10":   1536,
+	"generalpurpose_gen5_12":   2048,
+	"generalpurpose_gen5_14":   2048,
+	"generalpurpose_gen5_16":   2048,
+	"generalpurpose_gen5_18":   3072,
+	"generalpurpose_gen5_20":   3072,
+	"generalpurpose_gen5_24":   3072,
+	"generalpurpose_gen5_32":   4096,
+	"generalpurpose_gen5_40":   4096,
+	"generalpurpose_gen5_80":   4096,
+	"businesscritical_gen4_2":  1024,
+	"businesscritical_gen4_3":  1024,
+	"businesscritical_gen4_4":  1024,
+	"businesscritical_gen4_5":  1024,
+	"businesscritical_gen4_6":  1024,
+	"businesscritical_gen4_7":  1024,
+	"businesscritical_gen4_8":  1024,
+	"businesscritical_gen4_9":  1024,
+	"businesscritical_gen4_10": 1024,
+	"businesscritical_gen4_16": 1024,
+	"businesscritical_gen4_24": 1024,
+	"businesscritical_gen5_4":  1024,
+	"businesscritical_gen5_6":  1536,
+	"businesscritical_gen5_8":  1536,
+	"businesscritical_gen5_10": 1536,
+	"businesscritical_gen5_12": 3072,
+	"businesscritical_gen5_14": 3072,
+	"businesscritical_gen5_16": 3072,
+	"businesscritical_gen5_18": 3072,
+	"businesscritical_gen5_20": 3072,
+	"businesscritical_gen5_24": 4096,
+	"businesscritical_gen5_32": 4096,
+	"businesscritical_gen5_40": 4096,
+	"businesscritical_gen5_80": 4096,
+}
+
+func MSSQLElasticPoolGetDTUBasedErrorMsg(name string, errorType ErrorType) string {
+	errType := "capacity"
+
+	if errorType == MaxSizeGB {
+		errType = "maxSizeGB"
+	}
 
-func BasicGetMaxSizeGB(DTUs int) float64 {
-	return basicDTUMaxGB[DTUs]
+	return getDTUErrorMsg[fmt.Sprintf("%s_%s", strings.ToLower(name), errType)]
 }
 
-func StandardGetMaxSizeGB(DTUs int) float64 {
-	return standardDTUMaxGB[DTUs]
+func MSSQLElasticPoolGetvCoreBasedErrorMsg(tier string, family string) string {
+	return getvCoreErrorMsg[fmt.Sprintf("%s_%s_capacity", strings.ToLower(tier), strings.ToLower(family))]
 }
 
-func PremiumGetMaxSizeGB(DTUs int) float64 {
-	return premiumDTUMaxGB[DTUs]
+func MSSQLElasticPoolGetDTUMaxSizeGB(name string, capacity int) float64 {
+	return getDTUMaxGB[fmt.Sprintf("%s_%d", strings.ToLower(name), capacity)]
 }
 
-func StandardPremiumMaxGBValid(gb float64) bool {
+func MSSQLElasticPoolIsValidMaxGBSizeForSKU(gb float64) bool {
 	return supportedMaxGBValues[gb]
 }
 
-func GeneralPurposeGetMaxSizeGB(vCores int, family string) float64 {
-	maxGB := 0.0
-
-	if strings.EqualFold(family, "Gen4") {
-		maxGB = generalPurposeGen4vCoreMaxGB[vCores]
-	}
-
-	if strings.EqualFold(family, "Gen5") {
-		maxGB = generalPurposeGen5vCoreMaxGB[vCores]
-	}
-
-	return maxGB
+func MSSQLElasticPoolGetvCoreMaxSizeGB(tier string, family string, vCores int) float64 {
+	return getvCoreMaxGB[fmt.Sprintf("%s_%s_%d", strings.ToLower(tier), strings.ToLower(family), vCores)]
 }
 
-func BusinessCriticalGetMaxSizeGB(vCores int, family string) float64 {
-	maxGB := 0.0
-
-	if strings.EqualFold(family, "Gen4") {
-		maxGB = businessCriticalGen4vCoreMaxGB[vCores]
-	}
+func MSSQLElasticPoolNameContainsFamily(name string, family string) bool {
+	return strings.Contains(strings.ToLower(name), strings.ToLower(family))
+}
 
-	if strings.EqualFold(family, "Gen5") {
-		maxGB = businessCriticalGen5vCoreMaxGB[vCores]
+func MSSQLElasticPoolNameTierIsValid(name string, tier string) bool {
+	if strings.EqualFold(name, "BasicPool") && !strings.EqualFold(tier, "Basic") ||
+		strings.EqualFold(name, "StandardPool") && !strings.EqualFold(tier, "Standard") ||
+		strings.EqualFold(name, "PremiumPool") && !strings.EqualFold(tier, "Premium") ||
+		strings.HasPrefix(strings.ToLower(name), "gp_") && !strings.EqualFold(tier, "GeneralPurpose") ||
+		strings.HasPrefix(strings.ToLower(name), "bc_") && !strings.EqualFold(tier, "BusinessCritical") {
+		return false
 	}
 
-	return maxGB
-}
-
-func NameFamilyValid(name string, family string) bool {
-	return strings.Contains(strings.ToLower(name), strings.ToLower(family))
+	return true
 }
 
-func GetTier(name string) string {
-	validTier := ""
+func MSSQLElasticPoolGetTierFromSKUName(name string) string {
+	tier := ""
 
 	if strings.EqualFold(name, "BasicPool") {
-		validTier = "Basic"
+		tier = "Basic"
 	}
 
 	if strings.EqualFold(name, "StandardPool") {
-		validTier = "Standard"
+		tier = "Standard"
 	}
 
 	if strings.EqualFold(name, "PremiumPool") {
-		validTier = "Premium"
+		tier = "Premium"
 	}
 
 	if strings.HasPrefix(strings.ToLower(name), "gp_") {
-		validTier = "GeneralPurpose"
+		tier = "GeneralPurpose"
 	}
 
 	if strings.HasPrefix(strings.ToLower(name), "bc_") {
-		validTier = "BusinessCritical"
+		tier = "BusinessCritical"
 	}
 
-	return validTier
+	return tier
 }
 
-func GetFamily(name string) string {
+func MSSQLElasticPoolGetFamilyFromSKUName(name string) string {
 	if !strings.HasPrefix(strings.ToLower(name), "gp_") && !strings.HasPrefix(strings.ToLower(name), "bc_") {
 		return ""
 	}
 
 	nameFamily := name[3:]
-	retFamily := "Gen4"
+	retFamily := "Gen4" // Default
 
 	if strings.EqualFold(nameFamily, "Gen5") {
 		retFamily = "Gen5"
diff --git a/azurerm/helpers/suppress/string.go b/azurerm/helpers/suppress/string.go
index 1f90ab561c07..2db9554de5ce 100644
--- a/azurerm/helpers/suppress/string.go
+++ b/azurerm/helpers/suppress/string.go
@@ -9,11 +9,3 @@ import (
 func CaseDifference(_, old, new string, _ *schema.ResourceData) bool {
 	return strings.EqualFold(old, new)
 }
-
-func IgnoreIfNotSet(_, old, new string, _ *schema.ResourceData) bool {
-	if new == "" {
-		return true
-	} else {
-		return strings.EqualFold(old, new)
-	}
-}
diff --git a/azurerm/resource_arm_mssql_elasticpool.go b/azurerm/resource_arm_mssql_elasticpool.go
index 4491a8ee28fd..598cacc09675 100644
--- a/azurerm/resource_arm_mssql_elasticpool.go
+++ b/azurerm/resource_arm_mssql_elasticpool.go
@@ -194,178 +194,96 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 			minCapacity, _ := diff.GetOk("per_database_settings.0.min_capacity")
 			maxCapacity, _ := diff.GetOk("per_database_settings.0.max_capacity")
 
-			// Convert Bytes to Gigabytes
-			if maxSizeBytes != 0 {
+			// Convert Bytes to Gigabytes only if max_size_gb
+			// has not changed else use max_size_gb
+			if maxSizeBytes != 0 && !diff.HasChange("max_size_gb") {
 				maxSizeGb = float64(maxSizeBytes.(int) / 1024 / 1024 / 1024)
 			}
 
-			// Basic Checks
-			if strings.EqualFold(name.(string), "BasicPool") {
-				maxAllowedGB := azure.BasicGetMaxSizeGB(capacity.(int))
+			if !strings.HasPrefix(strings.ToLower(name.(string)), "gp_") && !strings.HasPrefix(strings.ToLower(name.(string)), "bc_") {
+				// DTU Based Checks
 
-				if maxAllowedGB == 0 {
-					return fmt.Errorf("service tier 'Basic' must have a 'capacity'(%d) of 50, 100, 200, 300, 400, 800, 1200 or 1600 DTUs", capacity.(int))
-				}
-
-				// Basic SKU does not let you pick your max_size_GB they are fixed values
-				if maxSizeGb.(float64) != maxAllowedGB {
-					return fmt.Errorf("service tier 'Basic' with a 'capacity' of %d must have a 'max_size_gb' of %.7f GB, got %.7f GB", capacity.(int), maxAllowedGB, maxSizeGb.(float64))
-				}
-			}
-
-			// Standard Checks
-			if strings.EqualFold(name.(string), "StandardPool") {
-				maxAllowedGB := azure.StandardGetMaxSizeGB(capacity.(int))
+				maxAllowedGB := azure.MSSQLElasticPoolGetDTUMaxSizeGB(name.(string), capacity.(int))
 
 				if maxAllowedGB == 0 {
-					return fmt.Errorf("service tier 'Standard' must have a 'capacity'(%d) of 50, 100, 200, 300, 400, 800, 1200, 1600, 2000, 2500 or 3000 DTUs", capacity.(int))
+					return fmt.Errorf(azure.MSSQLElasticPoolGetDTUBasedErrorMsg(name.(string), azure.Capacity), capacity.(int))
 				}
 
-				if maxSizeGb.(float64) > maxAllowedGB {
-					return fmt.Errorf("service tier 'Standard' with a 'capacity' of %d must have a 'max_size_gb' no greater than %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
-				}
-			}
-
-			// Premium Checks
-			if strings.EqualFold(name.(string), "PremiumPool") {
-				maxAllowedGB := azure.PremiumGetMaxSizeGB(capacity.(int))
-
-				if maxAllowedGB == 0 {
-					return fmt.Errorf("service tier 'Premium' must have a 'capacity'(%d) of 125, 250, 500, 1000, 1500, 2000, 2500, 3000, 3500 or 4000 DTUs", capacity.(int))
-				}
-
-				if maxSizeGb.(float64) > maxAllowedGB {
-					return fmt.Errorf("service tier 'Premium' with a 'capacity' of %d must have a 'max_size_gb' no greater than %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
-				}
-			}
-
-			// GeneralPurpose Checks
-			if strings.HasPrefix(strings.ToLower(name.(string)), "gp_") {
-				// Gen4 Checks
-				if strings.EqualFold(family.(string), "Gen4") {
-					maxAllowedGB := azure.GeneralPurposeGetMaxSizeGB(capacity.(int), family.(string))
-
-					if maxAllowedGB == 0 {
-						return fmt.Errorf("service tier 'GeneralPurpose' Gen4 must have a 'capacity'(%d) of 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 16 or 24 vCores", capacity.(int))
+				if strings.EqualFold(name.(string), "BasicPool") {
+					// Basic SKU does not let you pick your max_size_GB they are fixed values
+					if maxSizeGb.(float64) != maxAllowedGB {
+						return fmt.Errorf(azure.MSSQLElasticPoolGetDTUBasedErrorMsg(name.(string), azure.MaxSizeGB), capacity.(int), maxAllowedGB, maxSizeGb.(float64))
 					}
-
+				} else {
+					// All other DTU based SKUs
 					if maxSizeGb.(float64) > maxAllowedGB {
-						return fmt.Errorf("service tier 'GeneralPurpose' Gen4 with a 'capacity' of %d vCores must have a 'max_size_gb' between 5 GB and %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
+						return fmt.Errorf(azure.MSSQLElasticPoolGetDTUBasedErrorMsg(name.(string), azure.MaxSizeGB), capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
 					}
 				}
 
-				// Gen5 Checks
-				if strings.EqualFold(family.(string), "Gen5") {
-					maxAllowedGB := azure.GeneralPurposeGetMaxSizeGB(capacity.(int), family.(string))
-
-					if maxAllowedGB == 0 {
-						return fmt.Errorf("service tier 'GeneralPurpose' Gen5 must have a 'capacity'(%d) of 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 24, 32, 40 or 80 vCores", capacity.(int))
+				if !strings.EqualFold(name.(string), "BasicPool") {
+					if int(maxSizeGb.(float64)) < 50 {
+						return fmt.Errorf("service tier '%s', must have a 'max_size_gb' value equal to or greater than 50 GB, got %d GB", azure.MSSQLElasticPoolGetTierFromSKUName(name.(string)), int(maxSizeGb.(float64)))
 					}
 
-					if maxSizeGb.(float64) > maxAllowedGB {
-						return fmt.Errorf("service tier 'GeneralPurpose' Gen5 with a 'capacity' of %d vCores must have a 'max_size_gb' between 5 GB and %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
+					if !azure.MSSQLElasticPoolIsValidMaxGBSizeForSKU(maxSizeGb.(float64)) {
+						return fmt.Errorf("'max_size_gb'(%d) is not a valid value, valid values are 50, 100, 150, 200, 250, 300, 400, 500, 750, 800, 1024, 1200, 1280, 1536, 1600, 1792, 2000, 2048, 2304, 2500, 2560, 2816, 3000, 3072, 3328, 3584, 3840 or 4096", int(maxSizeGb.(float64)))
 					}
 				}
-			}
 
-			// BusinessCritical Checks
-			if strings.HasPrefix(strings.ToLower(name.(string)), "bc_") {
-				// Gen4 Checks
-				if strings.EqualFold(family.(string), "Gen4") {
-					maxAllowedGB := azure.BusinessCriticalGetMaxSizeGB(capacity.(int), family.(string))
-
-					if maxAllowedGB == 0 {
-						return fmt.Errorf("service tier 'BusinessCritical' Gen4 must have a 'capacity'(%d) of 2, 3, 4, 5, 6, 7, 8, 9, 10, 16 or 24 vCores", capacity.(int))
-					}
-
-					if maxSizeGb.(float64) > maxAllowedGB {
-						return fmt.Errorf("service tier 'BusinessCritical' Gen4 with a 'capacity' of %d vCores must have a 'max_size_gb' between 5 GB and %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
-					}
+				if family.(string) != "" {
+					return fmt.Errorf("Invalid attribute 'family' (%s) for service tiers 'Basic', 'Standard', and 'Premium', remove the 'family' attribute from the configuration file", family.(string))
 				}
 
-				// Gen5 Checks
-				if strings.EqualFold(family.(string), "Gen5") {
-					maxAllowedGB := azure.BusinessCriticalGetMaxSizeGB(capacity.(int), family.(string))
-
-					if maxAllowedGB == 0 {
-						return fmt.Errorf("service tier 'BusinessCritical' Gen5 must have a 'capacity'(%d) of 4, 6, 8, 10, 12, 14, 16, 18, 20, 24, 32, 40 or 80 vCores", capacity.(int))
-					}
-
-					if maxSizeGb.(float64) > maxAllowedGB {
-						return fmt.Errorf("service tier 'BusinessCritical' Gen5 with a 'capacity' of %d vCores must have a 'max_size_gb' between 5 GB and %d GB, got %d GB", capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
-					}
+				if minCapacity.(float64) != math.Trunc(minCapacity.(float64)) {
+					return fmt.Errorf("service tiers 'Basic', 'Standard', and 'Premium' must have whole numbers as their 'minCapacity'")
 				}
-			}
 
-			// General Checks based off SKU type...
-			if strings.HasPrefix(strings.ToLower(name.(string)), "gp_") || strings.HasPrefix(strings.ToLower(name.(string)), "bc_") {
-				// vCore Based
-				if int(maxSizeGb.(float64)) < 5 {
-					return fmt.Errorf("service tier 'GeneralPurpose' and 'BusinessCritical' must have a 'max_size_gb' value equal to or greater than 5 GB, got %d GB", int(maxSizeGb.(float64)))
+				if maxCapacity.(float64) != math.Trunc(maxCapacity.(float64)) {
+					return fmt.Errorf("service tiers 'Basic', 'Standard', and 'Premium' must have whole numbers as their 'maxCapacity'")
 				}
 
-				if maxSizeGb.(float64) != math.Trunc(maxSizeGb.(float64)) {
-					return fmt.Errorf("'max_size_gb' must be a whole number, got %f GB", maxSizeGb.(float64))
+				if minCapacity.(float64) < 0.0 {
+					return fmt.Errorf("service tiers 'Basic', 'Standard', and 'Premium' per_database_settings 'min_capacity' must be equal to or greater than zero")
 				}
 
-				if !azure.NameFamilyValid(name.(string), family.(string)) {
-					return fmt.Errorf("Mismatch between SKU name '%s' and family '%s', expected '%s'", name.(string), family.(string), azure.GetFamily(name.(string)))
-				}
+			} else {
+				// vCore Based Checks
 
-				if maxCapacity.(float64) > float64(capacity.(int)) {
-					return fmt.Errorf("service tiers 'GeneralPurpose' and 'BusinessCritical' perDatabaseSettings maxCapacity must not be higher than the SKUs 'capacity'(%d) value", capacity.(int))
-				}
+				maxAllowedGB := azure.MSSQLElasticPoolGetvCoreMaxSizeGB(azure.MSSQLElasticPoolGetTierFromSKUName(name.(string)), family.(string), capacity.(int))
 
-				if minCapacity.(float64) > maxCapacity.(float64) {
-					return fmt.Errorf("perDatabaseSettings maxCapacity must be greater than or equal to the perDatabaseSettings 'minCapacity' value")
+				if maxAllowedGB == 0 {
+					return fmt.Errorf(azure.MSSQLElasticPoolGetvCoreBasedErrorMsg(azure.MSSQLElasticPoolGetTierFromSKUName(name.(string)), family.(string)), capacity.(int))
 				}
-			} else {
-				// DTU Based
-				if !strings.EqualFold(name.(string), "BasicPool") {
-					if int(maxSizeGb.(float64)) < 50 {
-						return fmt.Errorf("service tiers 'Standard', and 'Premium' must have a 'max_size_gb' value equal to or greater than 50 GB, got %d GB", int(maxSizeGb.(float64)))
-					}
 
-					if !azure.StandardPremiumMaxGBValid(maxSizeGb.(float64)) {
-						return fmt.Errorf("'max_size_gb'(%d) is not a valid value, valid values are 50, 100, 150, 200, 250, 300, 400, 500, 750, 800, 1024, 1200, 1280, 1536, 1600, 1792, 2000, 2048, 2304, 2500, 2560, 2816, 3000, 3072, 3328, 3584, 3840 or 4096", int(maxSizeGb.(float64)))
-					}
+				if maxSizeGb.(float64) > maxAllowedGB {
+					return fmt.Errorf("service tier '%s' %s with a 'capacity' of %d vCores must have a 'max_size_gb' between 5 GB and %d GB, got %d GB", azure.MSSQLElasticPoolGetTierFromSKUName(name.(string)), family.(string), capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
 				}
 
-				if family.(string) != "" {
-					return fmt.Errorf("Invalid attribute 'family' (%s) for service tiers 'Basic', 'Standard', and 'Premium', remove the 'family' attribute from the configuration file", family.(string))
+				if int(maxSizeGb.(float64)) < 5 {
+					return fmt.Errorf("service tier '%s' must have a 'max_size_gb' value equal to or greater than 5 GB, got %d GB", azure.MSSQLElasticPoolGetTierFromSKUName(name.(string)), int(maxSizeGb.(float64)))
 				}
 
-				if maxCapacity.(float64) != math.Trunc(maxCapacity.(float64)) {
-					return fmt.Errorf("service tiers 'Basic', 'Standard', and 'Premium' must have whole numbers as their 'maxCapacity'")
+				if maxSizeGb.(float64) != math.Trunc(maxSizeGb.(float64)) {
+					return fmt.Errorf("'max_size_gb' must be a whole number, got %f GB", maxSizeGb.(float64))
 				}
 
-				if minCapacity.(float64) != math.Trunc(minCapacity.(float64)) {
-					return fmt.Errorf("service tiers 'Basic', 'Standard', and 'Premium' must have whole numbers as their 'minCapacity'")
+				if !azure.MSSQLElasticPoolNameContainsFamily(name.(string), family.(string)) {
+					return fmt.Errorf("Mismatch between SKU name '%s' and family '%s', expected '%s'", name.(string), family.(string), azure.MSSQLElasticPoolGetFamilyFromSKUName(name.(string)))
 				}
 
-				if minCapacity.(float64) < 0.0 {
-					return fmt.Errorf("service tiers 'Basic', 'Standard', and 'Premium' per_database_settings 'min_capacity' must be equal to or greater than zero")
+				if maxCapacity.(float64) > float64(capacity.(int)) {
+					return fmt.Errorf("service tier '%s' perDatabaseSettings 'maxCapacity' must not be higher than the SKUs 'capacity'(%d) value", azure.MSSQLElasticPoolGetTierFromSKUName(name.(string)), capacity.(int))
 				}
-			}
-
-			if strings.EqualFold(name.(string), "BasicPool") && !strings.EqualFold(tier.(string), "Basic") {
-				return fmt.Errorf("Mismatch between SKU name '%s' and tier '%s', expected 'tier' to be 'Basic'", name.(string), tier.(string))
-			}
-
-			if strings.EqualFold(name.(string), "StandardPool") && !strings.EqualFold(tier.(string), "Standard") {
-				return fmt.Errorf("Mismatch between SKU name '%s' and tier '%s', expected 'tier' to be 'Standard'", name.(string), tier.(string))
-			}
-
-			if strings.EqualFold(name.(string), "PremiumPool") && !strings.EqualFold(tier.(string), "Premium") {
-				return fmt.Errorf("Mismatch between SKU name '%s' and tier '%s', expected 'tier' to be 'Premium'", name.(string), tier.(string))
-			}
 
-			if strings.HasPrefix(strings.ToLower(name.(string)), "gp_") && !strings.EqualFold(tier.(string), "GeneralPurpose") {
-				return fmt.Errorf("Mismatch between SKU name '%s' and tier '%s', expected 'tier' to be 'GeneralPurpose'", name.(string), tier.(string))
+				if minCapacity.(float64) > maxCapacity.(float64) {
+					return fmt.Errorf("perDatabaseSettings 'maxCapacity' must be greater than or equal to the perDatabaseSettings 'minCapacity' value")
+				}
 			}
 
-			if strings.HasPrefix(strings.ToLower(name.(string)), "bc_") && !strings.EqualFold(tier.(string), "BusinessCritical") {
-				return fmt.Errorf("Mismatch between SKU name '%s' tier '%s', expected 'tier' to be 'BusinessCritical'", name.(string), tier.(string))
+			// Universal check for all SKUs
+			if !azure.MSSQLElasticPoolNameTierIsValid(name.(string), tier.(string)) {
+				return fmt.Errorf("Mismatch between SKU name '%s' and tier '%s', expected 'tier' to be '%s'", name.(string), tier.(string), azure.MSSQLElasticPoolGetTierFromSKUName(name.(string)))
 			}
 
 			return nil
diff --git a/website/docs/r/mssql_elasticpool.html.markdown b/website/docs/r/mssql_elasticpool.html.markdown
index abf651a6c55a..6c5ab9d20aaf 100644
--- a/website/docs/r/mssql_elasticpool.html.markdown
+++ b/website/docs/r/mssql_elasticpool.html.markdown
@@ -64,9 +64,9 @@ The following arguments are supported:
 
 * `per_database_settings` - (Required) A `per_database_settings` block as defined below.
 
-* `max_size_gb` - (Optional) The max data size of the elastic pool in gigabytes.
+* `max_size_gb` - (Optional) The max data size of the elastic pool in gigabytes. Conflicts with `max_size_bytes`. 
 
-* `max_size_bytes` - (Optional) The max data size of the elastic pool in bytes.
+* `max_size_bytes` - (Optional) The max data size of the elastic pool in bytes. Conflicts with `max_size_gb`.
 
 * `tags` - (Optional) A mapping of tags to assign to the resource.
 

From 544b19a58bceef0bc4a8bd9c8f011e50d7b8aa44 Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Wed, 30 Jan 2019 17:59:07 -0800
Subject: [PATCH 30/45] Updated GetTierFromSKUName to use map

---
 azurerm/helpers/azure/elasticpool.go | 34 +++++++++-------------------
 1 file changed, 11 insertions(+), 23 deletions(-)

diff --git a/azurerm/helpers/azure/elasticpool.go b/azurerm/helpers/azure/elasticpool.go
index 83bd7910918b..93ff912a2a01 100644
--- a/azurerm/helpers/azure/elasticpool.go
+++ b/azurerm/helpers/azure/elasticpool.go
@@ -144,6 +144,16 @@ var getvCoreMaxGB = map[string]float64{
 	"businesscritical_gen5_80": 4096,
 }
 
+var getTierFromName = map[string]string{
+	"basicpool":    "Basic",
+	"standardpool": "Standard",
+	"premiumpool":  "Premium",
+	"gp_gen4":      "GeneralPurpose",
+	"gp_gen5":      "GeneralPurpose",
+	"bc_gen4":      "BusinessCritical",
+	"bc_gen5":      "BusinessCritical",
+}
+
 func MSSQLElasticPoolGetDTUBasedErrorMsg(name string, errorType ErrorType) string {
 	errType := "capacity"
 
@@ -187,29 +197,7 @@ func MSSQLElasticPoolNameTierIsValid(name string, tier string) bool {
 }
 
 func MSSQLElasticPoolGetTierFromSKUName(name string) string {
-	tier := ""
-
-	if strings.EqualFold(name, "BasicPool") {
-		tier = "Basic"
-	}
-
-	if strings.EqualFold(name, "StandardPool") {
-		tier = "Standard"
-	}
-
-	if strings.EqualFold(name, "PremiumPool") {
-		tier = "Premium"
-	}
-
-	if strings.HasPrefix(strings.ToLower(name), "gp_") {
-		tier = "GeneralPurpose"
-	}
-
-	if strings.HasPrefix(strings.ToLower(name), "bc_") {
-		tier = "BusinessCritical"
-	}
-
-	return tier
+	return getTierFromName[strings.ToLower(name)]
 }
 
 func MSSQLElasticPoolGetFamilyFromSKUName(name string) string {

From 347f83d20bc93b17796c4315d29b2a1de34aa122 Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Wed, 30 Jan 2019 18:15:37 -0800
Subject: [PATCH 31/45] Updated error msg for clarity

---
 azurerm/resource_arm_mssql_elasticpool.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/azurerm/resource_arm_mssql_elasticpool.go b/azurerm/resource_arm_mssql_elasticpool.go
index 598cacc09675..a846b651fa65 100644
--- a/azurerm/resource_arm_mssql_elasticpool.go
+++ b/azurerm/resource_arm_mssql_elasticpool.go
@@ -227,7 +227,7 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 					}
 
 					if !azure.MSSQLElasticPoolIsValidMaxGBSizeForSKU(maxSizeGb.(float64)) {
-						return fmt.Errorf("'max_size_gb'(%d) is not a valid value, valid values are 50, 100, 150, 200, 250, 300, 400, 500, 750, 800, 1024, 1200, 1280, 1536, 1600, 1792, 2000, 2048, 2304, 2500, 2560, 2816, 3000, 3072, 3328, 3584, 3840 or 4096", int(maxSizeGb.(float64)))
+						return fmt.Errorf("'max_size_gb'(%d) is not a valid value for service tier '%s', 'max_size_gb' must have a value of 50, 100, 150, 200, 250, 300, 400, 500, 750, 800, 1024, 1200, 1280, 1536, 1600, 1792, 2000, 2048, 2304, 2500, 2560, 2816, 3000, 3072, 3328, 3584, 3840 or 4096", int(maxSizeGb.(float64)), azure.MSSQLElasticPoolGetTierFromSKUName(name.(string)))
 					}
 				}
 

From 3421bff8c64daa9f063fbd57d7e7179c5ca28e03 Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Wed, 30 Jan 2019 19:47:34 -0800
Subject: [PATCH 32/45] Switch to using nested maps

---
 azurerm/helpers/azure/elasticpool.go      | 235 ++++++++++++----------
 azurerm/resource_arm_mssql_elasticpool.go |   4 +-
 2 files changed, 130 insertions(+), 109 deletions(-)

diff --git a/azurerm/helpers/azure/elasticpool.go b/azurerm/helpers/azure/elasticpool.go
index 93ff912a2a01..296dfdcc79b1 100644
--- a/azurerm/helpers/azure/elasticpool.go
+++ b/azurerm/helpers/azure/elasticpool.go
@@ -1,7 +1,6 @@
 package azure
 
 import (
-	"fmt"
 	"strings"
 )
 
@@ -12,55 +11,71 @@ const (
 	MaxSizeGB ErrorType = 1
 )
 
-var getDTUErrorMsg = map[string]string{
-	"basicpool_capacity":     "service tier 'Basic' must have a 'capacity'(%d) of 50, 100, 200, 300, 400, 800, 1200 or 1600 DTUs",
-	"basicpool_maxSizeGB":    "service tier 'Basic' with a 'capacity' of %d must have a 'max_size_gb' of %.7f GB, got %.7f GB",
-	"standardpool_capacity":  "service tier 'Standard' must have a 'capacity'(%d) of 50, 100, 200, 300, 400, 800, 1200, 1600, 2000, 2500 or 3000 DTUs",
-	"standardpool_maxSizeGB": "service tier 'Standard' with a 'capacity' of %d must have a 'max_size_gb' no greater than %d GB, got %d GB",
-	"premiumpool_capacity":   "service tier 'Premium' must have a 'capacity'(%d) of 125, 250, 500, 1000, 1500, 2000, 2500, 3000, 3500 or 4000 DTUs",
-	"premiumpool_maxSizeGB":  "service tier 'Premium' with a 'capacity' of %d must have a 'max_size_gb' no greater than %d GB, got %d GB",
+var getDTUErrorMsg = map[string]map[ErrorType]string{
+	"basicpool": {
+		Capacity:  "service tier 'Basic' must have a 'capacity'(%d) of 50, 100, 200, 300, 400, 800, 1200 or 1600 DTUs",
+		MaxSizeGB: "service tier 'Basic' with a 'capacity' of %d must have a 'max_size_gb' of %.7f GB, got %.7f GB",
+	},
+	"standardpool": {
+		Capacity:  "service tier 'Standard' must have a 'capacity'(%d) of 50, 100, 200, 300, 400, 800, 1200, 1600, 2000, 2500 or 3000 DTUs",
+		MaxSizeGB: "service tier 'Standard' with a 'capacity' of %d must have a 'max_size_gb' no greater than %d GB, got %d GB",
+	},
+	"premiumpool": {
+		Capacity:  "service tier 'Premium' must have a 'capacity'(%d) of 125, 250, 500, 1000, 1500, 2000, 2500, 3000, 3500 or 4000 DTUs",
+		MaxSizeGB: "service tier 'Premium' with a 'capacity' of %d must have a 'max_size_gb' no greater than %d GB, got %d GB",
+	},
 }
 
-var getvCoreErrorMsg = map[string]string{
-	"generalpurpose_gen4_capacity":   "service tier 'GeneralPurpose' Gen4 must have a 'capacity'(%d) of 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 16 or 24 vCores",
-	"generalpurpose_gen5_capacity":   "service tier 'GeneralPurpose' Gen5 must have a 'capacity'(%d) of 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 24, 32, 40 or 80 vCores",
-	"businesscritical_gen4_capacity": "service tier 'BusinessCritical' Gen4 must have a 'capacity'(%d) of 2, 3, 4, 5, 6, 7, 8, 9, 10, 16 or 24 vCores",
-	"businesscritical_gen5_capacity": "service tier 'BusinessCritical' Gen5 must have a 'capacity'(%d) of 4, 6, 8, 10, 12, 14, 16, 18, 20, 24, 32, 40 or 80 vCores",
+var getvCoreErrorMsg = map[string]map[string]string{
+	"generalpurpose": {
+		"gen4": "service tier 'GeneralPurpose' Gen4 must have a 'capacity'(%d) of 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 16 or 24 vCores",
+		"gen5": "service tier 'GeneralPurpose' Gen5 must have a 'capacity'(%d) of 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 24, 32, 40 or 80 vCores",
+	},
+	"businesscritical": {
+		"gen4": "service tier 'BusinessCritical' Gen4 must have a 'capacity'(%d) of 2, 3, 4, 5, 6, 7, 8, 9, 10, 16 or 24 vCores",
+		"gen5": "service tier 'BusinessCritical' Gen5 must have a 'capacity'(%d) of 4, 6, 8, 10, 12, 14, 16, 18, 20, 24, 32, 40 or 80 vCores",
+	},
 }
 
-var getDTUMaxGB = map[string]float64{
-	"basicpool_50":      4.8828125,
-	"basicpool_100":     9.765625,
-	"basicpool_200":     19.53125,
-	"basicpool_300":     29.296875,
-	"basicpool_400":     39.0625,
-	"basicpool_800":     78.125,
-	"basicpool_1200":    117.1875,
-	"basicpool_1600":    156.25,
-	"standardpool_50":   500,
-	"standardpool_100":  750,
-	"standardpool_200":  1024,
-	"standardpool_300":  1280,
-	"standardpool_400":  1536,
-	"standardpool_800":  2048,
-	"standardpool_1200": 2560,
-	"standardpool_1600": 3072,
-	"standardpool_2000": 3584,
-	"standardpool_2500": 4096,
-	"standardpool_3000": 4096,
-	"premiumpool_125":   1024,
-	"premiumpool_250":   1024,
-	"premiumpool_500":   1024,
-	"premiumpool_1000":  1024,
-	"premiumpool_1500":  1536,
-	"premiumpool_2000":  2048,
-	"premiumpool_2500":  2560,
-	"premiumpool_3000":  3072,
-	"premiumpool_3500":  3584,
-	"premiumpool_4000":  4096,
+var getDTUMaxGB = map[string]map[int]float64{
+	"basicpool": {
+		50:   4.8828125,
+		100:  9.765625,
+		200:  19.53125,
+		300:  29.296875,
+		400:  39.0625,
+		800:  78.125,
+		1200: 117.1875,
+		1600: 156.25,
+	},
+	"standardpool": {
+		50:   500,
+		100:  750,
+		200:  1024,
+		300:  1280,
+		400:  1536,
+		800:  2048,
+		1200: 2560,
+		1600: 3072,
+		2000: 3584,
+		2500: 4096,
+		3000: 4096,
+	},
+	"premiumpool": {
+		125:  1024,
+		250:  1024,
+		500:  1024,
+		1000: 1024,
+		1500: 1536,
+		2000: 2048,
+		2500: 2560,
+		3000: 3072,
+		3500: 3584,
+		4000: 4096,
+	},
 }
 
-var supportedMaxGBValues = map[float64]bool{
+var supportedDTUMaxGBValues = map[float64]bool{
 	50:   true,
 	100:  true,
 	150:  true,
@@ -91,57 +106,69 @@ var supportedMaxGBValues = map[float64]bool{
 	4096: true,
 }
 
-var getvCoreMaxGB = map[string]float64{
-	"generalpurpose_gen4_1":    512,
-	"generalpurpose_gen4_2":    756,
-	"generalpurpose_gen4_3":    1536,
-	"generalpurpose_gen4_4":    1536,
-	"generalpurpose_gen4_5":    1536,
-	"generalpurpose_gen4_6":    2048,
-	"generalpurpose_gen4_7":    2048,
-	"generalpurpose_gen4_8":    2048,
-	"generalpurpose_gen4_9":    2048,
-	"generalpurpose_gen4_10":   2048,
-	"generalpurpose_gen4_16":   3584,
-	"generalpurpose_gen4_24":   4096,
-	"generalpurpose_gen5_2":    512,
-	"generalpurpose_gen5_4":    756,
-	"generalpurpose_gen5_6":    1536,
-	"generalpurpose_gen5_8":    1536,
-	"generalpurpose_gen5_10":   1536,
-	"generalpurpose_gen5_12":   2048,
-	"generalpurpose_gen5_14":   2048,
-	"generalpurpose_gen5_16":   2048,
-	"generalpurpose_gen5_18":   3072,
-	"generalpurpose_gen5_20":   3072,
-	"generalpurpose_gen5_24":   3072,
-	"generalpurpose_gen5_32":   4096,
-	"generalpurpose_gen5_40":   4096,
-	"generalpurpose_gen5_80":   4096,
-	"businesscritical_gen4_2":  1024,
-	"businesscritical_gen4_3":  1024,
-	"businesscritical_gen4_4":  1024,
-	"businesscritical_gen4_5":  1024,
-	"businesscritical_gen4_6":  1024,
-	"businesscritical_gen4_7":  1024,
-	"businesscritical_gen4_8":  1024,
-	"businesscritical_gen4_9":  1024,
-	"businesscritical_gen4_10": 1024,
-	"businesscritical_gen4_16": 1024,
-	"businesscritical_gen4_24": 1024,
-	"businesscritical_gen5_4":  1024,
-	"businesscritical_gen5_6":  1536,
-	"businesscritical_gen5_8":  1536,
-	"businesscritical_gen5_10": 1536,
-	"businesscritical_gen5_12": 3072,
-	"businesscritical_gen5_14": 3072,
-	"businesscritical_gen5_16": 3072,
-	"businesscritical_gen5_18": 3072,
-	"businesscritical_gen5_20": 3072,
-	"businesscritical_gen5_24": 4096,
-	"businesscritical_gen5_32": 4096,
-	"businesscritical_gen5_40": 4096,
-	"businesscritical_gen5_80": 4096,
+var getvCoreMaxGB = map[string]map[string]map[int]float64{
+	"generalpurpose": {
+		"gen4": {
+			1:  512,
+			2:  756,
+			3:  1536,
+			4:  1536,
+			5:  1536,
+			6:  2048,
+			7:  2048,
+			8:  2048,
+			9:  2048,
+			10: 2048,
+			16: 3584,
+			24: 4096,
+		},
+		"gen5": {
+			2:  512,
+			4:  756,
+			6:  1536,
+			8:  1536,
+			10: 1536,
+			12: 2048,
+			14: 2048,
+			16: 2048,
+			18: 3072,
+			20: 3072,
+			24: 3072,
+			32: 4096,
+			40: 4096,
+			80: 4096,
+		},
+	},
+	"businesscritical": {
+		"gen4": {
+			2:  1024,
+			3:  1024,
+			4:  1024,
+			5:  1024,
+			6:  1024,
+			7:  1024,
+			8:  1024,
+			9:  1024,
+			10: 1024,
+			16: 1024,
+			24: 1024,
+		},
+		"gen5": {
+			4:  1024,
+			6:  1536,
+			8:  1536,
+			10: 1536,
+			12: 3072,
+			14: 3072,
+			16: 3072,
+			18: 3072,
+			20: 3072,
+			24: 4096,
+			32: 4096,
+			40: 4096,
+			80: 4096,
+		},
+	},
 }
 
 var getTierFromName = map[string]string{
@@ -155,29 +182,23 @@ var getTierFromName = map[string]string{
 }
 
 func MSSQLElasticPoolGetDTUBasedErrorMsg(name string, errorType ErrorType) string {
-	errType := "capacity"
-
-	if errorType == MaxSizeGB {
-		errType = "maxSizeGB"
-	}
-
-	return getDTUErrorMsg[fmt.Sprintf("%s_%s", strings.ToLower(name), errType)]
+	return getDTUErrorMsg[strings.ToLower(name)][errorType]
 }
 
 func MSSQLElasticPoolGetvCoreBasedErrorMsg(tier string, family string) string {
-	return getvCoreErrorMsg[fmt.Sprintf("%s_%s_capacity", strings.ToLower(tier), strings.ToLower(family))]
+	return getvCoreErrorMsg[strings.ToLower(tier)][strings.ToLower(family)]
 }
 
 func MSSQLElasticPoolGetDTUMaxSizeGB(name string, capacity int) float64 {
-	return getDTUMaxGB[fmt.Sprintf("%s_%d", strings.ToLower(name), capacity)]
+	return getDTUMaxGB[strings.ToLower(name)][capacity]
 }
 
-func MSSQLElasticPoolIsValidMaxGBSizeForSKU(gb float64) bool {
-	return supportedMaxGBValues[gb]
+func MSSQLElasticPoolIsValidDTUMaxGBSize(gigabytes float64) bool {
+	return supportedDTUMaxGBValues[gigabytes]
 }
 
 func MSSQLElasticPoolGetvCoreMaxSizeGB(tier string, family string, vCores int) float64 {
-	return getvCoreMaxGB[fmt.Sprintf("%s_%s_%d", strings.ToLower(tier), strings.ToLower(family), vCores)]
+	return getvCoreMaxGB[strings.ToLower(tier)][strings.ToLower(family)][vCores]
 }
 
 func MSSQLElasticPoolNameContainsFamily(name string, family string) bool {
diff --git a/azurerm/resource_arm_mssql_elasticpool.go b/azurerm/resource_arm_mssql_elasticpool.go
index a846b651fa65..0454bcb467e5 100644
--- a/azurerm/resource_arm_mssql_elasticpool.go
+++ b/azurerm/resource_arm_mssql_elasticpool.go
@@ -226,7 +226,7 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 						return fmt.Errorf("service tier '%s', must have a 'max_size_gb' value equal to or greater than 50 GB, got %d GB", azure.MSSQLElasticPoolGetTierFromSKUName(name.(string)), int(maxSizeGb.(float64)))
 					}
 
-					if !azure.MSSQLElasticPoolIsValidMaxGBSizeForSKU(maxSizeGb.(float64)) {
+					if !azure.MSSQLElasticPoolIsValidDTUMaxGBSize(maxSizeGb.(float64)) {
 						return fmt.Errorf("'max_size_gb'(%d) is not a valid value for service tier '%s', 'max_size_gb' must have a value of 50, 100, 150, 200, 250, 300, 400, 500, 750, 800, 1024, 1200, 1280, 1536, 1600, 1792, 2000, 2048, 2304, 2500, 2560, 2816, 3000, 3072, 3328, 3584, 3840 or 4096", int(maxSizeGb.(float64)), azure.MSSQLElasticPoolGetTierFromSKUName(name.(string)))
 					}
 				}
@@ -253,7 +253,7 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 				maxAllowedGB := azure.MSSQLElasticPoolGetvCoreMaxSizeGB(azure.MSSQLElasticPoolGetTierFromSKUName(name.(string)), family.(string), capacity.(int))
 
 				if maxAllowedGB == 0 {
-					return fmt.Errorf(azure.MSSQLElasticPoolGetvCoreBasedErrorMsg(azure.MSSQLElasticPoolGetTierFromSKUName(name.(string)), family.(string)), capacity.(int))
+					return fmt.Errorf(azure.MSSQLElasticPoolGetvCoreBasedErrorMsg(azure.MSSQLElasticPoolGetTierFromSKUName(name.(string)), azure.MSSQLElasticPoolGetFamilyFromSKUName(name.(string))), capacity.(int))
 				}
 
 				if maxSizeGb.(float64) > maxAllowedGB {

From ab9c67aa01eb9d19eb4d0abb5dbfe90e5626b196 Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Thu, 31 Jan 2019 19:52:58 -0800
Subject: [PATCH 33/45] Updated errors to be dynamically generated

---
 azurerm/helpers/azure/elasticpool.go      | 291 ++++++++++++++++++----
 azurerm/resource_arm_mssql_elasticpool.go | 102 +-------
 2 files changed, 242 insertions(+), 151 deletions(-)

diff --git a/azurerm/helpers/azure/elasticpool.go b/azurerm/helpers/azure/elasticpool.go
index 296dfdcc79b1..0b9d6ac30081 100644
--- a/azurerm/helpers/azure/elasticpool.go
+++ b/azurerm/helpers/azure/elasticpool.go
@@ -1,44 +1,29 @@
 package azure
 
 import (
+	"fmt"
+	"math"
+	"sort"
 	"strings"
+
+	"github.com/hashicorp/terraform/helper/schema"
 )
 
 type ErrorType int
+type SkuType int
 
 const (
-	Capacity  ErrorType = 0
-	MaxSizeGB ErrorType = 1
+	CapacityError ErrorType = 0
+	AllOtherError ErrorType = 1
 )
 
-var getDTUErrorMsg = map[string]map[ErrorType]string{
-	"basicpool": {
-		Capacity:  "service tier 'Basic' must have a 'capacity'(%d) of 50, 100, 200, 300, 400, 800, 1200 or 1600 DTUs",
-		MaxSizeGB: "service tier 'Basic' with a 'capacity' of %d must have a 'max_size_gb' of %.7f GB, got %.7f GB",
-	},
-	"standardpool": {
-		Capacity:  "service tier 'Standard' must have a 'capacity'(%d) of 50, 100, 200, 300, 400, 800, 1200, 1600, 2000, 2500 or 3000 DTUs",
-		MaxSizeGB: "service tier 'Standard' with a 'capacity' of %d must have a 'max_size_gb' no greater than %d GB, got %d GB",
-	},
-	"premiumpool": {
-		Capacity:  "service tier 'Premium' must have a 'capacity'(%d) of 125, 250, 500, 1000, 1500, 2000, 2500, 3000, 3500 or 4000 DTUs",
-		MaxSizeGB: "service tier 'Premium' with a 'capacity' of %d must have a 'max_size_gb' no greater than %d GB, got %d GB",
-	},
-}
-
-var getvCoreErrorMsg = map[string]map[string]string{
-	"generalpurpose": {
-		"gen4": "service tier 'GeneralPurpose' Gen4 must have a 'capacity'(%d) of 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 16 or 24 vCores",
-		"gen5": "service tier 'GeneralPurpose' Gen5 must have a 'capacity'(%d) of 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 24, 32, 40 or 80 vCores",
-	},
-	"businesscritical": {
-		"gen4": "service tier 'BusinessCritical' Gen4 must have a 'capacity'(%d) of 2, 3, 4, 5, 6, 7, 8, 9, 10, 16 or 24 vCores",
-		"gen5": "service tier 'BusinessCritical' Gen5 must have a 'capacity'(%d) of 4, 6, 8, 10, 12, 14, 16, 18, 20, 24, 32, 40 or 80 vCores",
-	},
-}
+const (
+	DTU   SkuType = 0
+	VCore SkuType = 1
+)
 
 var getDTUMaxGB = map[string]map[int]float64{
-	"basicpool": {
+	"basic": {
 		50:   4.8828125,
 		100:  9.765625,
 		200:  19.53125,
@@ -48,7 +33,7 @@ var getDTUMaxGB = map[string]map[int]float64{
 		1200: 117.1875,
 		1600: 156.25,
 	},
-	"standardpool": {
+	"standard": {
 		50:   500,
 		100:  750,
 		200:  1024,
@@ -61,7 +46,7 @@ var getDTUMaxGB = map[string]map[int]float64{
 		2500: 4096,
 		3000: 4096,
 	},
-	"premiumpool": {
+	"premium": {
 		125:  1024,
 		250:  1024,
 		500:  1024,
@@ -181,31 +166,70 @@ var getTierFromName = map[string]string{
 	"bc_gen5":      "BusinessCritical",
 }
 
-func MSSQLElasticPoolGetDTUBasedErrorMsg(name string, errorType ErrorType) string {
-	return getDTUErrorMsg[strings.ToLower(name)][errorType]
-}
+func MSSQLElasticPoolValidateSKU(diff *schema.ResourceDiff) error {
 
-func MSSQLElasticPoolGetvCoreBasedErrorMsg(tier string, family string) string {
-	return getvCoreErrorMsg[strings.ToLower(tier)][strings.ToLower(family)]
-}
+	name, _ := diff.GetOk("sku.0.name")
+	tier, _ := diff.GetOk("sku.0.tier")
+	capacity, _ := diff.GetOk("sku.0.capacity")
+	family, _ := diff.GetOk("sku.0.family")
+	maxSizeBytes, _ := diff.GetOk("max_size_bytes")
+	maxSizeGb, _ := diff.GetOk("max_size_gb")
+	minCapacity, _ := diff.GetOk("per_database_settings.0.min_capacity")
+	maxCapacity, _ := diff.GetOk("per_database_settings.0.max_capacity")
 
-func MSSQLElasticPoolGetDTUMaxSizeGB(name string, capacity int) float64 {
-	return getDTUMaxGB[strings.ToLower(name)][capacity]
-}
+	skuToValidate := DTU
 
-func MSSQLElasticPoolIsValidDTUMaxGBSize(gigabytes float64) bool {
-	return supportedDTUMaxGBValues[gigabytes]
-}
+	if strings.HasPrefix(strings.ToLower(name.(string)), "gp_") || strings.HasPrefix(strings.ToLower(name.(string)), "bc_") {
+		skuToValidate = VCore
+	}
 
-func MSSQLElasticPoolGetvCoreMaxSizeGB(tier string, family string, vCores int) float64 {
-	return getvCoreMaxGB[strings.ToLower(tier)][strings.ToLower(family)][vCores]
+	// Convert Bytes to Gigabytes only if max_size_gb
+	// has not changed else use max_size_gb
+	if maxSizeBytes != 0 && !diff.HasChange("max_size_gb") {
+		maxSizeGb = float64(maxSizeBytes.(int) / 1024 / 1024 / 1024)
+	}
+
+	if skuToValidate == DTU {
+		// DTU Checks
+		maxAllowedGB := getDTUMaxGB[strings.ToLower(getTierFromName[strings.ToLower(name.(string))])][capacity.(int)]
+
+		// Check to see if this is a valid SKU capacity combo
+		if errMsg := getErrorMsg(name.(string), family.(string), capacity.(int), maxAllowedGB, maxSizeGb.(float64), minCapacity.(float64), maxCapacity.(float64), CapacityError, skuToValidate); errMsg != "" {
+			return fmt.Errorf(errMsg)
+		}
+
+		// Check to see if this is a valid Max_Size_GB value
+		if errMsg := getErrorMsg(name.(string), family.(string), capacity.(int), maxAllowedGB, maxSizeGb.(float64), minCapacity.(float64), maxCapacity.(float64), AllOtherError, skuToValidate); errMsg != "" {
+			return fmt.Errorf(errMsg)
+		}
+
+	} else {
+		// vCore Checks
+		maxAllowedGB := getvCoreMaxGB[strings.ToLower(getTierFromName[strings.ToLower(name.(string))])][strings.ToLower(getFamilyFromName(strings.ToLower(name.(string))))][capacity.(int)]
+
+		if errMsg := getErrorMsg(name.(string), family.(string), capacity.(int), maxAllowedGB, maxSizeGb.(float64), minCapacity.(float64), maxCapacity.(float64), CapacityError, skuToValidate); errMsg != "" {
+			return fmt.Errorf(errMsg)
+		}
+
+		// Check to see if this is a valid Max_Size_GB value
+		if errMsg := getErrorMsg(name.(string), family.(string), capacity.(int), maxAllowedGB, maxSizeGb.(float64), minCapacity.(float64), maxCapacity.(float64), AllOtherError, skuToValidate); errMsg != "" {
+			return fmt.Errorf(errMsg)
+		}
+	}
+
+	// Universal check for all SKUs
+	if !nameTierIsValid(name.(string), tier.(string)) {
+		return fmt.Errorf("Mismatch between SKU name '%s' and tier '%s', expected 'tier' to be '%s'", name.(string), tier.(string), getTierFromName[strings.ToLower(name.(string))])
+	}
+
+	return nil
 }
 
-func MSSQLElasticPoolNameContainsFamily(name string, family string) bool {
+func nameContainsFamily(name string, family string) bool {
 	return strings.Contains(strings.ToLower(name), strings.ToLower(family))
 }
 
-func MSSQLElasticPoolNameTierIsValid(name string, tier string) bool {
+func nameTierIsValid(name string, tier string) bool {
 	if strings.EqualFold(name, "BasicPool") && !strings.EqualFold(tier, "Basic") ||
 		strings.EqualFold(name, "StandardPool") && !strings.EqualFold(tier, "Standard") ||
 		strings.EqualFold(name, "PremiumPool") && !strings.EqualFold(tier, "Premium") ||
@@ -217,11 +241,7 @@ func MSSQLElasticPoolNameTierIsValid(name string, tier string) bool {
 	return true
 }
 
-func MSSQLElasticPoolGetTierFromSKUName(name string) string {
-	return getTierFromName[strings.ToLower(name)]
-}
-
-func MSSQLElasticPoolGetFamilyFromSKUName(name string) string {
+func getFamilyFromName(name string) string {
 	if !strings.HasPrefix(strings.ToLower(name), "gp_") && !strings.HasPrefix(strings.ToLower(name), "bc_") {
 		return ""
 	}
@@ -235,3 +255,172 @@ func MSSQLElasticPoolGetFamilyFromSKUName(name string) string {
 
 	return retFamily
 }
+
+func getDTUCapacityErrorMsg(name string, capacity int) string {
+	m := getDTUMaxGB[strings.ToLower(getTierFromName[strings.ToLower(name)])]
+	return buildCapacityErrorString(name, capacity, m)
+}
+
+func getVCoreCapacityErrorMsg(name string, capacity int) string {
+	m := getvCoreMaxGB[strings.ToLower(getTierFromName[strings.ToLower(name)])][strings.ToLower(getFamilyFromName(name))]
+	return buildCapacityErrorString(name, capacity, m)
+}
+
+func buildCapacityErrorString(name string, capacity int, m map[int]float64) string {
+	var a []int
+	str := ""
+	family := getFamilyFromName(name)
+	tier := getTierFromName[strings.ToLower(name)]
+
+	if family == "" {
+		str += fmt.Sprintf("service tier '%s' must have a 'capacity'(%d) of ", tier, capacity)
+	} else {
+		str += fmt.Sprintf("service tier '%s' %s must have a 'capacity'(%d) of ", tier, family, capacity)
+	}
+
+	// copy the keys into another map
+	possible := make([]int, 0, len(m))
+	for k := range m {
+		possible = append(possible, k)
+	}
+
+	// copy the values of the map of keys into a slice of ints
+	for v := range possible {
+		a = append(a, possible[v])
+	}
+
+	// sort the slice to get them in order
+	sort.Sort(sort.IntSlice(a))
+
+	// build the error message
+	for i := range a {
+		if i < len(a)-1 {
+			str += fmt.Sprintf("%d, ", a[i])
+		} else {
+			if family == "" {
+				str += fmt.Sprintf("or %d DTUs", a[i])
+			} else {
+				str += fmt.Sprintf("or %d vCores", a[i])
+			}
+		}
+	}
+
+	return str
+}
+
+func getDTUNotValidSizeErrorMsg(name string, maxSizeGb float64) string {
+	m := supportedDTUMaxGBValues
+	var a []int
+	str := fmt.Sprintf("'max_size_gb'(%d) is not a valid value for service tier '%s', 'max_size_gb' must have a value of ", int(maxSizeGb), getTierFromName[strings.ToLower(name)])
+
+	// copy the keys into another map
+	possible := make([]int, 0, len(m))
+	for k := range m {
+		possible = append(possible, int(k))
+	}
+
+	// copy the values of the map of keys into a slice of ints
+	for v := range possible {
+		a = append(a, possible[v])
+	}
+
+	// sort the slice to get them in order
+	sort.Sort(sort.IntSlice(a))
+
+	// build the error message
+	for index := range a {
+
+		if index < len(a)-1 {
+			str += fmt.Sprintf("%d, ", a[index])
+		} else {
+			str += fmt.Sprintf("or %d GB", a[index])
+		}
+	}
+
+	return str
+}
+
+func getErrorMsg(name string, family string, capacity int, maxAllowedGB float64, maxSizeGb float64, minCapacity float64, maxCapacity float64, errType ErrorType, skuType SkuType) string {
+	errMsg := ""
+
+	if errType == CapacityError {
+		if skuType == DTU {
+			// DTU Based Capacity Errors
+			if maxAllowedGB == 0 {
+				return getDTUCapacityErrorMsg(name, capacity)
+			}
+		} else {
+			// vCore Based Capacity Errors
+			if maxAllowedGB == 0 {
+				return getVCoreCapacityErrorMsg(name, capacity)
+			}
+		}
+	} else {
+		// AllOther Errors
+		if skuType == DTU {
+			if strings.EqualFold(name, "BasicPool") {
+				// Basic SKU does not let you pick your max_size_GB they are fixed values
+				if maxSizeGb != maxAllowedGB {
+					return fmt.Sprintf("service tier 'Basic' with a 'capacity' of %d must have a 'max_size_gb' of %.7f GB, got %.7f GB", capacity, maxAllowedGB, maxSizeGb)
+				}
+			} else {
+				// All other DTU based SKUs
+				if maxSizeGb > maxAllowedGB {
+					return fmt.Sprintf("service tier '%s' with a 'capacity' of %d must have a 'max_size_gb' no greater than %d GB, got %d GB", getTierFromName[strings.ToLower(name)], capacity, int(maxAllowedGB), int(maxSizeGb))
+				}
+
+				if int(maxSizeGb) < 50 {
+					return fmt.Sprintf("service tier '%s', must have a 'max_size_gb' value equal to or greater than 50 GB, got %d GB", getTierFromName[strings.ToLower(name)], int(maxSizeGb))
+				}
+
+				// Check to see if the max_size_gb value is valid for this SKU type and capacity
+				if !supportedDTUMaxGBValues[maxSizeGb] {
+					return getDTUNotValidSizeErrorMsg(name, maxSizeGb)
+				}
+			}
+
+			// All Other DTU based SKU Checks
+			if family != "" {
+				return fmt.Sprintf("Invalid attribute 'family' (%s) for service tiers 'Basic', 'Standard', and 'Premium', remove the 'family' attribute from the configuration file", family)
+			}
+			if minCapacity != math.Trunc(minCapacity) {
+				return fmt.Sprintf("service tiers 'Basic', 'Standard', and 'Premium' must have whole numbers as their 'minCapacity'")
+			}
+
+			if maxCapacity != math.Trunc(maxCapacity) {
+				return fmt.Sprintf("service tiers 'Basic', 'Standard', and 'Premium' must have whole numbers as their 'maxCapacity'")
+			}
+
+			if minCapacity < 0.0 {
+				return fmt.Sprintf("service tiers 'Basic', 'Standard', and 'Premium' per_database_settings 'min_capacity' must be equal to or greater than zero")
+			}
+		} else {
+			// vCore Based AllOther Errors
+			if maxSizeGb > maxAllowedGB {
+				return fmt.Sprintf("service tier '%s' %s with a 'capacity' of %d vCores must have a 'max_size_gb' between 5 GB and %d GB, got %d GB", getTierFromName[strings.ToLower(name)], family, capacity, int(maxAllowedGB), int(maxSizeGb))
+			}
+
+			if int(maxSizeGb) < 5 {
+				return fmt.Sprintf("service tier '%s' must have a 'max_size_gb' value equal to or greater than 5 GB, got %d GB", getTierFromName[strings.ToLower(name)], int(maxSizeGb))
+			}
+
+			if maxSizeGb != math.Trunc(maxSizeGb) {
+				return fmt.Sprintf("'max_size_gb' must be a whole number, got %f GB", maxSizeGb)
+			}
+
+			if !nameContainsFamily(name, family) {
+				return fmt.Sprintf("Mismatch between SKU name '%s' and family '%s', expected '%s'", name, family, getFamilyFromName(name))
+			}
+
+			if maxCapacity > float64(capacity) {
+				return fmt.Sprintf("service tier '%s' perDatabaseSettings 'maxCapacity' must not be higher than the SKUs 'capacity'(%d) value", getTierFromName[strings.ToLower(name)], capacity)
+			}
+
+			if minCapacity > maxCapacity {
+				return fmt.Sprintf("perDatabaseSettings 'maxCapacity' must be greater than or equal to the perDatabaseSettings 'minCapacity' value")
+			}
+		}
+	}
+
+	return errMsg
+}
diff --git a/azurerm/resource_arm_mssql_elasticpool.go b/azurerm/resource_arm_mssql_elasticpool.go
index 0454bcb467e5..f64bd09395df 100644
--- a/azurerm/resource_arm_mssql_elasticpool.go
+++ b/azurerm/resource_arm_mssql_elasticpool.go
@@ -3,7 +3,6 @@ package azurerm
 import (
 	"fmt"
 	"log"
-	"math"
 	"strings"
 
 	"github.com/Azure/azure-sdk-for-go/services/preview/sql/mgmt/2017-10-01-preview/sql"
@@ -185,105 +184,8 @@ func resourceArmMsSqlElasticPool() *schema.Resource {
 
 		CustomizeDiff: func(diff *schema.ResourceDiff, v interface{}) error {
 
-			name, _ := diff.GetOk("sku.0.name")
-			tier, _ := diff.GetOk("sku.0.tier")
-			capacity, _ := diff.GetOk("sku.0.capacity")
-			family, _ := diff.GetOk("sku.0.family")
-			maxSizeBytes, _ := diff.GetOk("max_size_bytes")
-			maxSizeGb, _ := diff.GetOk("max_size_gb")
-			minCapacity, _ := diff.GetOk("per_database_settings.0.min_capacity")
-			maxCapacity, _ := diff.GetOk("per_database_settings.0.max_capacity")
-
-			// Convert Bytes to Gigabytes only if max_size_gb
-			// has not changed else use max_size_gb
-			if maxSizeBytes != 0 && !diff.HasChange("max_size_gb") {
-				maxSizeGb = float64(maxSizeBytes.(int) / 1024 / 1024 / 1024)
-			}
-
-			if !strings.HasPrefix(strings.ToLower(name.(string)), "gp_") && !strings.HasPrefix(strings.ToLower(name.(string)), "bc_") {
-				// DTU Based Checks
-
-				maxAllowedGB := azure.MSSQLElasticPoolGetDTUMaxSizeGB(name.(string), capacity.(int))
-
-				if maxAllowedGB == 0 {
-					return fmt.Errorf(azure.MSSQLElasticPoolGetDTUBasedErrorMsg(name.(string), azure.Capacity), capacity.(int))
-				}
-
-				if strings.EqualFold(name.(string), "BasicPool") {
-					// Basic SKU does not let you pick your max_size_GB they are fixed values
-					if maxSizeGb.(float64) != maxAllowedGB {
-						return fmt.Errorf(azure.MSSQLElasticPoolGetDTUBasedErrorMsg(name.(string), azure.MaxSizeGB), capacity.(int), maxAllowedGB, maxSizeGb.(float64))
-					}
-				} else {
-					// All other DTU based SKUs
-					if maxSizeGb.(float64) > maxAllowedGB {
-						return fmt.Errorf(azure.MSSQLElasticPoolGetDTUBasedErrorMsg(name.(string), azure.MaxSizeGB), capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
-					}
-				}
-
-				if !strings.EqualFold(name.(string), "BasicPool") {
-					if int(maxSizeGb.(float64)) < 50 {
-						return fmt.Errorf("service tier '%s', must have a 'max_size_gb' value equal to or greater than 50 GB, got %d GB", azure.MSSQLElasticPoolGetTierFromSKUName(name.(string)), int(maxSizeGb.(float64)))
-					}
-
-					if !azure.MSSQLElasticPoolIsValidDTUMaxGBSize(maxSizeGb.(float64)) {
-						return fmt.Errorf("'max_size_gb'(%d) is not a valid value for service tier '%s', 'max_size_gb' must have a value of 50, 100, 150, 200, 250, 300, 400, 500, 750, 800, 1024, 1200, 1280, 1536, 1600, 1792, 2000, 2048, 2304, 2500, 2560, 2816, 3000, 3072, 3328, 3584, 3840 or 4096", int(maxSizeGb.(float64)), azure.MSSQLElasticPoolGetTierFromSKUName(name.(string)))
-					}
-				}
-
-				if family.(string) != "" {
-					return fmt.Errorf("Invalid attribute 'family' (%s) for service tiers 'Basic', 'Standard', and 'Premium', remove the 'family' attribute from the configuration file", family.(string))
-				}
-
-				if minCapacity.(float64) != math.Trunc(minCapacity.(float64)) {
-					return fmt.Errorf("service tiers 'Basic', 'Standard', and 'Premium' must have whole numbers as their 'minCapacity'")
-				}
-
-				if maxCapacity.(float64) != math.Trunc(maxCapacity.(float64)) {
-					return fmt.Errorf("service tiers 'Basic', 'Standard', and 'Premium' must have whole numbers as their 'maxCapacity'")
-				}
-
-				if minCapacity.(float64) < 0.0 {
-					return fmt.Errorf("service tiers 'Basic', 'Standard', and 'Premium' per_database_settings 'min_capacity' must be equal to or greater than zero")
-				}
-
-			} else {
-				// vCore Based Checks
-
-				maxAllowedGB := azure.MSSQLElasticPoolGetvCoreMaxSizeGB(azure.MSSQLElasticPoolGetTierFromSKUName(name.(string)), family.(string), capacity.(int))
-
-				if maxAllowedGB == 0 {
-					return fmt.Errorf(azure.MSSQLElasticPoolGetvCoreBasedErrorMsg(azure.MSSQLElasticPoolGetTierFromSKUName(name.(string)), azure.MSSQLElasticPoolGetFamilyFromSKUName(name.(string))), capacity.(int))
-				}
-
-				if maxSizeGb.(float64) > maxAllowedGB {
-					return fmt.Errorf("service tier '%s' %s with a 'capacity' of %d vCores must have a 'max_size_gb' between 5 GB and %d GB, got %d GB", azure.MSSQLElasticPoolGetTierFromSKUName(name.(string)), family.(string), capacity.(int), int(maxAllowedGB), int(maxSizeGb.(float64)))
-				}
-
-				if int(maxSizeGb.(float64)) < 5 {
-					return fmt.Errorf("service tier '%s' must have a 'max_size_gb' value equal to or greater than 5 GB, got %d GB", azure.MSSQLElasticPoolGetTierFromSKUName(name.(string)), int(maxSizeGb.(float64)))
-				}
-
-				if maxSizeGb.(float64) != math.Trunc(maxSizeGb.(float64)) {
-					return fmt.Errorf("'max_size_gb' must be a whole number, got %f GB", maxSizeGb.(float64))
-				}
-
-				if !azure.MSSQLElasticPoolNameContainsFamily(name.(string), family.(string)) {
-					return fmt.Errorf("Mismatch between SKU name '%s' and family '%s', expected '%s'", name.(string), family.(string), azure.MSSQLElasticPoolGetFamilyFromSKUName(name.(string)))
-				}
-
-				if maxCapacity.(float64) > float64(capacity.(int)) {
-					return fmt.Errorf("service tier '%s' perDatabaseSettings 'maxCapacity' must not be higher than the SKUs 'capacity'(%d) value", azure.MSSQLElasticPoolGetTierFromSKUName(name.(string)), capacity.(int))
-				}
-
-				if minCapacity.(float64) > maxCapacity.(float64) {
-					return fmt.Errorf("perDatabaseSettings 'maxCapacity' must be greater than or equal to the perDatabaseSettings 'minCapacity' value")
-				}
-			}
-
-			// Universal check for all SKUs
-			if !azure.MSSQLElasticPoolNameTierIsValid(name.(string), tier.(string)) {
-				return fmt.Errorf("Mismatch between SKU name '%s' and tier '%s', expected 'tier' to be '%s'", name.(string), tier.(string), azure.MSSQLElasticPoolGetTierFromSKUName(name.(string)))
+			if err := azure.MSSQLElasticPoolValidateSKU(diff); err != nil {
+				return err
 			}
 
 			return nil

From 66ac53b6aa7fd464c8ea417c96b79c17ca8e756c Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Fri, 1 Feb 2019 12:41:12 -0800
Subject: [PATCH 34/45] Added descriptions of maps

---
 azurerm/helpers/azure/elasticpool.go | 179 ++++++++++++++++-----------
 1 file changed, 109 insertions(+), 70 deletions(-)

diff --git a/azurerm/helpers/azure/elasticpool.go b/azurerm/helpers/azure/elasticpool.go
index 0b9d6ac30081..8406d9a645fb 100644
--- a/azurerm/helpers/azure/elasticpool.go
+++ b/azurerm/helpers/azure/elasticpool.go
@@ -9,19 +9,32 @@ import (
 	"github.com/hashicorp/terraform/helper/schema"
 )
 
-type ErrorType int
-type SkuType int
+type errorType int
+type skuType int
 
 const (
-	CapacityError ErrorType = 0
-	AllOtherError ErrorType = 1
+	capacityError errorType = 0
+	allOtherError errorType = 1
 )
 
 const (
-	DTU   SkuType = 0
-	VCore SkuType = 1
+	DTU   skuType = 0
+	VCore skuType = 1
 )
 
+type sku struct {
+	Name, Tier, Family                                string
+	Capacity                                          int
+	MaxAllowedGB, MaxSizeGb, MinCapacity, MaxCapacity float64
+	ErrorType                                         errorType
+	SkuType                                           skuType
+}
+
+// getDTUMaxGB: this map holds all of the DTU to 'max_size_gb' mappings based on a DTU lookup
+//              note that the value can be below the returned value, except for 'basic' it's
+//              value must match exactly what is returned else it will be rejected by the API
+//              which will return a 'Internal Server Error'
+
 var getDTUMaxGB = map[string]map[int]float64{
 	"basic": {
 		50:   4.8828125,
@@ -60,6 +73,11 @@ var getDTUMaxGB = map[string]map[int]float64{
 	},
 }
 
+// supportedDTUMaxGBValues: this map holds all of the valid 'max_size_gb' values
+//                          for a DTU SKU type. If the 'max_size_gb' is anything
+//                          other than the values in the map the API with throw
+//                          an 'Internal Server Error'
+
 var supportedDTUMaxGBValues = map[float64]bool{
 	50:   true,
 	100:  true,
@@ -91,6 +109,9 @@ var supportedDTUMaxGBValues = map[float64]bool{
 	4096: true,
 }
 
+// getvCoreMaxGB: this map holds all of the vCore to 'max_size_gb' mappings based on a vCore lookup
+//                note that the value can be below the returned value
+
 var getvCoreMaxGB = map[string]map[string]map[int]float64{
 	"generalpurpose": {
 		"gen4": {
@@ -156,6 +177,12 @@ var getvCoreMaxGB = map[string]map[string]map[int]float64{
 	},
 }
 
+// getTierFromName: this map contains all of the valid mappings between 'name' and 'tier'
+//                  the reason for this map is that the user may pass in an invalid mapping
+//                  (e.g. name: "Basicpool" tier:"BusinessCritical") this map allows me
+//                  to lookup the correct values in other maps even if the config file
+//                  contains an invalid 'tier' attribute.
+
 var getTierFromName = map[string]string{
 	"basicpool":    "Basic",
 	"standardpool": "Standard",
@@ -177,49 +204,61 @@ func MSSQLElasticPoolValidateSKU(diff *schema.ResourceDiff) error {
 	minCapacity, _ := diff.GetOk("per_database_settings.0.min_capacity")
 	maxCapacity, _ := diff.GetOk("per_database_settings.0.max_capacity")
 
-	skuToValidate := DTU
+	s := sku{
+		Name:        name.(string),
+		Tier:        tier.(string),
+		Family:      family.(string),
+		Capacity:    capacity.(int),
+		MaxSizeGb:   maxSizeGb.(float64),
+		MinCapacity: minCapacity.(float64),
+		MaxCapacity: maxCapacity.(float64),
+		ErrorType:   capacityError,
+		SkuType:     DTU,
+	}
 
 	if strings.HasPrefix(strings.ToLower(name.(string)), "gp_") || strings.HasPrefix(strings.ToLower(name.(string)), "bc_") {
-		skuToValidate = VCore
+		s.SkuType = VCore
 	}
 
 	// Convert Bytes to Gigabytes only if max_size_gb
 	// has not changed else use max_size_gb
-	if maxSizeBytes != 0 && !diff.HasChange("max_size_gb") {
-		maxSizeGb = float64(maxSizeBytes.(int) / 1024 / 1024 / 1024)
+	if maxSizeBytes.(int) != 0 && !diff.HasChange("max_size_gb") {
+		s.MaxSizeGb = float64(maxSizeBytes.(int) / 1024 / 1024 / 1024)
 	}
 
-	if skuToValidate == DTU {
+	if s.SkuType == DTU {
 		// DTU Checks
-		maxAllowedGB := getDTUMaxGB[strings.ToLower(getTierFromName[strings.ToLower(name.(string))])][capacity.(int)]
+		s.MaxAllowedGB = getDTUMaxGB[strings.ToLower(getTierFromName[strings.ToLower(s.Name)])][s.Capacity]
 
 		// Check to see if this is a valid SKU capacity combo
-		if errMsg := getErrorMsg(name.(string), family.(string), capacity.(int), maxAllowedGB, maxSizeGb.(float64), minCapacity.(float64), maxCapacity.(float64), CapacityError, skuToValidate); errMsg != "" {
+		if errMsg := doSKUValidation(s); errMsg != "" {
 			return fmt.Errorf(errMsg)
 		}
 
 		// Check to see if this is a valid Max_Size_GB value
-		if errMsg := getErrorMsg(name.(string), family.(string), capacity.(int), maxAllowedGB, maxSizeGb.(float64), minCapacity.(float64), maxCapacity.(float64), AllOtherError, skuToValidate); errMsg != "" {
+		s.ErrorType = allOtherError
+		if errMsg := doSKUValidation(s); errMsg != "" {
 			return fmt.Errorf(errMsg)
 		}
 
 	} else {
 		// vCore Checks
-		maxAllowedGB := getvCoreMaxGB[strings.ToLower(getTierFromName[strings.ToLower(name.(string))])][strings.ToLower(getFamilyFromName(strings.ToLower(name.(string))))][capacity.(int)]
+		s.MaxAllowedGB = getvCoreMaxGB[strings.ToLower(getTierFromName[strings.ToLower(s.Name)])][strings.ToLower(getFamilyFromName(strings.ToLower(s.Name)))][s.Capacity]
 
-		if errMsg := getErrorMsg(name.(string), family.(string), capacity.(int), maxAllowedGB, maxSizeGb.(float64), minCapacity.(float64), maxCapacity.(float64), CapacityError, skuToValidate); errMsg != "" {
+		if errMsg := doSKUValidation(s); errMsg != "" {
 			return fmt.Errorf(errMsg)
 		}
 
 		// Check to see if this is a valid Max_Size_GB value
-		if errMsg := getErrorMsg(name.(string), family.(string), capacity.(int), maxAllowedGB, maxSizeGb.(float64), minCapacity.(float64), maxCapacity.(float64), AllOtherError, skuToValidate); errMsg != "" {
+		s.ErrorType = allOtherError
+		if errMsg := doSKUValidation(s); errMsg != "" {
 			return fmt.Errorf(errMsg)
 		}
 	}
 
 	// Universal check for all SKUs
-	if !nameTierIsValid(name.(string), tier.(string)) {
-		return fmt.Errorf("Mismatch between SKU name '%s' and tier '%s', expected 'tier' to be '%s'", name.(string), tier.(string), getTierFromName[strings.ToLower(name.(string))])
+	if !nameTierIsValid(s.Name, s.Tier) {
+		return fmt.Errorf("Mismatch between SKU name '%s' and tier '%s', expected 'tier' to be '%s'", s.Name, s.Tier, getTierFromName[strings.ToLower(s.Name)])
 	}
 
 	return nil
@@ -258,15 +297,15 @@ func getFamilyFromName(name string) string {
 
 func getDTUCapacityErrorMsg(name string, capacity int) string {
 	m := getDTUMaxGB[strings.ToLower(getTierFromName[strings.ToLower(name)])]
-	return buildCapacityErrorString(name, capacity, m)
+	return buildcapacityErrorString(name, capacity, m)
 }
 
 func getVCoreCapacityErrorMsg(name string, capacity int) string {
 	m := getvCoreMaxGB[strings.ToLower(getTierFromName[strings.ToLower(name)])][strings.ToLower(getFamilyFromName(name))]
-	return buildCapacityErrorString(name, capacity, m)
+	return buildcapacityErrorString(name, capacity, m)
 }
 
-func buildCapacityErrorString(name string, capacity int, m map[int]float64) string {
+func buildcapacityErrorString(name string, capacity int, m map[int]float64) string {
 	var a []int
 	str := ""
 	family := getFamilyFromName(name)
@@ -279,18 +318,18 @@ func buildCapacityErrorString(name string, capacity int, m map[int]float64) stri
 	}
 
 	// copy the keys into another map
-	possible := make([]int, 0, len(m))
+	p := make([]int, 0, len(m))
 	for k := range m {
-		possible = append(possible, k)
+		p = append(p, k)
 	}
 
 	// copy the values of the map of keys into a slice of ints
-	for v := range possible {
-		a = append(a, possible[v])
+	for v := range p {
+		a = append(a, p[v])
 	}
 
 	// sort the slice to get them in order
-	sort.Sort(sort.IntSlice(a))
+	sort.Ints(a)
 
 	// build the error message
 	for i := range a {
@@ -314,109 +353,109 @@ func getDTUNotValidSizeErrorMsg(name string, maxSizeGb float64) string {
 	str := fmt.Sprintf("'max_size_gb'(%d) is not a valid value for service tier '%s', 'max_size_gb' must have a value of ", int(maxSizeGb), getTierFromName[strings.ToLower(name)])
 
 	// copy the keys into another map
-	possible := make([]int, 0, len(m))
+	p := make([]int, 0, len(m))
 	for k := range m {
-		possible = append(possible, int(k))
+		p = append(p, int(k))
 	}
 
 	// copy the values of the map of keys into a slice of ints
-	for v := range possible {
-		a = append(a, possible[v])
+	for v := range p {
+		a = append(a, p[v])
 	}
 
 	// sort the slice to get them in order
-	sort.Sort(sort.IntSlice(a))
+	sort.Ints(a)
 
 	// build the error message
-	for index := range a {
+	for i := range a {
 
-		if index < len(a)-1 {
-			str += fmt.Sprintf("%d, ", a[index])
+		if i < len(a)-1 {
+			str += fmt.Sprintf("%d, ", a[i])
 		} else {
-			str += fmt.Sprintf("or %d GB", a[index])
+			str += fmt.Sprintf("or %d GB", a[i])
 		}
 	}
 
 	return str
 }
 
-func getErrorMsg(name string, family string, capacity int, maxAllowedGB float64, maxSizeGb float64, minCapacity float64, maxCapacity float64, errType ErrorType, skuType SkuType) string {
+func doSKUValidation(s sku) string {
 	errMsg := ""
 
-	if errType == CapacityError {
-		if skuType == DTU {
+	if s.ErrorType == capacityError {
+		if s.SkuType == DTU {
 			// DTU Based Capacity Errors
-			if maxAllowedGB == 0 {
-				return getDTUCapacityErrorMsg(name, capacity)
+			if s.MaxAllowedGB == 0 {
+				return getDTUCapacityErrorMsg(s.Name, s.Capacity)
 			}
 		} else {
 			// vCore Based Capacity Errors
-			if maxAllowedGB == 0 {
-				return getVCoreCapacityErrorMsg(name, capacity)
+			if s.MaxAllowedGB == 0 {
+				return getVCoreCapacityErrorMsg(s.Name, s.Capacity)
 			}
 		}
 	} else {
 		// AllOther Errors
-		if skuType == DTU {
-			if strings.EqualFold(name, "BasicPool") {
+		if s.SkuType == DTU {
+			if strings.EqualFold(s.Name, "BasicPool") {
 				// Basic SKU does not let you pick your max_size_GB they are fixed values
-				if maxSizeGb != maxAllowedGB {
-					return fmt.Sprintf("service tier 'Basic' with a 'capacity' of %d must have a 'max_size_gb' of %.7f GB, got %.7f GB", capacity, maxAllowedGB, maxSizeGb)
+				if s.MaxSizeGb != s.MaxAllowedGB {
+					return fmt.Sprintf("service tier 'Basic' with a 'capacity' of %d must have a 'max_size_gb' of %.7f GB, got %.7f GB", s.Capacity, s.MaxAllowedGB, s.MaxSizeGb)
 				}
 			} else {
 				// All other DTU based SKUs
-				if maxSizeGb > maxAllowedGB {
-					return fmt.Sprintf("service tier '%s' with a 'capacity' of %d must have a 'max_size_gb' no greater than %d GB, got %d GB", getTierFromName[strings.ToLower(name)], capacity, int(maxAllowedGB), int(maxSizeGb))
+				if s.MaxSizeGb > s.MaxAllowedGB {
+					return fmt.Sprintf("service tier '%s' with a 'capacity' of %d must have a 'max_size_gb' no greater than %d GB, got %d GB", getTierFromName[strings.ToLower(s.Name)], s.Capacity, int(s.MaxAllowedGB), int(s.MaxSizeGb))
 				}
 
-				if int(maxSizeGb) < 50 {
-					return fmt.Sprintf("service tier '%s', must have a 'max_size_gb' value equal to or greater than 50 GB, got %d GB", getTierFromName[strings.ToLower(name)], int(maxSizeGb))
+				if int(s.MaxSizeGb) < 50 {
+					return fmt.Sprintf("service tier '%s', must have a 'max_size_gb' value equal to or greater than 50 GB, got %d GB", getTierFromName[strings.ToLower(s.Name)], int(s.MaxSizeGb))
 				}
 
 				// Check to see if the max_size_gb value is valid for this SKU type and capacity
-				if !supportedDTUMaxGBValues[maxSizeGb] {
-					return getDTUNotValidSizeErrorMsg(name, maxSizeGb)
+				if !supportedDTUMaxGBValues[s.MaxSizeGb] {
+					return getDTUNotValidSizeErrorMsg(s.Name, s.MaxSizeGb)
 				}
 			}
 
 			// All Other DTU based SKU Checks
-			if family != "" {
-				return fmt.Sprintf("Invalid attribute 'family' (%s) for service tiers 'Basic', 'Standard', and 'Premium', remove the 'family' attribute from the configuration file", family)
+			if s.Family != "" {
+				return fmt.Sprintf("Invalid attribute 'family' (%s) for service tiers 'Basic', 'Standard', and 'Premium', remove the 'family' attribute from the configuration file", s.Family)
 			}
-			if minCapacity != math.Trunc(minCapacity) {
+			if s.MinCapacity != math.Trunc(s.MinCapacity) {
 				return fmt.Sprintf("service tiers 'Basic', 'Standard', and 'Premium' must have whole numbers as their 'minCapacity'")
 			}
 
-			if maxCapacity != math.Trunc(maxCapacity) {
+			if s.MaxCapacity != math.Trunc(s.MaxCapacity) {
 				return fmt.Sprintf("service tiers 'Basic', 'Standard', and 'Premium' must have whole numbers as their 'maxCapacity'")
 			}
 
-			if minCapacity < 0.0 {
+			if s.MinCapacity < 0.0 {
 				return fmt.Sprintf("service tiers 'Basic', 'Standard', and 'Premium' per_database_settings 'min_capacity' must be equal to or greater than zero")
 			}
 		} else {
-			// vCore Based AllOther Errors
-			if maxSizeGb > maxAllowedGB {
-				return fmt.Sprintf("service tier '%s' %s with a 'capacity' of %d vCores must have a 'max_size_gb' between 5 GB and %d GB, got %d GB", getTierFromName[strings.ToLower(name)], family, capacity, int(maxAllowedGB), int(maxSizeGb))
+			// vCore Based Errors
+			if s.MaxSizeGb > s.MaxAllowedGB {
+				return fmt.Sprintf("service tier '%s' %s with a 'capacity' of %d vCores must have a 'max_size_gb' between 5 GB and %d GB, got %d GB", getTierFromName[strings.ToLower(s.Name)], s.Family, s.Capacity, int(s.MaxAllowedGB), int(s.MaxSizeGb))
 			}
 
-			if int(maxSizeGb) < 5 {
-				return fmt.Sprintf("service tier '%s' must have a 'max_size_gb' value equal to or greater than 5 GB, got %d GB", getTierFromName[strings.ToLower(name)], int(maxSizeGb))
+			if int(s.MaxSizeGb) < 5 {
+				return fmt.Sprintf("service tier '%s' must have a 'max_size_gb' value equal to or greater than 5 GB, got %d GB", getTierFromName[strings.ToLower(s.Name)], int(s.MaxSizeGb))
 			}
 
-			if maxSizeGb != math.Trunc(maxSizeGb) {
-				return fmt.Sprintf("'max_size_gb' must be a whole number, got %f GB", maxSizeGb)
+			if s.MaxSizeGb != math.Trunc(s.MaxSizeGb) {
+				return fmt.Sprintf("'max_size_gb' must be a whole number, got %f GB", s.MaxSizeGb)
 			}
 
-			if !nameContainsFamily(name, family) {
-				return fmt.Sprintf("Mismatch between SKU name '%s' and family '%s', expected '%s'", name, family, getFamilyFromName(name))
+			if !nameContainsFamily(s.Name, s.Family) {
+				return fmt.Sprintf("Mismatch between SKU name '%s' and family '%s', expected '%s'", s.Name, s.Family, getFamilyFromName(s.Name))
 			}
 
-			if maxCapacity > float64(capacity) {
-				return fmt.Sprintf("service tier '%s' perDatabaseSettings 'maxCapacity' must not be higher than the SKUs 'capacity'(%d) value", getTierFromName[strings.ToLower(name)], capacity)
+			if s.MaxCapacity > float64(s.Capacity) {
+				return fmt.Sprintf("service tier '%s' perDatabaseSettings 'maxCapacity' must not be higher than the SKUs 'capacity'(%d) value", getTierFromName[strings.ToLower(s.Name)], s.Capacity)
 			}
 
-			if minCapacity > maxCapacity {
+			if s.MinCapacity > s.MaxCapacity {
 				return fmt.Sprintf("perDatabaseSettings 'maxCapacity' must be greater than or equal to the perDatabaseSettings 'minCapacity' value")
 			}
 		}

From 98eb1d3f587f2debd99b429eb67b3acdbf16ceb4 Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Fri, 1 Feb 2019 14:24:32 -0800
Subject: [PATCH 35/45] Unifying func signatures

---
 azurerm/helpers/azure/elasticpool.go | 83 +++++++++++++---------------
 1 file changed, 39 insertions(+), 44 deletions(-)

diff --git a/azurerm/helpers/azure/elasticpool.go b/azurerm/helpers/azure/elasticpool.go
index 8406d9a645fb..3c24d5952d51 100644
--- a/azurerm/helpers/azure/elasticpool.go
+++ b/azurerm/helpers/azure/elasticpool.go
@@ -216,7 +216,8 @@ func MSSQLElasticPoolValidateSKU(diff *schema.ResourceDiff) error {
 		SkuType:     DTU,
 	}
 
-	if strings.HasPrefix(strings.ToLower(name.(string)), "gp_") || strings.HasPrefix(strings.ToLower(name.(string)), "bc_") {
+	// Check to see if the name describes a vCore type SKU
+	if strings.HasPrefix(strings.ToLower(s.Name), "gp_") || strings.HasPrefix(strings.ToLower(s.Name), "bc_") {
 		s.SkuType = VCore
 	}
 
@@ -243,7 +244,7 @@ func MSSQLElasticPoolValidateSKU(diff *schema.ResourceDiff) error {
 
 	} else {
 		// vCore Checks
-		s.MaxAllowedGB = getvCoreMaxGB[strings.ToLower(getTierFromName[strings.ToLower(s.Name)])][strings.ToLower(getFamilyFromName(strings.ToLower(s.Name)))][s.Capacity]
+		s.MaxAllowedGB = getvCoreMaxGB[strings.ToLower(getTierFromName[strings.ToLower(s.Name)])][strings.ToLower(getFamilyFromName(s))][s.Capacity]
 
 		if errMsg := doSKUValidation(s); errMsg != "" {
 			return fmt.Errorf(errMsg)
@@ -257,35 +258,35 @@ func MSSQLElasticPoolValidateSKU(diff *schema.ResourceDiff) error {
 	}
 
 	// Universal check for all SKUs
-	if !nameTierIsValid(s.Name, s.Tier) {
+	if !nameTierIsValid(s) {
 		return fmt.Errorf("Mismatch between SKU name '%s' and tier '%s', expected 'tier' to be '%s'", s.Name, s.Tier, getTierFromName[strings.ToLower(s.Name)])
 	}
 
 	return nil
 }
 
-func nameContainsFamily(name string, family string) bool {
-	return strings.Contains(strings.ToLower(name), strings.ToLower(family))
+func nameContainsFamily(s sku) bool {
+	return strings.Contains(strings.ToLower(s.Name), strings.ToLower(s.Family))
 }
 
-func nameTierIsValid(name string, tier string) bool {
-	if strings.EqualFold(name, "BasicPool") && !strings.EqualFold(tier, "Basic") ||
-		strings.EqualFold(name, "StandardPool") && !strings.EqualFold(tier, "Standard") ||
-		strings.EqualFold(name, "PremiumPool") && !strings.EqualFold(tier, "Premium") ||
-		strings.HasPrefix(strings.ToLower(name), "gp_") && !strings.EqualFold(tier, "GeneralPurpose") ||
-		strings.HasPrefix(strings.ToLower(name), "bc_") && !strings.EqualFold(tier, "BusinessCritical") {
+func nameTierIsValid(s sku) bool {
+	if strings.EqualFold(s.Name, "BasicPool") && !strings.EqualFold(s.Tier, "Basic") ||
+		strings.EqualFold(s.Name, "StandardPool") && !strings.EqualFold(s.Tier, "Standard") ||
+		strings.EqualFold(s.Name, "PremiumPool") && !strings.EqualFold(s.Tier, "Premium") ||
+		strings.HasPrefix(strings.ToLower(s.Name), "gp_") && !strings.EqualFold(s.Tier, "GeneralPurpose") ||
+		strings.HasPrefix(strings.ToLower(s.Name), "bc_") && !strings.EqualFold(s.Tier, "BusinessCritical") {
 		return false
 	}
 
 	return true
 }
 
-func getFamilyFromName(name string) string {
-	if !strings.HasPrefix(strings.ToLower(name), "gp_") && !strings.HasPrefix(strings.ToLower(name), "bc_") {
+func getFamilyFromName(s sku) string {
+	if !strings.HasPrefix(strings.ToLower(s.Name), "gp_") && !strings.HasPrefix(strings.ToLower(s.Name), "bc_") {
 		return ""
 	}
 
-	nameFamily := name[3:]
+	nameFamily := s.Name[3:]
 	retFamily := "Gen4" // Default
 
 	if strings.EqualFold(nameFamily, "Gen5") {
@@ -295,26 +296,26 @@ func getFamilyFromName(name string) string {
 	return retFamily
 }
 
-func getDTUCapacityErrorMsg(name string, capacity int) string {
-	m := getDTUMaxGB[strings.ToLower(getTierFromName[strings.ToLower(name)])]
-	return buildcapacityErrorString(name, capacity, m)
+func getDTUCapacityErrorMsg(s sku) string {
+	m := getDTUMaxGB[strings.ToLower(getTierFromName[strings.ToLower(s.Name)])]
+	return buildcapacityErrorString(s, m)
 }
 
-func getVCoreCapacityErrorMsg(name string, capacity int) string {
-	m := getvCoreMaxGB[strings.ToLower(getTierFromName[strings.ToLower(name)])][strings.ToLower(getFamilyFromName(name))]
-	return buildcapacityErrorString(name, capacity, m)
+func getVCoreCapacityErrorMsg(s sku) string {
+	m := getvCoreMaxGB[strings.ToLower(getTierFromName[strings.ToLower(s.Name)])][strings.ToLower(getFamilyFromName(s))]
+	return buildcapacityErrorString(s, m)
 }
 
-func buildcapacityErrorString(name string, capacity int, m map[int]float64) string {
+func buildcapacityErrorString(s sku, m map[int]float64) string {
 	var a []int
 	str := ""
-	family := getFamilyFromName(name)
-	tier := getTierFromName[strings.ToLower(name)]
+	family := getFamilyFromName(s)
+	tier := getTierFromName[strings.ToLower(s.Name)]
 
-	if family == "" {
-		str += fmt.Sprintf("service tier '%s' must have a 'capacity'(%d) of ", tier, capacity)
+	if s.SkuType == DTU {
+		str += fmt.Sprintf("service tier '%s' must have a 'capacity'(%d) of ", tier, s.Capacity)
 	} else {
-		str += fmt.Sprintf("service tier '%s' %s must have a 'capacity'(%d) of ", tier, family, capacity)
+		str += fmt.Sprintf("service tier '%s' %s must have a 'capacity'(%d) of ", tier, family, s.Capacity)
 	}
 
 	// copy the keys into another map
@@ -336,7 +337,7 @@ func buildcapacityErrorString(name string, capacity int, m map[int]float64) stri
 		if i < len(a)-1 {
 			str += fmt.Sprintf("%d, ", a[i])
 		} else {
-			if family == "" {
+			if s.SkuType == DTU {
 				str += fmt.Sprintf("or %d DTUs", a[i])
 			} else {
 				str += fmt.Sprintf("or %d vCores", a[i])
@@ -347,10 +348,10 @@ func buildcapacityErrorString(name string, capacity int, m map[int]float64) stri
 	return str
 }
 
-func getDTUNotValidSizeErrorMsg(name string, maxSizeGb float64) string {
+func getDTUNotValidSizeErrorMsg(s sku) string {
 	m := supportedDTUMaxGBValues
 	var a []int
-	str := fmt.Sprintf("'max_size_gb'(%d) is not a valid value for service tier '%s', 'max_size_gb' must have a value of ", int(maxSizeGb), getTierFromName[strings.ToLower(name)])
+	str := fmt.Sprintf("'max_size_gb'(%d) is not a valid value for service tier '%s', 'max_size_gb' must have a value of ", int(s.MaxSizeGb), getTierFromName[strings.ToLower(s.Name)])
 
 	// copy the keys into another map
 	p := make([]int, 0, len(m))
@@ -383,18 +384,12 @@ func doSKUValidation(s sku) string {
 	errMsg := ""
 
 	if s.ErrorType == capacityError {
-		if s.SkuType == DTU {
-			// DTU Based Capacity Errors
-			if s.MaxAllowedGB == 0 {
-				return getDTUCapacityErrorMsg(s.Name, s.Capacity)
-			}
-		} else {
-			// vCore Based Capacity Errors
-			if s.MaxAllowedGB == 0 {
-				return getVCoreCapacityErrorMsg(s.Name, s.Capacity)
-			}
+		if s.SkuType == DTU && s.MaxAllowedGB == 0 {
+			return getDTUCapacityErrorMsg(s)
+		} else if s.SkuType == VCore && s.MaxAllowedGB == 0 {
+			return getVCoreCapacityErrorMsg(s)
 		}
-	} else {
+	} else if s.ErrorType == allOtherError {
 		// AllOther Errors
 		if s.SkuType == DTU {
 			if strings.EqualFold(s.Name, "BasicPool") {
@@ -414,7 +409,7 @@ func doSKUValidation(s sku) string {
 
 				// Check to see if the max_size_gb value is valid for this SKU type and capacity
 				if !supportedDTUMaxGBValues[s.MaxSizeGb] {
-					return getDTUNotValidSizeErrorMsg(s.Name, s.MaxSizeGb)
+					return getDTUNotValidSizeErrorMsg(s)
 				}
 			}
 
@@ -433,7 +428,7 @@ func doSKUValidation(s sku) string {
 			if s.MinCapacity < 0.0 {
 				return fmt.Sprintf("service tiers 'Basic', 'Standard', and 'Premium' per_database_settings 'min_capacity' must be equal to or greater than zero")
 			}
-		} else {
+		} else if s.SkuType == VCore {
 			// vCore Based Errors
 			if s.MaxSizeGb > s.MaxAllowedGB {
 				return fmt.Sprintf("service tier '%s' %s with a 'capacity' of %d vCores must have a 'max_size_gb' between 5 GB and %d GB, got %d GB", getTierFromName[strings.ToLower(s.Name)], s.Family, s.Capacity, int(s.MaxAllowedGB), int(s.MaxSizeGb))
@@ -447,8 +442,8 @@ func doSKUValidation(s sku) string {
 				return fmt.Sprintf("'max_size_gb' must be a whole number, got %f GB", s.MaxSizeGb)
 			}
 
-			if !nameContainsFamily(s.Name, s.Family) {
-				return fmt.Sprintf("Mismatch between SKU name '%s' and family '%s', expected '%s'", s.Name, s.Family, getFamilyFromName(s.Name))
+			if !nameContainsFamily(s) {
+				return fmt.Sprintf("Mismatch between SKU name '%s' and family '%s', expected '%s'", s.Name, s.Family, getFamilyFromName(s))
 			}
 
 			if s.MaxCapacity > float64(s.Capacity) {

From d3973734c81b4a444e900eaa3ad92ae5f33102c8 Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Fri, 1 Feb 2019 15:13:24 -0800
Subject: [PATCH 36/45] Removed unneeded validation check

---
 azurerm/helpers/azure/elasticpool.go | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/azurerm/helpers/azure/elasticpool.go b/azurerm/helpers/azure/elasticpool.go
index 3c24d5952d51..680e8ff2e98d 100644
--- a/azurerm/helpers/azure/elasticpool.go
+++ b/azurerm/helpers/azure/elasticpool.go
@@ -425,9 +425,6 @@ func doSKUValidation(s sku) string {
 				return fmt.Sprintf("service tiers 'Basic', 'Standard', and 'Premium' must have whole numbers as their 'maxCapacity'")
 			}
 
-			if s.MinCapacity < 0.0 {
-				return fmt.Sprintf("service tiers 'Basic', 'Standard', and 'Premium' per_database_settings 'min_capacity' must be equal to or greater than zero")
-			}
 		} else if s.SkuType == VCore {
 			// vCore Based Errors
 			if s.MaxSizeGb > s.MaxAllowedGB {

From 5994856308906f1302817a6a25ddcd5e8f96f4f6 Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Fri, 1 Feb 2019 15:44:11 -0800
Subject: [PATCH 37/45] Updated name and family validation

---
 azurerm/helpers/azure/elasticpool.go | 56 ++++++++++++++--------------
 1 file changed, 27 insertions(+), 29 deletions(-)

diff --git a/azurerm/helpers/azure/elasticpool.go b/azurerm/helpers/azure/elasticpool.go
index 680e8ff2e98d..b09bc830cfc2 100644
--- a/azurerm/helpers/azure/elasticpool.go
+++ b/azurerm/helpers/azure/elasticpool.go
@@ -221,6 +221,18 @@ func MSSQLElasticPoolValidateSKU(diff *schema.ResourceDiff) error {
 		s.SkuType = VCore
 	}
 
+	// Universal check for both DTU and vCore based SKUs
+	if !nameTierIsValid(s) {
+		return fmt.Errorf("Mismatch between SKU name '%s' and tier '%s', expected 'tier' to be '%s'", s.Name, s.Tier, getTierFromName[strings.ToLower(s.Name)])
+	}
+
+	// Verify that Family is valid
+	if s.SkuType == DTU && s.Family != "" {
+		return fmt.Sprintf("Invalid attribute 'family'(%s) for service tier '%s', remove the 'family' attribute from the configuration file", s.Family, s.Tier)
+	} else if s.SkuType == VCore && !nameContainsFamily(s) {
+		return fmt.Sprintf("Mismatch between SKU name '%s' and family '%s', expected '%s'", s.Name, s.Family, getFamilyFromName(s))
+	}
+	
 	// Convert Bytes to Gigabytes only if max_size_gb
 	// has not changed else use max_size_gb
 	if maxSizeBytes.(int) != 0 && !diff.HasChange("max_size_gb") {
@@ -229,7 +241,7 @@ func MSSQLElasticPoolValidateSKU(diff *schema.ResourceDiff) error {
 
 	if s.SkuType == DTU {
 		// DTU Checks
-		s.MaxAllowedGB = getDTUMaxGB[strings.ToLower(getTierFromName[strings.ToLower(s.Name)])][s.Capacity]
+		s.MaxAllowedGB = getDTUMaxGB[strings.ToLower(s.Tier)][s.Capacity]
 
 		// Check to see if this is a valid SKU capacity combo
 		if errMsg := doSKUValidation(s); errMsg != "" {
@@ -244,7 +256,7 @@ func MSSQLElasticPoolValidateSKU(diff *schema.ResourceDiff) error {
 
 	} else {
 		// vCore Checks
-		s.MaxAllowedGB = getvCoreMaxGB[strings.ToLower(getTierFromName[strings.ToLower(s.Name)])][strings.ToLower(getFamilyFromName(s))][s.Capacity]
+		s.MaxAllowedGB = getvCoreMaxGB[strings.ToLower(s.Tier][strings.ToLower(s.Family)][s.Capacity]
 
 		if errMsg := doSKUValidation(s); errMsg != "" {
 			return fmt.Errorf(errMsg)
@@ -257,11 +269,6 @@ func MSSQLElasticPoolValidateSKU(diff *schema.ResourceDiff) error {
 		}
 	}
 
-	// Universal check for all SKUs
-	if !nameTierIsValid(s) {
-		return fmt.Errorf("Mismatch between SKU name '%s' and tier '%s', expected 'tier' to be '%s'", s.Name, s.Tier, getTierFromName[strings.ToLower(s.Name)])
-	}
-
 	return nil
 }
 
@@ -297,25 +304,23 @@ func getFamilyFromName(s sku) string {
 }
 
 func getDTUCapacityErrorMsg(s sku) string {
-	m := getDTUMaxGB[strings.ToLower(getTierFromName[strings.ToLower(s.Name)])]
+	m := getDTUMaxGB[strings.ToLower(s.Tier)]
 	return buildcapacityErrorString(s, m)
 }
 
 func getVCoreCapacityErrorMsg(s sku) string {
-	m := getvCoreMaxGB[strings.ToLower(getTierFromName[strings.ToLower(s.Name)])][strings.ToLower(getFamilyFromName(s))]
+	m := getvCoreMaxGB[strings.ToLower(s.Tier][strings.ToLower(s.Family)]
 	return buildcapacityErrorString(s, m)
 }
 
 func buildcapacityErrorString(s sku, m map[int]float64) string {
 	var a []int
 	str := ""
-	family := getFamilyFromName(s)
-	tier := getTierFromName[strings.ToLower(s.Name)]
 
 	if s.SkuType == DTU {
-		str += fmt.Sprintf("service tier '%s' must have a 'capacity'(%d) of ", tier, s.Capacity)
+		str += fmt.Sprintf("service tier '%s' must have a 'capacity'(%d) of ", s.Tier, s.Capacity)
 	} else {
-		str += fmt.Sprintf("service tier '%s' %s must have a 'capacity'(%d) of ", tier, family, s.Capacity)
+		str += fmt.Sprintf("service tier '%s' %s must have a 'capacity'(%d) of ", s.Tier, s.Family, s.Capacity)
 	}
 
 	// copy the keys into another map
@@ -351,7 +356,7 @@ func buildcapacityErrorString(s sku, m map[int]float64) string {
 func getDTUNotValidSizeErrorMsg(s sku) string {
 	m := supportedDTUMaxGBValues
 	var a []int
-	str := fmt.Sprintf("'max_size_gb'(%d) is not a valid value for service tier '%s', 'max_size_gb' must have a value of ", int(s.MaxSizeGb), getTierFromName[strings.ToLower(s.Name)])
+	str := fmt.Sprintf("'max_size_gb'(%d) is not a valid value for service tier '%s', 'max_size_gb' must have a value of ", int(s.MaxSizeGb), s.Tier)
 
 	// copy the keys into another map
 	p := make([]int, 0, len(m))
@@ -400,11 +405,11 @@ func doSKUValidation(s sku) string {
 			} else {
 				// All other DTU based SKUs
 				if s.MaxSizeGb > s.MaxAllowedGB {
-					return fmt.Sprintf("service tier '%s' with a 'capacity' of %d must have a 'max_size_gb' no greater than %d GB, got %d GB", getTierFromName[strings.ToLower(s.Name)], s.Capacity, int(s.MaxAllowedGB), int(s.MaxSizeGb))
+					return fmt.Sprintf("service tier '%s' with a 'capacity' of %d must have a 'max_size_gb' no greater than %d GB, got %d GB", s.Tier, s.Capacity, int(s.MaxAllowedGB), int(s.MaxSizeGb))
 				}
 
 				if int(s.MaxSizeGb) < 50 {
-					return fmt.Sprintf("service tier '%s', must have a 'max_size_gb' value equal to or greater than 50 GB, got %d GB", getTierFromName[strings.ToLower(s.Name)], int(s.MaxSizeGb))
+					return fmt.Sprintf("service tier '%s', must have a 'max_size_gb' value equal to or greater than 50 GB, got %d GB", s.Tier, int(s.MaxSizeGb))
 				}
 
 				// Check to see if the max_size_gb value is valid for this SKU type and capacity
@@ -414,41 +419,34 @@ func doSKUValidation(s sku) string {
 			}
 
 			// All Other DTU based SKU Checks
-			if s.Family != "" {
-				return fmt.Sprintf("Invalid attribute 'family' (%s) for service tiers 'Basic', 'Standard', and 'Premium', remove the 'family' attribute from the configuration file", s.Family)
-			}
 			if s.MinCapacity != math.Trunc(s.MinCapacity) {
-				return fmt.Sprintf("service tiers 'Basic', 'Standard', and 'Premium' must have whole numbers as their 'minCapacity'")
+				return fmt.Sprintf("service tier '%s' must have whole numbers as their 'minCapacity'", s.Tier)
 			}
 
 			if s.MaxCapacity != math.Trunc(s.MaxCapacity) {
-				return fmt.Sprintf("service tiers 'Basic', 'Standard', and 'Premium' must have whole numbers as their 'maxCapacity'")
+				return fmt.Sprintf("service tier '%s' must have whole numbers as their 'maxCapacity'", s.Tier)
 			}
 
 		} else if s.SkuType == VCore {
 			// vCore Based Errors
 			if s.MaxSizeGb > s.MaxAllowedGB {
-				return fmt.Sprintf("service tier '%s' %s with a 'capacity' of %d vCores must have a 'max_size_gb' between 5 GB and %d GB, got %d GB", getTierFromName[strings.ToLower(s.Name)], s.Family, s.Capacity, int(s.MaxAllowedGB), int(s.MaxSizeGb))
+				return fmt.Sprintf("service tier '%s' %s with a 'capacity' of %d vCores must have a 'max_size_gb' between 5 GB and %d GB, got %d GB", s.Tier, s.Family, s.Capacity, int(s.MaxAllowedGB), int(s.MaxSizeGb))
 			}
 
 			if int(s.MaxSizeGb) < 5 {
-				return fmt.Sprintf("service tier '%s' must have a 'max_size_gb' value equal to or greater than 5 GB, got %d GB", getTierFromName[strings.ToLower(s.Name)], int(s.MaxSizeGb))
+				return fmt.Sprintf("service tier '%s' must have a 'max_size_gb' value equal to or greater than 5 GB, got %d GB", s.Tier, int(s.MaxSizeGb))
 			}
 
 			if s.MaxSizeGb != math.Trunc(s.MaxSizeGb) {
 				return fmt.Sprintf("'max_size_gb' must be a whole number, got %f GB", s.MaxSizeGb)
 			}
 
-			if !nameContainsFamily(s) {
-				return fmt.Sprintf("Mismatch between SKU name '%s' and family '%s', expected '%s'", s.Name, s.Family, getFamilyFromName(s))
-			}
-
 			if s.MaxCapacity > float64(s.Capacity) {
-				return fmt.Sprintf("service tier '%s' perDatabaseSettings 'maxCapacity' must not be higher than the SKUs 'capacity'(%d) value", getTierFromName[strings.ToLower(s.Name)], s.Capacity)
+				return fmt.Sprintf("service tier '%s' perDatabaseSettings 'maxCapacity'(%d) must not be higher than the SKUs 'capacity'(%d) value", s.Tier, int(s.MaxCapacity), s.Capacity)
 			}
 
 			if s.MinCapacity > s.MaxCapacity {
-				return fmt.Sprintf("perDatabaseSettings 'maxCapacity' must be greater than or equal to the perDatabaseSettings 'minCapacity' value")
+				return fmt.Sprintf("perDatabaseSettings 'maxCapacity'(%d) must be greater than or equal to the perDatabaseSettings 'minCapacity'(%d) value", int(s.MaxCapacity), int(s.MinCapacity))
 			}
 		}
 	}

From be8580b90e118d488308643f7946cdea09d7de07 Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Fri, 1 Feb 2019 15:47:31 -0800
Subject: [PATCH 38/45] Fixed issue due to code editor auto-complete

---
 azurerm/helpers/azure/elasticpool.go | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/azurerm/helpers/azure/elasticpool.go b/azurerm/helpers/azure/elasticpool.go
index b09bc830cfc2..6e268b53bf7a 100644
--- a/azurerm/helpers/azure/elasticpool.go
+++ b/azurerm/helpers/azure/elasticpool.go
@@ -232,7 +232,7 @@ func MSSQLElasticPoolValidateSKU(diff *schema.ResourceDiff) error {
 	} else if s.SkuType == VCore && !nameContainsFamily(s) {
 		return fmt.Sprintf("Mismatch between SKU name '%s' and family '%s', expected '%s'", s.Name, s.Family, getFamilyFromName(s))
 	}
-	
+
 	// Convert Bytes to Gigabytes only if max_size_gb
 	// has not changed else use max_size_gb
 	if maxSizeBytes.(int) != 0 && !diff.HasChange("max_size_gb") {
@@ -256,7 +256,7 @@ func MSSQLElasticPoolValidateSKU(diff *schema.ResourceDiff) error {
 
 	} else {
 		// vCore Checks
-		s.MaxAllowedGB = getvCoreMaxGB[strings.ToLower(s.Tier][strings.ToLower(s.Family)][s.Capacity]
+		s.MaxAllowedGB = getvCoreMaxGB[strings.ToLower(s.Tier)][strings.ToLower(s.Family)][s.Capacity]
 
 		if errMsg := doSKUValidation(s); errMsg != "" {
 			return fmt.Errorf(errMsg)
@@ -309,7 +309,7 @@ func getDTUCapacityErrorMsg(s sku) string {
 }
 
 func getVCoreCapacityErrorMsg(s sku) string {
-	m := getvCoreMaxGB[strings.ToLower(s.Tier][strings.ToLower(s.Family)]
+	m := getvCoreMaxGB[strings.ToLower(s.Tier)][strings.ToLower(s.Family)]
 	return buildcapacityErrorString(s, m)
 }
 

From 2e3809b13379e8b5b67b93d5c09f8bdc8e272d5b Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Fri, 1 Feb 2019 15:49:14 -0800
Subject: [PATCH 39/45] Changed to Errorf

---
 azurerm/helpers/azure/elasticpool.go | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/azurerm/helpers/azure/elasticpool.go b/azurerm/helpers/azure/elasticpool.go
index 6e268b53bf7a..29b73e1f8bf7 100644
--- a/azurerm/helpers/azure/elasticpool.go
+++ b/azurerm/helpers/azure/elasticpool.go
@@ -228,9 +228,9 @@ func MSSQLElasticPoolValidateSKU(diff *schema.ResourceDiff) error {
 
 	// Verify that Family is valid
 	if s.SkuType == DTU && s.Family != "" {
-		return fmt.Sprintf("Invalid attribute 'family'(%s) for service tier '%s', remove the 'family' attribute from the configuration file", s.Family, s.Tier)
+		return fmt.Errorf("Invalid attribute 'family'(%s) for service tier '%s', remove the 'family' attribute from the configuration file", s.Family, s.Tier)
 	} else if s.SkuType == VCore && !nameContainsFamily(s) {
-		return fmt.Sprintf("Mismatch between SKU name '%s' and family '%s', expected '%s'", s.Name, s.Family, getFamilyFromName(s))
+		return fmt.Errorf("Mismatch between SKU name '%s' and family '%s', expected '%s'", s.Name, s.Family, getFamilyFromName(s))
 	}
 
 	// Convert Bytes to Gigabytes only if max_size_gb

From 6933c4b5520101ec923c26e39adfb5767b082cbb Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Fri, 1 Feb 2019 16:08:41 -0800
Subject: [PATCH 40/45] Update for edge case

---
 azurerm/helpers/azure/elasticpool.go | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/azurerm/helpers/azure/elasticpool.go b/azurerm/helpers/azure/elasticpool.go
index 29b73e1f8bf7..e7d40ff48aa6 100644
--- a/azurerm/helpers/azure/elasticpool.go
+++ b/azurerm/helpers/azure/elasticpool.go
@@ -273,6 +273,10 @@ func MSSQLElasticPoolValidateSKU(diff *schema.ResourceDiff) error {
 }
 
 func nameContainsFamily(s sku) bool {
+	if s.Family == "" {
+		return false
+	}
+
 	return strings.Contains(strings.ToLower(s.Name), strings.ToLower(s.Family))
 }
 

From 0bd9ea7009a013d9b29952a67c58f7a8a69943eb Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Fri, 1 Feb 2019 17:55:25 -0800
Subject: [PATCH 41/45] Updated map to get better code reuse

---
 azurerm/helpers/azure/elasticpool.go | 133 ++++++++++-----------------
 1 file changed, 49 insertions(+), 84 deletions(-)

diff --git a/azurerm/helpers/azure/elasticpool.go b/azurerm/helpers/azure/elasticpool.go
index e7d40ff48aa6..9b24d5ab69f0 100644
--- a/azurerm/helpers/azure/elasticpool.go
+++ b/azurerm/helpers/azure/elasticpool.go
@@ -78,35 +78,35 @@ var getDTUMaxGB = map[string]map[int]float64{
 //                          other than the values in the map the API with throw
 //                          an 'Internal Server Error'
 
-var supportedDTUMaxGBValues = map[float64]bool{
-	50:   true,
-	100:  true,
-	150:  true,
-	200:  true,
-	250:  true,
-	300:  true,
-	400:  true,
-	500:  true,
-	750:  true,
-	800:  true,
-	1024: true,
-	1200: true,
-	1280: true,
-	1536: true,
-	1600: true,
-	1792: true,
-	2000: true,
-	2048: true,
-	2304: true,
-	2500: true,
-	2560: true,
-	2816: true,
-	3000: true,
-	3072: true,
-	3328: true,
-	3584: true,
-	3840: true,
-	4096: true,
+var supportedDTUMaxGBValues = map[int]float64{
+	50:   1,
+	100:  1,
+	150:  1,
+	200:  1,
+	250:  1,
+	300:  1,
+	400:  1,
+	500:  1,
+	750:  1,
+	800:  1,
+	1024: 1,
+	1200: 1,
+	1280: 1,
+	1536: 1,
+	1600: 1,
+	1792: 1,
+	2000: 1,
+	2048: 1,
+	2304: 1,
+	2500: 1,
+	2560: 1,
+	2816: 1,
+	3000: 1,
+	3072: 1,
+	3328: 1,
+	3584: 1,
+	3840: 1,
+	4096: 1,
 }
 
 // getvCoreMaxGB: this map holds all of the vCore to 'max_size_gb' mappings based on a vCore lookup
@@ -216,6 +216,12 @@ func MSSQLElasticPoolValidateSKU(diff *schema.ResourceDiff) error {
 		SkuType:     DTU,
 	}
 
+	// Convert Bytes to Gigabytes only if
+	// 'max_size_bytes' has changed
+	if diff.HasChange("max_size_bytes") {
+		s.MaxSizeGb = float64(maxSizeBytes.(int) / 1024 / 1024 / 1024)
+	}
+
 	// Check to see if the name describes a vCore type SKU
 	if strings.HasPrefix(strings.ToLower(s.Name), "gp_") || strings.HasPrefix(strings.ToLower(s.Name), "bc_") {
 		s.SkuType = VCore
@@ -233,12 +239,6 @@ func MSSQLElasticPoolValidateSKU(diff *schema.ResourceDiff) error {
 		return fmt.Errorf("Mismatch between SKU name '%s' and family '%s', expected '%s'", s.Name, s.Family, getFamilyFromName(s))
 	}
 
-	// Convert Bytes to Gigabytes only if max_size_gb
-	// has not changed else use max_size_gb
-	if maxSizeBytes.(int) != 0 && !diff.HasChange("max_size_gb") {
-		s.MaxSizeGb = float64(maxSizeBytes.(int) / 1024 / 1024 / 1024)
-	}
-
 	if s.SkuType == DTU {
 		// DTU Checks
 		s.MaxAllowedGB = getDTUMaxGB[strings.ToLower(s.Tier)][s.Capacity]
@@ -309,63 +309,29 @@ func getFamilyFromName(s sku) string {
 
 func getDTUCapacityErrorMsg(s sku) string {
 	m := getDTUMaxGB[strings.ToLower(s.Tier)]
-	return buildcapacityErrorString(s, m)
+	stub := fmt.Sprintf("service tier '%s' must have a 'capacity'(%d) of ", s.Tier, s.Capacity)
+	return buildErrorString(s, stub, m) + "DTUs"
 }
 
 func getVCoreCapacityErrorMsg(s sku) string {
 	m := getvCoreMaxGB[strings.ToLower(s.Tier)][strings.ToLower(s.Family)]
-	return buildcapacityErrorString(s, m)
-}
-
-func buildcapacityErrorString(s sku, m map[int]float64) string {
-	var a []int
-	str := ""
-
-	if s.SkuType == DTU {
-		str += fmt.Sprintf("service tier '%s' must have a 'capacity'(%d) of ", s.Tier, s.Capacity)
-	} else {
-		str += fmt.Sprintf("service tier '%s' %s must have a 'capacity'(%d) of ", s.Tier, s.Family, s.Capacity)
-	}
-
-	// copy the keys into another map
-	p := make([]int, 0, len(m))
-	for k := range m {
-		p = append(p, k)
-	}
-
-	// copy the values of the map of keys into a slice of ints
-	for v := range p {
-		a = append(a, p[v])
-	}
-
-	// sort the slice to get them in order
-	sort.Ints(a)
-
-	// build the error message
-	for i := range a {
-		if i < len(a)-1 {
-			str += fmt.Sprintf("%d, ", a[i])
-		} else {
-			if s.SkuType == DTU {
-				str += fmt.Sprintf("or %d DTUs", a[i])
-			} else {
-				str += fmt.Sprintf("or %d vCores", a[i])
-			}
-		}
-	}
-
-	return str
+	stub := fmt.Sprintf("service tier '%s' %s must have a 'capacity'(%d) of ", s.Tier, s.Family, s.Capacity)
+	return buildErrorString(s, stub, m) + " vCores"
 }
 
 func getDTUNotValidSizeErrorMsg(s sku) string {
 	m := supportedDTUMaxGBValues
+	stub := fmt.Sprintf("'max_size_gb'(%d) is not a valid value for service tier '%s', 'max_size_gb' must have a value of ", int(s.MaxSizeGb), s.Tier)
+	return buildErrorString(s, stub, m) + " GB"
+}
+
+func buildErrorString(s sku, stub string, m map[int]float64) string {
 	var a []int
-	str := fmt.Sprintf("'max_size_gb'(%d) is not a valid value for service tier '%s', 'max_size_gb' must have a value of ", int(s.MaxSizeGb), s.Tier)
 
 	// copy the keys into another map
 	p := make([]int, 0, len(m))
 	for k := range m {
-		p = append(p, int(k))
+		p = append(p, k)
 	}
 
 	// copy the values of the map of keys into a slice of ints
@@ -378,15 +344,14 @@ func getDTUNotValidSizeErrorMsg(s sku) string {
 
 	// build the error message
 	for i := range a {
-
 		if i < len(a)-1 {
-			str += fmt.Sprintf("%d, ", a[i])
+			stub += fmt.Sprintf("%d, ", a[i])
 		} else {
-			str += fmt.Sprintf("or %d GB", a[i])
+			stub += fmt.Sprintf("or %d", a[i])
 		}
 	}
 
-	return str
+	return stub
 }
 
 func doSKUValidation(s sku) string {
@@ -417,7 +382,7 @@ func doSKUValidation(s sku) string {
 				}
 
 				// Check to see if the max_size_gb value is valid for this SKU type and capacity
-				if !supportedDTUMaxGBValues[s.MaxSizeGb] {
+				if supportedDTUMaxGBValues[int(s.MaxSizeGb)] != 1 {
 					return getDTUNotValidSizeErrorMsg(s)
 				}
 			}

From 321139fb915690018afc61e69cf2050eb7226c4e Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Fri, 1 Feb 2019 17:56:26 -0800
Subject: [PATCH 42/45] Missed a space

---
 azurerm/helpers/azure/elasticpool.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/azurerm/helpers/azure/elasticpool.go b/azurerm/helpers/azure/elasticpool.go
index 9b24d5ab69f0..3f778cb1f866 100644
--- a/azurerm/helpers/azure/elasticpool.go
+++ b/azurerm/helpers/azure/elasticpool.go
@@ -310,7 +310,7 @@ func getFamilyFromName(s sku) string {
 func getDTUCapacityErrorMsg(s sku) string {
 	m := getDTUMaxGB[strings.ToLower(s.Tier)]
 	stub := fmt.Sprintf("service tier '%s' must have a 'capacity'(%d) of ", s.Tier, s.Capacity)
-	return buildErrorString(s, stub, m) + "DTUs"
+	return buildErrorString(s, stub, m) + " DTUs"
 }
 
 func getVCoreCapacityErrorMsg(s sku) string {

From 56ecf290571c7c3e537d50d82bbe599546412134 Mon Sep 17 00:00:00 2001
From: Jeffrey Cline <jcline@microsoft.com>
Date: Fri, 1 Feb 2019 18:03:16 -0800
Subject: [PATCH 43/45] Fix lint error

---
 azurerm/helpers/azure/elasticpool.go | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/azurerm/helpers/azure/elasticpool.go b/azurerm/helpers/azure/elasticpool.go
index 3f778cb1f866..e18b1c6186e0 100644
--- a/azurerm/helpers/azure/elasticpool.go
+++ b/azurerm/helpers/azure/elasticpool.go
@@ -310,22 +310,22 @@ func getFamilyFromName(s sku) string {
 func getDTUCapacityErrorMsg(s sku) string {
 	m := getDTUMaxGB[strings.ToLower(s.Tier)]
 	stub := fmt.Sprintf("service tier '%s' must have a 'capacity'(%d) of ", s.Tier, s.Capacity)
-	return buildErrorString(s, stub, m) + " DTUs"
+	return buildErrorString(stub, m) + " DTUs"
 }
 
 func getVCoreCapacityErrorMsg(s sku) string {
 	m := getvCoreMaxGB[strings.ToLower(s.Tier)][strings.ToLower(s.Family)]
 	stub := fmt.Sprintf("service tier '%s' %s must have a 'capacity'(%d) of ", s.Tier, s.Family, s.Capacity)
-	return buildErrorString(s, stub, m) + " vCores"
+	return buildErrorString(stub, m) + " vCores"
 }
 
 func getDTUNotValidSizeErrorMsg(s sku) string {
 	m := supportedDTUMaxGBValues
 	stub := fmt.Sprintf("'max_size_gb'(%d) is not a valid value for service tier '%s', 'max_size_gb' must have a value of ", int(s.MaxSizeGb), s.Tier)
-	return buildErrorString(s, stub, m) + " GB"
+	return buildErrorString(stub, m) + " GB"
 }
 
-func buildErrorString(s sku, stub string, m map[int]float64) string {
+func buildErrorString(stub string, m map[int]float64) string {
 	var a []int
 
 	// copy the keys into another map

From 857797efc10fcd730815e84c1bffd6e7d3724867 Mon Sep 17 00:00:00 2001
From: kt <kt@katbyte.me>
Date: Mon, 4 Feb 2019 21:43:03 -0800
Subject: [PATCH 44/45] broke doSKUValidation into two seperate functions

---
 azurerm/helpers/azure/elasticpool.go | 174 +++++++++++----------------
 1 file changed, 72 insertions(+), 102 deletions(-)

diff --git a/azurerm/helpers/azure/elasticpool.go b/azurerm/helpers/azure/elasticpool.go
index e18b1c6186e0..bfda8ba8e567 100644
--- a/azurerm/helpers/azure/elasticpool.go
+++ b/azurerm/helpers/azure/elasticpool.go
@@ -9,14 +9,8 @@ import (
 	"github.com/hashicorp/terraform/helper/schema"
 )
 
-type errorType int
 type skuType int
 
-const (
-	capacityError errorType = 0
-	allOtherError errorType = 1
-)
-
 const (
 	DTU   skuType = 0
 	VCore skuType = 1
@@ -26,7 +20,6 @@ type sku struct {
 	Name, Tier, Family                                string
 	Capacity                                          int
 	MaxAllowedGB, MaxSizeGb, MinCapacity, MaxCapacity float64
-	ErrorType                                         errorType
 	SkuType                                           skuType
 }
 
@@ -195,14 +188,14 @@ var getTierFromName = map[string]string{
 
 func MSSQLElasticPoolValidateSKU(diff *schema.ResourceDiff) error {
 
-	name, _ := diff.GetOk("sku.0.name")
-	tier, _ := diff.GetOk("sku.0.tier")
-	capacity, _ := diff.GetOk("sku.0.capacity")
-	family, _ := diff.GetOk("sku.0.family")
-	maxSizeBytes, _ := diff.GetOk("max_size_bytes")
-	maxSizeGb, _ := diff.GetOk("max_size_gb")
-	minCapacity, _ := diff.GetOk("per_database_settings.0.min_capacity")
-	maxCapacity, _ := diff.GetOk("per_database_settings.0.max_capacity")
+	name := diff.Get("sku.0.name")
+	tier := diff.Get("sku.0.tier")
+	capacity := diff.Get("sku.0.capacity")
+	family := diff.Get("sku.0.family")
+	maxSizeBytes := diff.Get("max_size_bytes")
+	maxSizeGb := diff.Get("max_size_gb")
+	minCapacity := diff.Get("per_database_settings.0.min_capacity")
+	maxCapacity := diff.Get("per_database_settings.0.max_capacity")
 
 	s := sku{
 		Name:        name.(string),
@@ -212,7 +205,6 @@ func MSSQLElasticPoolValidateSKU(diff *schema.ResourceDiff) error {
 		MaxSizeGb:   maxSizeGb.(float64),
 		MinCapacity: minCapacity.(float64),
 		MaxCapacity: maxCapacity.(float64),
-		ErrorType:   capacityError,
 		SkuType:     DTU,
 	}
 
@@ -239,34 +231,13 @@ func MSSQLElasticPoolValidateSKU(diff *schema.ResourceDiff) error {
 		return fmt.Errorf("Mismatch between SKU name '%s' and family '%s', expected '%s'", s.Name, s.Family, getFamilyFromName(s))
 	}
 
+	//get max GB and do validation based on SKU type
 	if s.SkuType == DTU {
-		// DTU Checks
 		s.MaxAllowedGB = getDTUMaxGB[strings.ToLower(s.Tier)][s.Capacity]
-
-		// Check to see if this is a valid SKU capacity combo
-		if errMsg := doSKUValidation(s); errMsg != "" {
-			return fmt.Errorf(errMsg)
-		}
-
-		// Check to see if this is a valid Max_Size_GB value
-		s.ErrorType = allOtherError
-		if errMsg := doSKUValidation(s); errMsg != "" {
-			return fmt.Errorf(errMsg)
-		}
-
+		return doDTUSKUValidation(s)
 	} else {
-		// vCore Checks
 		s.MaxAllowedGB = getvCoreMaxGB[strings.ToLower(s.Tier)][strings.ToLower(s.Family)][s.Capacity]
-
-		if errMsg := doSKUValidation(s); errMsg != "" {
-			return fmt.Errorf(errMsg)
-		}
-
-		// Check to see if this is a valid Max_Size_GB value
-		s.ErrorType = allOtherError
-		if errMsg := doSKUValidation(s); errMsg != "" {
-			return fmt.Errorf(errMsg)
-		}
+		return doVCoreSKUValidation(s)
 	}
 
 	return nil
@@ -354,71 +325,70 @@ func buildErrorString(stub string, m map[int]float64) string {
 	return stub
 }
 
-func doSKUValidation(s sku) string {
-	errMsg := ""
+func doDTUSKUValidation(s sku) error {
+
+	if s.MaxAllowedGB == 0 {
+		return fmt.Errorf(getDTUCapacityErrorMsg(s))
+	}
+
+	if strings.EqualFold(s.Name, "BasicPool") {
+		// Basic SKU does not let you pick your max_size_GB they are fixed values
+		if s.MaxSizeGb != s.MaxAllowedGB {
+			return fmt.Errorf("service tier 'Basic' with a 'capacity' of %d must have a 'max_size_gb' of %.7f GB, got %.7f GB", s.Capacity, s.MaxAllowedGB, s.MaxSizeGb)
+		}
+	} else {
+		// All other DTU based SKUs
+		if s.MaxSizeGb > s.MaxAllowedGB {
+			return fmt.Errorf("service tier '%s' with a 'capacity' of %d must have a 'max_size_gb' no greater than %d GB, got %d GB", s.Tier, s.Capacity, int(s.MaxAllowedGB), int(s.MaxSizeGb))
+		}
 
-	if s.ErrorType == capacityError {
-		if s.SkuType == DTU && s.MaxAllowedGB == 0 {
-			return getDTUCapacityErrorMsg(s)
-		} else if s.SkuType == VCore && s.MaxAllowedGB == 0 {
-			return getVCoreCapacityErrorMsg(s)
+		if int(s.MaxSizeGb) < 50 {
+			return fmt.Errorf("service tier '%s', must have a 'max_size_gb' value equal to or greater than 50 GB, got %d GB", s.Tier, int(s.MaxSizeGb))
 		}
-	} else if s.ErrorType == allOtherError {
-		// AllOther Errors
-		if s.SkuType == DTU {
-			if strings.EqualFold(s.Name, "BasicPool") {
-				// Basic SKU does not let you pick your max_size_GB they are fixed values
-				if s.MaxSizeGb != s.MaxAllowedGB {
-					return fmt.Sprintf("service tier 'Basic' with a 'capacity' of %d must have a 'max_size_gb' of %.7f GB, got %.7f GB", s.Capacity, s.MaxAllowedGB, s.MaxSizeGb)
-				}
-			} else {
-				// All other DTU based SKUs
-				if s.MaxSizeGb > s.MaxAllowedGB {
-					return fmt.Sprintf("service tier '%s' with a 'capacity' of %d must have a 'max_size_gb' no greater than %d GB, got %d GB", s.Tier, s.Capacity, int(s.MaxAllowedGB), int(s.MaxSizeGb))
-				}
-
-				if int(s.MaxSizeGb) < 50 {
-					return fmt.Sprintf("service tier '%s', must have a 'max_size_gb' value equal to or greater than 50 GB, got %d GB", s.Tier, int(s.MaxSizeGb))
-				}
-
-				// Check to see if the max_size_gb value is valid for this SKU type and capacity
-				if supportedDTUMaxGBValues[int(s.MaxSizeGb)] != 1 {
-					return getDTUNotValidSizeErrorMsg(s)
-				}
-			}
-
-			// All Other DTU based SKU Checks
-			if s.MinCapacity != math.Trunc(s.MinCapacity) {
-				return fmt.Sprintf("service tier '%s' must have whole numbers as their 'minCapacity'", s.Tier)
-			}
-
-			if s.MaxCapacity != math.Trunc(s.MaxCapacity) {
-				return fmt.Sprintf("service tier '%s' must have whole numbers as their 'maxCapacity'", s.Tier)
-			}
-
-		} else if s.SkuType == VCore {
-			// vCore Based Errors
-			if s.MaxSizeGb > s.MaxAllowedGB {
-				return fmt.Sprintf("service tier '%s' %s with a 'capacity' of %d vCores must have a 'max_size_gb' between 5 GB and %d GB, got %d GB", s.Tier, s.Family, s.Capacity, int(s.MaxAllowedGB), int(s.MaxSizeGb))
-			}
-
-			if int(s.MaxSizeGb) < 5 {
-				return fmt.Sprintf("service tier '%s' must have a 'max_size_gb' value equal to or greater than 5 GB, got %d GB", s.Tier, int(s.MaxSizeGb))
-			}
-
-			if s.MaxSizeGb != math.Trunc(s.MaxSizeGb) {
-				return fmt.Sprintf("'max_size_gb' must be a whole number, got %f GB", s.MaxSizeGb)
-			}
-
-			if s.MaxCapacity > float64(s.Capacity) {
-				return fmt.Sprintf("service tier '%s' perDatabaseSettings 'maxCapacity'(%d) must not be higher than the SKUs 'capacity'(%d) value", s.Tier, int(s.MaxCapacity), s.Capacity)
-			}
-
-			if s.MinCapacity > s.MaxCapacity {
-				return fmt.Sprintf("perDatabaseSettings 'maxCapacity'(%d) must be greater than or equal to the perDatabaseSettings 'minCapacity'(%d) value", int(s.MaxCapacity), int(s.MinCapacity))
-			}
+
+		// Check to see if the max_size_gb value is valid for this SKU type and capacity
+		if supportedDTUMaxGBValues[int(s.MaxSizeGb)] != 1 {
+			return fmt.Errorf(getDTUNotValidSizeErrorMsg(s))
 		}
 	}
 
-	return errMsg
+	// All Other DTU based SKU Checks
+	if s.MinCapacity != math.Trunc(s.MinCapacity) {
+		return fmt.Errorf("service tier '%s' must have whole numbers as their 'minCapacity'", s.Tier)
+	}
+
+	if s.MaxCapacity != math.Trunc(s.MaxCapacity) {
+		return fmt.Errorf("service tier '%s' must have whole numbers as their 'maxCapacity'", s.Tier)
+	}
+
+	return nil
+}
+
+func doVCoreSKUValidation(s sku) error {
+
+	if s.MaxAllowedGB == 0 {
+		return fmt.Errorf(getVCoreCapacityErrorMsg(s))
+	}
+
+	if s.MaxSizeGb > s.MaxAllowedGB {
+		return fmt.Errorf("service tier '%s' %s with a 'capacity' of %d vCores must have a 'max_size_gb' between 5 GB and %d GB, got %d GB", s.Tier, s.Family, s.Capacity, int(s.MaxAllowedGB), int(s.MaxSizeGb))
+	}
+
+	if int(s.MaxSizeGb) < 5 {
+		return fmt.Errorf("service tier '%s' must have a 'max_size_gb' value equal to or greater than 5 GB, got %d GB", s.Tier, int(s.MaxSizeGb))
+	}
+
+	if s.MaxSizeGb != math.Trunc(s.MaxSizeGb) {
+		return fmt.Errorf("'max_size_gb' must be a whole number, got %f GB", s.MaxSizeGb)
+	}
+
+	if s.MaxCapacity > float64(s.Capacity) {
+		return fmt.Errorf("service tier '%s' perDatabaseSettings 'maxCapacity'(%d) must not be higher than the SKUs 'capacity'(%d) value", s.Tier, int(s.MaxCapacity), s.Capacity)
+	}
+
+	if s.MinCapacity > s.MaxCapacity {
+		return fmt.Errorf("perDatabaseSettings 'maxCapacity'(%d) must be greater than or equal to the perDatabaseSettings 'minCapacity'(%d) value", int(s.MaxCapacity), int(s.MinCapacity))
+	}
+
+	return nil
 }

From 9d69371e17225e6839bd42b1a352ddf910b282a3 Mon Sep 17 00:00:00 2001
From: kt <kt@katbyte.me>
Date: Mon, 4 Feb 2019 21:52:46 -0800
Subject: [PATCH 45/45] fix linting

---
 azurerm/helpers/azure/elasticpool.go | 2 --
 1 file changed, 2 deletions(-)

diff --git a/azurerm/helpers/azure/elasticpool.go b/azurerm/helpers/azure/elasticpool.go
index bfda8ba8e567..9d9b150a843a 100644
--- a/azurerm/helpers/azure/elasticpool.go
+++ b/azurerm/helpers/azure/elasticpool.go
@@ -239,8 +239,6 @@ func MSSQLElasticPoolValidateSKU(diff *schema.ResourceDiff) error {
 		s.MaxAllowedGB = getvCoreMaxGB[strings.ToLower(s.Tier)][strings.ToLower(s.Family)][s.Capacity]
 		return doVCoreSKUValidation(s)
 	}
-
-	return nil
 }
 
 func nameContainsFamily(s sku) bool {