Reputation: 28800
I'm trying to set up multiple autoscaling rules for an Azure App Service Plan using Terraform.
resource "azurerm_resource_group" "example" {
name = "autoscalingTest"
location = "West Europe"
}
resource "azurerm_virtual_machine_scale_set" "example" {
# ...
}
resource "azurerm_monitor_autoscale_setting" "example" {
name = "myAutoscaleSetting"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
target_resource_id = azurerm_virtual_machine_scale_set.example.id
profile {
name = "defaultProfile"
capacity {
default = 1
minimum = 1
maximum = 10
}
rule {
metric_trigger {
metric_name = "Percentage CPU"
metric_resource_id = azurerm_virtual_machine_scale_set.example.id
time_grain = "PT1M"
statistic = "Average"
time_window = "PT5M"
time_aggregation = "Average"
operator = "GreaterThan"
threshold = 75
metric_namespace = "microsoft.compute/virtualmachinescalesets"
dimensions {
name = "AppName"
operator = "Equals"
values = ["App1"]
}
}
scale_action {
direction = "Increase"
type = "ChangeCount"
value = "1"
cooldown = "PT1M"
}
}
rule {
metric_trigger {
metric_name = "Percentage CPU"
metric_resource_id = azurerm_virtual_machine_scale_set.example.id
time_grain = "PT1M"
statistic = "Average"
time_window = "PT5M"
time_aggregation = "Average"
operator = "LessThan"
threshold = 25
}
scale_action {
direction = "Decrease"
type = "ChangeCount"
value = "1"
cooldown = "PT1M"
}
}
}
notification {
email {
send_to_subscription_administrator = true
send_to_subscription_co_administrator = true
custom_emails = ["[email protected]"]
}
}
}
Basically, I do not want to repeat the rules. So I will just define one block for the rules and use the variables file to set the values for the multiple rules.
This is what I have so far, but it's not working:
main.tf file
resource "azurerm_monitor_autoscale_setting" "main" {
name = var.monitor_autoscale_setting_name
resource_group_name = var.resource_group_name
location = var.resource_group_location
target_resource_id = var.target_resource_id
enabled = var.monitor_autoscale_setting_enabled
profile {
name = var.autoscale_profile_name
capacity {
default = var.profile_capacity_default
minimum = var.profile_capacity_minimum
maximum = var.profile_capacity_maximum
}
for_each = var.rules
metric_trigger {
metric_name = each.value["metric_name"]
metric_resource_id = each.value["metric_resource_id"]
time_grain = each.value["metric_time_grain"]
statistic = each.value["metric_statistic"]
time_window = each.value["metric_time_window"]
time_aggregation = each.value["metric_time_aggregation"]
operator = each.value["metric_operator"]
threshold = each.value["metric_threshold"]
}
scale_action {
direction = each.value["scale_action_direction"]
type = each.value["scale_action_type"]
value = each.value["scale_action_value"]
cooldown = each.value["scale_action_cooldown"]
}
notification {
email {
send_to_subscription_administrator = var.send_to_subscription_administrator
send_to_subscription_co_administrator = var.send_to_subscription_co_administrator
custom_emails = var.notification_custom_emails
}
}
}
module file
module "monitor_autoscale_setting" {
source = "../../../modules/azure/monitor-autoscale-setting"
monitor_autoscale_setting_name = var.monitor_autoscale_setting_name
resource_group_name = var.resource_group_name
resource_group_location = var.resource_group_location
target_resource_id = var.app_service_plan_id
monitor_autoscale_setting_enabled = var.monitor_autoscale_setting_enabled
autoscale_profile_name = var.autoscale_profile_name
profile_capacity_default = var.profile_capacity_default
profile_capacity_minimum = var.profile_capacity_minimum
profile_capacity_maximum = var.profile_capacity_maximum
rules = {
"rule1" = {
metric_trigger = {
metric_name = var.metric_name
metric_resource_id = var.app_service_plan_id
metric_time_grain = var.metric_time_grain
metric_statistic = var.metric_statistic
metric_time_window = var.metric_time_window
metric_time_aggregation = var.metric_time_aggregation
metric_operator = var.metric_operator
metric_threshold = var.metric_threshold
}
scale_action = {
scale_action_direction = var.scale_action_direction
scale_action_type = var.scale_action_type
scale_action_value = var.scale_action_value
scale_action_cooldown = var.scale_action_cooldown
}
}
"rule2" = {
metric_name = var.metric_name
metric_resource_id = var.app_service_plan_id
metric_time_grain = var.metric_time_grain
metric_statistic = var.metric_statistic
metric_time_window = var.metric_time_window
metric_time_aggregation = var.metric_time_aggregation
metric_operator = var.metric_operator
metric_threshold = var.metric_threshold
scale_action_direction = var.scale_action_direction
scale_action_type = var.scale_action_type
scale_action_value = var.scale_action_value
scale_action_cooldown = var.scale_action_cooldown
}
}
}
variables.tf file
variable "rules" {
type = map(object({
metric_trigger = {
metric_name = string
metric_time_grain = string
metric_statistic = string
metric_time_window = string
metric_time_aggregation = string
metric_operator = string
metric_threshold = number
}
scale_action = {
scale_action_direction = string
scale_action_type = string
scale_action_value = string
scale_action_cooldown = string
}
}))
default = {
"rule1" = {
metric_trigger = {
metric_name = "Percentage CPU"
metric_time_grain = "PT1M"
metric_statistic = "Average"
metric_time_window = "PT5M"
metric_time_aggregation = "Average"
metric_operator = "GreaterThan"
metric_threshold = 90
}
scale_action = {
scale_action_direction = "Increase"
scale_action_type = "ChangeCount"
scale_action_value = "1"
scale_action_cooldown = "PT1M"
}
}
"rule2" = {
metric_trigger = {
metric_name = "Percentage CPU"
metric_time_grain = "PT1M"
metric_statistic = "Average"
metric_time_window = "PT5M"
metric_time_aggregation = "Average"
metric_operator = "LessThan"
metric_threshold = 10
}
scale_action = {
scale_action_direction = "Decrease"
scale_action_type = "ChangeCount"
scale_action_value = "1"
scale_action_cooldown = "PT1M"
}
}
}
}
variable "monitor_autoscale_setting_name" {
type = string
description = "The name of the AutoScale Setting"
}
variable "resource_group_name" {
type = string
description = "The name of the resource group in which to create the App Service Plan component"
}
variable "resource_group_location" {
type = string
description = "The supported Azure location where the resource exists"
}
variable "target_resource_id" {
type = string
description = "Specifies the resource ID of the resource that the autoscale setting should be added to"
}
variable "monitor_autoscale_setting_enabled" {
type = bool
description = "Specifies whether automatic scaling is enabled for the target resource. Defaults to true"
}
variable "autoscale_profile_name" {
type = string
description = "The name of the profile"
}
variable "profile_capacity_default" {
type = number
description = "The number of instances that are available for scaling if metrics are not available for evaluation"
}
variable "profile_capacity_minimum" {
type = number
description = "The minimum number of instances for this resource. Valid values are between 0 and 1000."
}
variable "profile_capacity_maximum" {
type = number
description = "The maximum number of instances for this resource. Valid values are between 0 and 1000"
}
Here are the errors:
│ Error: Invalid type specification
│
│ on variables.tf line 162, in variable "rules":
│ 162: metric_trigger = {
│ 163: metric_name = string
│ 164: metric_time_grain = string
│ 165: metric_statistic = string
│ 166: metric_time_window = string
│ 167: metric_time_aggregation = string
│ 168: metric_operator = string
│ 169: metric_threshold = number
│ 170: }
│
│ A type specification is either a primitive type keyword (bool, number, string) or a complex type constructor call, like list(string).
╵
╷
│ Error: Invalid type specification
│
│ on variables.tf line 171, in variable "rules":
│ 171: scale_action = {
│ 172: scale_action_direction = string
│ 173: scale_action_type = string
│ 174: scale_action_value = string
│ 175: scale_action_cooldown = string
│ 176: }
│
│ A type specification is either a primitive type keyword (bool, number, string) or a complex type constructor call, like list(string).
Any form of help will be appreciated.
Upvotes: 0
Views: 3552
Reputation: 238081
The correct type for your var.rules
is as below (you forgot object
):
variable "rules" {
type = map(object({
metric_trigger = object({
metric_name = string
metric_time_grain = string
metric_statistic = string
metric_time_window = string
metric_time_aggregation = string
metric_operator = string
metric_threshold = number
})
scale_action = object({
scale_action_direction = string
scale_action_type = string
scale_action_value = string
scale_action_cooldown = string
})
}))
default = {
"rule1" = {
metric_trigger = {
metric_name = "Percentage CPU"
metric_time_grain = "PT1M"
metric_statistic = "Average"
metric_time_window = "PT5M"
metric_time_aggregation = "Average"
metric_operator = "GreaterThan"
metric_threshold = 90
}
scale_action = {
scale_action_direction = "Increase"
scale_action_type = "ChangeCount"
scale_action_value = "1"
scale_action_cooldown = "PT1M"
}
}
"rule2" = {
metric_trigger = {
metric_name = "Percentage CPU"
metric_time_grain = "PT1M"
metric_statistic = "Average"
metric_time_window = "PT5M"
metric_time_aggregation = "Average"
metric_operator = "LessThan"
metric_threshold = 10
}
scale_action = {
scale_action_direction = "Decrease"
scale_action_type = "ChangeCount"
scale_action_value = "1"
scale_action_cooldown = "PT1M"
}
}
}
}
Upvotes: 1