-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
azurerm_service_plan
- Support premium_site_elastic_scaling_enabled
feature.
#24770
Changes from 18 commits
871e63e
c98a402
bde0382
1d0bf19
c379c6a
63ad9a6
e2088ff
89d7799
06e8912
fb44c48
b54de55
8227760
d0ea574
10c44bb
09df1c2
b7538fa
bac4370
dac397d
c4d6fa1
45eb6d2
316c6c4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -49,6 +49,7 @@ type ServicePlanModel struct { | |||||
Sku string `tfschema:"sku_name"` | ||||||
AppServiceEnvironmentId string `tfschema:"app_service_environment_id"` | ||||||
PerSiteScaling bool `tfschema:"per_site_scaling_enabled"` | ||||||
ElasticScaling bool `tfschema:"elastic_scale_enabled"` | ||||||
Reserved bool `tfschema:"reserved"` | ||||||
WorkerCount int `tfschema:"worker_count"` | ||||||
MaximumElasticWorkerCount int `tfschema:"maximum_elastic_worker_count"` | ||||||
|
@@ -100,6 +101,12 @@ func (r ServicePlanResource) Arguments() map[string]*pluginsdk.Schema { | |||||
Default: false, | ||||||
}, | ||||||
|
||||||
"elastic_scale_enabled": { | ||||||
Type: pluginsdk.TypeBool, | ||||||
Optional: true, | ||||||
Default: false, | ||||||
}, | ||||||
|
||||||
"worker_count": { | ||||||
Type: pluginsdk.TypeInt, | ||||||
Optional: true, | ||||||
|
@@ -170,10 +177,11 @@ func (r ServicePlanResource) Create() sdk.ResourceFunc { | |||||
|
||||||
appServicePlan := appserviceplans.AppServicePlan{ | ||||||
Properties: &appserviceplans.AppServicePlanProperties{ | ||||||
PerSiteScaling: pointer.To(servicePlan.PerSiteScaling), | ||||||
Reserved: pointer.To(servicePlan.OSType == OSTypeLinux), | ||||||
HyperV: pointer.To(servicePlan.OSType == OSTypeWindowsContainer), | ||||||
ZoneRedundant: pointer.To(servicePlan.ZoneBalancing), | ||||||
PerSiteScaling: pointer.To(servicePlan.PerSiteScaling), | ||||||
Reserved: pointer.To(servicePlan.OSType == OSTypeLinux), | ||||||
HyperV: pointer.To(servicePlan.OSType == OSTypeWindowsContainer), | ||||||
ZoneRedundant: pointer.To(servicePlan.ZoneBalancing), | ||||||
ElasticScaleEnabled: pointer.To(servicePlan.ElasticScaling), | ||||||
}, | ||||||
Sku: &appserviceplans.SkuDescription{ | ||||||
Name: pointer.To(servicePlan.Sku), | ||||||
|
@@ -192,12 +200,21 @@ func (r ServicePlanResource) Create() sdk.ResourceFunc { | |||||
} | ||||||
|
||||||
if servicePlan.MaximumElasticWorkerCount > 0 { | ||||||
if !isServicePlanSupportScaleOut(servicePlan.Sku) { | ||||||
return fmt.Errorf("`maximum_elastic_worker_count` can only be specified with Elastic Premium Skus") | ||||||
if !isServicePlanSupportScaleOut(servicePlan.Sku) && (helpers.PlanIsPremium(servicePlan.Sku) && !servicePlan.ElasticScaling) { | ||||||
return fmt.Errorf("`maximum_elastic_worker_count` can only be specified with Elastic Premium Skus or Premium V2 and V3 plan with `elastic_scale_enabled` set to true") | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this reads more clearly and accurately here:
Suggested change
|
||||||
} | ||||||
if helpers.PlanIsPremium(servicePlan.Sku) { | ||||||
appServicePlan.Properties.ElasticScaleEnabled = pointer.To(servicePlan.ElasticScaling) | ||||||
} | ||||||
appServicePlan.Properties.MaximumElasticWorkerCount = pointer.To(int64(servicePlan.MaximumElasticWorkerCount)) | ||||||
} | ||||||
|
||||||
if servicePlan.ElasticScaling && !(helpers.PlanIsPremium(servicePlan.Sku) || isServicePlanSupportScaleOut(servicePlan.Sku)) { | ||||||
return fmt.Errorf("`elastic_scale_enabled` can only be enabled for Elastic Premium Skus or Premium V2 and V3 Skus") | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For consistency:
Suggested change
|
||||||
} else if !servicePlan.ElasticScaling && helpers.PlanIsElastic(&servicePlan.Sku) { | ||||||
return fmt.Errorf("`elastic_scale_enabled` cannot be disabled for elastic plans") | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. for consistency:
Suggested change
|
||||||
} | ||||||
|
||||||
if servicePlan.WorkerCount != 0 { | ||||||
appServicePlan.Sku.Capacity = pointer.To(int64(servicePlan.WorkerCount)) | ||||||
} | ||||||
|
@@ -271,7 +288,10 @@ func (r ServicePlanResource) Read() sdk.ResourceFunc { | |||||
state.ZoneBalancing = utils.NormaliseNilableBool(props.ZoneRedundant) | ||||||
|
||||||
state.MaximumElasticWorkerCount = int(pointer.From(props.MaximumElasticWorkerCount)) | ||||||
|
||||||
state.ElasticScaling = pointer.From(props.ElasticScaleEnabled) | ||||||
} | ||||||
|
||||||
state.Tags = pointer.From(model.Tags) | ||||||
} | ||||||
|
||||||
|
@@ -345,12 +365,19 @@ func (r ServicePlanResource) Update() sdk.ResourceFunc { | |||||
} | ||||||
|
||||||
if metadata.ResourceData.HasChange("maximum_elastic_worker_count") { | ||||||
if metadata.ResourceData.HasChange("maximum_elastic_worker_count") && !isServicePlanSupportScaleOut(state.Sku) { | ||||||
return fmt.Errorf("`maximum_elastic_worker_count` can only be specified with Elastic Premium Skus") | ||||||
if metadata.ResourceData.HasChange("maximum_elastic_worker_count") && (!isServicePlanSupportScaleOut(state.Sku) || helpers.PlanIsPremium(state.Sku) && !state.ElasticScaling) { | ||||||
return fmt.Errorf("`maximum_elastic_worker_count` can only be specified with Elastic Premium Skus or Premium v2, v3 with `elastic_scale_enabled` set to true") | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. as above:
Suggested change
|
||||||
} | ||||||
model.Properties.MaximumElasticWorkerCount = pointer.To(int64(state.MaximumElasticWorkerCount)) | ||||||
} | ||||||
|
||||||
if metadata.ResourceData.HasChange("elastic_scale_enabled") { | ||||||
if state.ElasticScaling && !(isServicePlanSupportScaleOut(state.Sku) || helpers.PlanIsPremium(state.Sku)) { | ||||||
return fmt.Errorf("`elastic_scale_enabled` can only be enabled for Elastic Premium Skus or Premium V2 and V3 Skus") | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
} | ||||||
model.Properties.ElasticScaleEnabled = pointer.To(state.ElasticScaling) | ||||||
} | ||||||
|
||||||
if err = client.CreateOrUpdateThenPoll(ctx, *id, model); err != nil { | ||||||
return fmt.Errorf("updating %s: %+v", id, err) | ||||||
} | ||||||
|
@@ -376,3 +403,20 @@ func (r ServicePlanResource) StateUpgraders() sdk.StateUpgradeData { | |||||
}, | ||||||
} | ||||||
} | ||||||
|
||||||
func (s ServicePlanResource) CustomizeDiff() sdk.ResourceFunc { | ||||||
return sdk.ResourceFunc{ | ||||||
Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { | ||||||
rd := metadata.ResourceDiff | ||||||
sku := rd.Get("sku_name").(string) | ||||||
|
||||||
if helpers.PlanIsElastic(&sku) { | ||||||
elasticScalingEnabled := rd.Get("elastic_scale_enabled").(bool) | ||||||
if rd.HasChange("elastic_scale_enabled") && !elasticScalingEnabled { | ||||||
return fmt.Errorf("`elastic_scale_enabled` cannot be disabled for elastic plan") | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
} | ||||||
} | ||||||
return nil | ||||||
}, | ||||||
} | ||||||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -6,6 +6,7 @@ package appservice_test | |||||||||||||||
import ( | ||||||||||||||||
"context" | ||||||||||||||||
"fmt" | ||||||||||||||||
"regexp" | ||||||||||||||||
"testing" | ||||||||||||||||
|
||||||||||||||||
"github.com/hashicorp/go-azure-helpers/lang/response" | ||||||||||||||||
|
@@ -149,6 +150,78 @@ func TestAccServicePlan_maxElasticWorkerCount(t *testing.T) { | |||||||||||||||
}) | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
func TestAccServicePlan_premiumElasticScaling(t *testing.T) { | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we add a test that updates a non-scaling plan type to scaling with the new property set to true, and then back again? e.g. |
||||||||||||||||
data := acceptance.BuildTestData(t, "azurerm_service_plan", "test") | ||||||||||||||||
r := ServicePlanResource{} | ||||||||||||||||
|
||||||||||||||||
data.ResourceTest(t, r, []acceptance.TestStep{ | ||||||||||||||||
{ | ||||||||||||||||
Config: r.complete(data), | ||||||||||||||||
Check: acceptance.ComposeTestCheckFunc( | ||||||||||||||||
check.That(data.ResourceName).ExistsInAzure(r), | ||||||||||||||||
), | ||||||||||||||||
}, | ||||||||||||||||
data.ImportStep(), | ||||||||||||||||
{ | ||||||||||||||||
Config: r.premiumElasticScale(data, 5, "P1v3"), | ||||||||||||||||
Check: acceptance.ComposeTestCheckFunc( | ||||||||||||||||
check.That(data.ResourceName).ExistsInAzure(r), | ||||||||||||||||
), | ||||||||||||||||
}, | ||||||||||||||||
data.ImportStep(), | ||||||||||||||||
{ | ||||||||||||||||
Config: r.complete(data), | ||||||||||||||||
Check: acceptance.ComposeTestCheckFunc( | ||||||||||||||||
check.That(data.ResourceName).ExistsInAzure(r), | ||||||||||||||||
), | ||||||||||||||||
}, | ||||||||||||||||
data.ImportStep(), | ||||||||||||||||
}) | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
func TestAccServicePlan_premiumElasticScalingErrorUpdate(t *testing.T) { | ||||||||||||||||
data := acceptance.BuildTestData(t, "azurerm_service_plan", "test") | ||||||||||||||||
r := ServicePlanResource{} | ||||||||||||||||
|
||||||||||||||||
data.ResourceTest(t, r, []acceptance.TestStep{ | ||||||||||||||||
{ | ||||||||||||||||
Config: r.premiumElasticScaleError(data, "S1"), | ||||||||||||||||
ExpectError: regexp.MustCompile("`elastic_scale_enabled` can only be enabled for Elastic Premium Skus or Premium V2 and V3 Skus"), | ||||||||||||||||
}, | ||||||||||||||||
{ | ||||||||||||||||
Config: r.premiumElasticScaleError(data, "P1v3"), | ||||||||||||||||
Check: acceptance.ComposeTestCheckFunc( | ||||||||||||||||
check.That(data.ResourceName).ExistsInAzure(r), | ||||||||||||||||
), | ||||||||||||||||
}, | ||||||||||||||||
data.ImportStep(), | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. An expectError test should only perform that one check. The property should be being checked for correct/successful use elsewhere.
Suggested change
|
||||||||||||||||
}) | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
func TestAccServicePlan_premiumElasticScalingError(t *testing.T) { | ||||||||||||||||
data := acceptance.BuildTestData(t, "azurerm_service_plan", "test") | ||||||||||||||||
r := ServicePlanResource{} | ||||||||||||||||
|
||||||||||||||||
data.ResourceTest(t, r, []acceptance.TestStep{ | ||||||||||||||||
{ | ||||||||||||||||
Config: r.premiumElasticScaleError(data, "S1"), | ||||||||||||||||
ExpectError: regexp.MustCompile("`elastic_scale_enabled` can only be enabled for Elastic Premium Skus or Premium V2 and V3 Skus"), | ||||||||||||||||
}, | ||||||||||||||||
}) | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
func TestAccServicePlan_premiumElasticScalingErrorElasticPlan(t *testing.T) { | ||||||||||||||||
data := acceptance.BuildTestData(t, "azurerm_service_plan", "test") | ||||||||||||||||
r := ServicePlanResource{} | ||||||||||||||||
|
||||||||||||||||
data.ResourceTest(t, r, []acceptance.TestStep{ | ||||||||||||||||
{ | ||||||||||||||||
Config: r.premiumElasticScaleErrorElasticPlan(data, "EP1"), | ||||||||||||||||
ExpectError: regexp.MustCompile("`elastic_scale_enabled` cannot be disabled for elastic plan"), | ||||||||||||||||
}, | ||||||||||||||||
}) | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
func TestAccServicePlan_memoryOptimized(t *testing.T) { | ||||||||||||||||
data := acceptance.BuildTestData(t, "azurerm_service_plan", "test") | ||||||||||||||||
r := ServicePlanResource{} | ||||||||||||||||
|
@@ -362,6 +435,7 @@ resource "azurerm_service_plan" "test" { | |||||||||||||||
sku_name = "EP1" | ||||||||||||||||
os_type = "Linux" | ||||||||||||||||
maximum_elastic_worker_count = %[3]d | ||||||||||||||||
elastic_scale_enabled = true | ||||||||||||||||
|
||||||||||||||||
tags = { | ||||||||||||||||
environment = "AccTest" | ||||||||||||||||
|
@@ -389,6 +463,35 @@ resource "azurerm_service_plan" "test" { | |||||||||||||||
sku_name = "%[3]s" | ||||||||||||||||
os_type = "Linux" | ||||||||||||||||
maximum_elastic_worker_count = %[4]d | ||||||||||||||||
elastic_scale_enabled = true | ||||||||||||||||
|
||||||||||||||||
tags = { | ||||||||||||||||
environment = "AccTest" | ||||||||||||||||
Foo = "bar" | ||||||||||||||||
} | ||||||||||||||||
} | ||||||||||||||||
`, data.RandomInteger, data.Locations.Primary, sku, count) | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
func (r ServicePlanResource) premiumElasticScale(data acceptance.TestData, count int, sku string) string { | ||||||||||||||||
return fmt.Sprintf(` | ||||||||||||||||
provider "azurerm" { | ||||||||||||||||
features {} | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
resource "azurerm_resource_group" "test" { | ||||||||||||||||
name = "acctestRG-appserviceplan-%[1]d" | ||||||||||||||||
location = "%s" | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
resource "azurerm_service_plan" "test" { | ||||||||||||||||
name = "acctest-SP-%[1]d" | ||||||||||||||||
resource_group_name = azurerm_resource_group.test.name | ||||||||||||||||
location = azurerm_resource_group.test.location | ||||||||||||||||
sku_name = "%[3]s" | ||||||||||||||||
os_type = "Linux" | ||||||||||||||||
elastic_scale_enabled = true | ||||||||||||||||
maximum_elastic_worker_count = %[4]d | ||||||||||||||||
|
||||||||||||||||
tags = { | ||||||||||||||||
environment = "AccTest" | ||||||||||||||||
|
@@ -398,6 +501,59 @@ resource "azurerm_service_plan" "test" { | |||||||||||||||
`, data.RandomInteger, data.Locations.Primary, sku, count) | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
func (r ServicePlanResource) premiumElasticScaleError(data acceptance.TestData, sku string) string { | ||||||||||||||||
return fmt.Sprintf(` | ||||||||||||||||
provider "azurerm" { | ||||||||||||||||
features {} | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
resource "azurerm_resource_group" "test" { | ||||||||||||||||
name = "acctestRG-appserviceplan-%[1]d" | ||||||||||||||||
location = "%s" | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
resource "azurerm_service_plan" "test" { | ||||||||||||||||
name = "acctest-SP-%[1]d" | ||||||||||||||||
resource_group_name = azurerm_resource_group.test.name | ||||||||||||||||
location = azurerm_resource_group.test.location | ||||||||||||||||
sku_name = "%[3]s" | ||||||||||||||||
os_type = "Linux" | ||||||||||||||||
elastic_scale_enabled = true | ||||||||||||||||
|
||||||||||||||||
tags = { | ||||||||||||||||
environment = "AccTest" | ||||||||||||||||
Foo = "bar" | ||||||||||||||||
} | ||||||||||||||||
} | ||||||||||||||||
`, data.RandomInteger, data.Locations.Primary, sku) | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
func (r ServicePlanResource) premiumElasticScaleErrorElasticPlan(data acceptance.TestData, sku string) string { | ||||||||||||||||
return fmt.Sprintf(` | ||||||||||||||||
provider "azurerm" { | ||||||||||||||||
features {} | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
resource "azurerm_resource_group" "test" { | ||||||||||||||||
name = "xiaxintestRG-appserviceplan-%[1]d" | ||||||||||||||||
location = "%s" | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
resource "azurerm_service_plan" "test" { | ||||||||||||||||
name = "xiaxintest-SP-%[1]d" | ||||||||||||||||
resource_group_name = azurerm_resource_group.test.name | ||||||||||||||||
location = azurerm_resource_group.test.location | ||||||||||||||||
sku_name = "%[3]s" | ||||||||||||||||
os_type = "Linux" | ||||||||||||||||
|
||||||||||||||||
tags = { | ||||||||||||||||
environment = "AccTest" | ||||||||||||||||
Foo = "bar" | ||||||||||||||||
} | ||||||||||||||||
} | ||||||||||||||||
`, data.RandomInteger, data.Locations.Primary, sku) | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
func (r ServicePlanResource) memoryOptimized(data acceptance.TestData) string { | ||||||||||||||||
return fmt.Sprintf(` | ||||||||||||||||
provider "azurerm" { | ||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will, unfortunately, be a breaking change for existing EP plan deployments. It has different default values per Plan SKU. It may be possible to handle this in a
CustomiseDiff
function in a non-breaking way. Sorry I did not spot it sooner.