Skip to content

Commit

Permalink
Add autoscaling to NGINXaaS
Browse files Browse the repository at this point in the history
  • Loading branch information
puneetsarna committed Mar 14, 2024
1 parent ae7b92b commit 439de7a
Show file tree
Hide file tree
Showing 6 changed files with 300 additions and 6 deletions.
38 changes: 37 additions & 1 deletion internal/services/nginx/nginx_deployment_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ type DeploymentDataSourceModel struct {
ManagedResourceGroup string `tfschema:"managed_resource_group"`
Location string `tfschema:"location"`
Capacity int64 `tfschema:"capacity"`
AutoScaleProfile []AutoScaleProfile `tfschema:"auto_scale_profile"`
DiagnoseSupportEnabled bool `tfschema:"diagnose_support_enabled"`
Email string `tfschema:"email"`
IpAddress string `tfschema:"ip_address"`
Expand Down Expand Up @@ -80,6 +81,29 @@ func (m DeploymentDataSource) Attributes() map[string]*pluginsdk.Schema {
Computed: true,
},

"auto_scale_profile": {
Type: pluginsdk.TypeList,
Computed: true,
Elem: &pluginsdk.Resource{
Schema: map[string]*pluginsdk.Schema{
"name": {
Type: pluginsdk.TypeString,
Computed: true,
},

"min_capacity": {
Type: pluginsdk.TypeInt,
Computed: true,
},

"max_capacity": {
Type: pluginsdk.TypeInt,
Computed: true,
},
},
},
},

"diagnose_support_enabled": {
Type: pluginsdk.TypeBool,
Computed: true,
Expand Down Expand Up @@ -267,7 +291,19 @@ func (m DeploymentDataSource) Read() sdk.ResourceFunc {
}

if scaling := props.ScalingProperties; scaling != nil {
output.Capacity = pointer.ToInt64(props.ScalingProperties.Capacity)
if capacity := scaling.Capacity; capacity != nil {
output.Capacity = pointer.ToInt64(props.ScalingProperties.Capacity)
}
if autoScaleProfiles := scaling.AutoScaleSettings; autoScaleProfiles != nil {
profiles := autoScaleProfiles.Profiles
for _, profile := range profiles {
output.AutoScaleProfile = append(output.AutoScaleProfile, AutoScaleProfile{
Name: profile.Name,
Min: profile.Capacity.Min,
Max: profile.Capacity.Max,
})
}
}
}

if userProfile := props.UserProfile; userProfile != nil && userProfile.PreferredEmail != nil {
Expand Down
27 changes: 27 additions & 0 deletions internal/services/nginx/nginx_deployment_data_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,30 @@ data "azurerm_nginx_deployment" "test" {
}
`, DeploymentResource{}.basic(data))
}

func (d NginxDeploymentDataSource) basicAutoscaling(data acceptance.TestData) string {
return fmt.Sprintf(`
%s
data "azurerm_nginx_deployment" "test" {
name = azurerm_nginx_deployment.test.name
resource_group_name = azurerm_nginx_deployment.test.resource_group_name
}
`, DeploymentResource{}.basicAutoscaling(data))
}

func TestAccNginxDeploymentDataSource_autoscaling(t *testing.T) {
data := acceptance.BuildTestData(t, "data.azurerm_nginx_deployment", "test")
r := NginxDeploymentDataSource{}

data.DataSourceTest(t, []acceptance.TestStep{
{
Config: r.basicAutoscaling(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).Key("auto_scale_profile.0.name").HasValue("test"),
check.That(data.ResourceName).Key("auto_scale_profile.0.min_capacity").HasValue("10"),
check.That(data.ResourceName).Key("auto_scale_profile.0.max_capacity").HasValue("30"),
),
},
})
}
93 changes: 88 additions & 5 deletions internal/services/nginx/nginx_deployment_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ type NetworkInterface struct {
SubnetId string `tfschema:"subnet_id"`
}

type AutoScaleProfile struct {
Name string `tfschema:"name"`
Min int64 `tfschema:"min_capacity"`
Max int64 `tfschema:"max_capacity"`
}

type DeploymentModel struct {
ResourceGroupName string `tfschema:"resource_group_name"`
Name string `tfschema:"name"`
Expand All @@ -46,6 +52,7 @@ type DeploymentModel struct {
ManagedResourceGroup string `tfschema:"managed_resource_group"`
Location string `tfschema:"location"`
Capacity int64 `tfschema:"capacity"`
AutoScaleProfile []AutoScaleProfile `tfschema:"auto_scale_profile"`
DiagnoseSupportEnabled bool `tfschema:"diagnose_support_enabled"`
Email string `tfschema:"email"`
IpAddress string `tfschema:"ip_address"`
Expand Down Expand Up @@ -99,10 +106,38 @@ func (m DeploymentResource) Arguments() map[string]*pluginsdk.Schema {
"location": commonschema.Location(),

"capacity": {
Type: pluginsdk.TypeInt,
Optional: true,
Default: 20,
ValidateFunc: validation.IntPositive,
Type: pluginsdk.TypeInt,
Optional: true,
ConflictsWith: []string{"auto_scale_profile"},
Default: 20,
ValidateFunc: validation.IntPositive,
},

"auto_scale_profile": {
Type: pluginsdk.TypeList,
Optional: true,
ConflictsWith: []string{"capacity"},
Elem: &pluginsdk.Resource{
Schema: map[string]*pluginsdk.Schema{
"name": {
Type: pluginsdk.TypeString,
Required: true,
ValidateFunc: validation.StringIsNotEmpty,
},

"min_capacity": {
Type: pluginsdk.TypeInt,
Required: true,
ValidateFunc: validation.IntPositive,
},

"max_capacity": {
Type: pluginsdk.TypeInt,
Required: true,
ValidateFunc: validation.IntPositive,
},
},
},
},

"diagnose_support_enabled": {
Expand Down Expand Up @@ -315,6 +350,24 @@ func (m DeploymentResource) Create() sdk.ResourceFunc {
}
}

if autoScaleProfile := model.AutoScaleProfile; len(autoScaleProfile) > 0 {
var autoScaleProfiles []nginxdeployment.ScaleProfile
for _, profile := range autoScaleProfile {
autoScaleProfiles = append(autoScaleProfiles, nginxdeployment.ScaleProfile{
Name: profile.Name,
Capacity: nginxdeployment.ScaleProfileCapacity{
Min: profile.Min,
Max: profile.Max,
},
})
}
prop.ScalingProperties = &nginxdeployment.NginxDeploymentScalingProperties{
AutoScaleSettings: &nginxdeployment.NginxDeploymentScalingPropertiesAutoScaleSettings{
Profiles: autoScaleProfiles,
},
}
}

if model.Email != "" {
prop.UserProfile = &nginxdeployment.NginxDeploymentUserProfile{
PreferredEmail: pointer.FromString(model.Email),
Expand Down Expand Up @@ -423,7 +476,19 @@ func (m DeploymentResource) Read() sdk.ResourceFunc {
}

if scaling := props.ScalingProperties; scaling != nil {
output.Capacity = pointer.ToInt64(props.ScalingProperties.Capacity)
if capacity := scaling.Capacity; capacity != nil {
output.Capacity = pointer.ToInt64(props.ScalingProperties.Capacity)
}
if autoScaleProfiles := scaling.AutoScaleSettings; autoScaleProfiles != nil {
profiles := autoScaleProfiles.Profiles
for _, profile := range profiles {
output.AutoScaleProfile = append(output.AutoScaleProfile, AutoScaleProfile{
Name: profile.Name,
Min: profile.Capacity.Min,
Max: profile.Capacity.Max,
})
}
}
}

if userProfile := props.UserProfile; userProfile != nil && userProfile.PreferredEmail != nil {
Expand Down Expand Up @@ -497,6 +562,24 @@ func (m DeploymentResource) Update() sdk.ResourceFunc {
}
}

if meta.ResourceData.HasChange("auto_scale_profile") && len(model.AutoScaleProfile) > 0 {
var autoScaleProfiles []nginxdeployment.ScaleProfile
for _, profile := range model.AutoScaleProfile {
autoScaleProfiles = append(autoScaleProfiles, nginxdeployment.ScaleProfile{
Name: profile.Name,
Capacity: nginxdeployment.ScaleProfileCapacity{
Min: profile.Min,
Max: profile.Max,
},
})
}
req.Properties.ScalingProperties = &nginxdeployment.NginxDeploymentScalingProperties{
AutoScaleSettings: &nginxdeployment.NginxDeploymentScalingPropertiesAutoScaleSettings{
Profiles: autoScaleProfiles,
},
}
}

if meta.ResourceData.HasChange("email") {
req.Properties.UserProfile = &nginxdeployment.NginxDeploymentUserProfile{
PreferredEmail: pointer.FromString(model.Email),
Expand Down
123 changes: 123 additions & 0 deletions internal/services/nginx/nginx_deployment_resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,92 @@ resource "azurerm_nginx_deployment" "test" {
`, a.template(data), data.RandomInteger, data.Locations.Primary)
}

func (a DeploymentResource) basicAutoscaling(data acceptance.TestData) string {
return fmt.Sprintf(`
%s
resource "azurerm_nginx_deployment" "test" {
name = "acctest-%[2]d"
resource_group_name = azurerm_resource_group.test.name
sku = "standard_Monthly"
location = azurerm_resource_group.test.location
diagnose_support_enabled = true
automatic_upgrade_channel = "stable"
frontend_public {
ip_address = [azurerm_public_ip.test.id]
}
network_interface {
subnet_id = azurerm_subnet.test.id
}
auto_scale_profile {
name = "test"
min_capacity = 10
max_capacity = 30
}
email = "test@test.com"
tags = {
foo = "bar"
}
lifecycle {
ignore_changes = [
capacity,
]
}
}
`, a.template(data), data.RandomInteger, data.Locations.Primary)
}

func (a DeploymentResource) basicAutoscaling_update(data acceptance.TestData) string {
return fmt.Sprintf(`
%s
resource "azurerm_nginx_deployment" "test" {
name = "acctest-%[2]d"
resource_group_name = azurerm_resource_group.test.name
sku = "standard_Monthly"
location = azurerm_resource_group.test.location
diagnose_support_enabled = true
automatic_upgrade_channel = "stable"
frontend_public {
ip_address = [azurerm_public_ip.test.id]
}
network_interface {
subnet_id = azurerm_subnet.test.id
}
auto_scale_profile {
name = "test"
min_capacity = 10
max_capacity = 20
}
email = "test@test.com"
tags = {
foo = "bar"
}
lifecycle {
ignore_changes = [
capacity,
]
}
}
`, a.template(data), data.RandomInteger, data.Locations.Primary)
}

func (a DeploymentResource) update(data acceptance.TestData) string {
return fmt.Sprintf(`
Expand Down Expand Up @@ -281,3 +367,40 @@ resource "azurerm_subnet" "test" {
}
`, data.RandomInteger, data.Locations.Primary)
}

func TestAccNginxDeployment_autoscaling(t *testing.T) {
data := acceptance.BuildTestData(t, nginx.DeploymentResource{}.ResourceType(), "test")
r := DeploymentResource{}
data.ResourceTest(t, r, []acceptance.TestStep{
{
Config: r.basicAutoscaling(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
check.That(data.ResourceName).Key("auto_scale_profile.0.name").HasValue("test"),
check.That(data.ResourceName).Key("auto_scale_profile.0.min_capacity").HasValue("10"),
check.That(data.ResourceName).Key("auto_scale_profile.0.max_capacity").HasValue("30"),
),
},
data.ImportStep(),
{
Config: r.basicAutoscaling_update(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
check.That(data.ResourceName).Key("auto_scale_profile.0.name").HasValue("test"),
check.That(data.ResourceName).Key("auto_scale_profile.0.min_capacity").HasValue("10"),
check.That(data.ResourceName).Key("auto_scale_profile.0.max_capacity").HasValue("20"),
),
},
data.ImportStep(),
{
Config: r.update(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
check.That(data.ResourceName).Key("auto_scale_profile.0.name").DoesNotExist(),
check.That(data.ResourceName).Key("auto_scale_profile.0.min_capacity").DoesNotExist(),
check.That(data.ResourceName).Key("auto_scale_profile.0.max_capacity").DoesNotExist(),
),
},
data.ImportStep(),
})
}
12 changes: 12 additions & 0 deletions website/docs/d/nginx_deployment.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ In addition to the Arguments listed above - the following Attributes are exporte

* `capacity` - The number of NGINX capacity units for this Nginx Deployment.

* `auto_scale_profile` - An `auto_scale_profile` block as defined below.

* `diagnose_support_enabled` - Whether diagnostic settings are enabled.

* `email` - Preferred email associated with the Nginx Deployment.
Expand Down Expand Up @@ -105,6 +107,16 @@ A `network_interface` block exports the following:

* `subnet_id` - The subnet resource ID of the Nginx Deployment.

---

An `auto_scale_profile` block exports the following:

* `name` - Name of the autoscaling profile.

* `min_capacity` - The minimum number of NGINX capacity units for this NGINX Deployment.

* `max_capacity` - The maximum number of NGINX capacity units for this NGINX Deployment.

## Timeouts

The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/language/resources/syntax#operation-timeouts) for certain actions:
Expand Down
Loading

0 comments on commit 439de7a

Please sign in to comment.