Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions examples/autoscaling/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
provider "aws" {

Check warning on line 1 in examples/autoscaling/main.tf

View workflow job for this annotation

GitHub Actions / terraform-module / CI / Lint (./examples/autoscaling)

[tflint] reported by reviewdog 🐶 Missing version constraint for provider "aws" in `required_providers` Raw Output: main.tf:1:1: warning: Missing version constraint for provider "aws" in `required_providers` ()

Check warning on line 1 in examples/autoscaling/main.tf

View workflow job for this annotation

GitHub Actions / terraform-module / CI / Lint (./examples/autoscaling)

[tflint] reported by reviewdog 🐶 Missing version constraint for provider "aws" in `required_providers` Raw Output: main.tf:1:1: warning: Missing version constraint for provider "aws" in `required_providers` ()
region = "us-west-1"
}

module "rds_cluster_autoscaling_mysql_predefined" {
source = "../../"
name = "autoscaling_predefined_metrics"
engine = "aurora-mysql"
cluster_family = "aurora-mysql8.0"
cluster_size = 2
namespace = "eg"
stage = "dev"
admin_user = "admin1"
admin_password = "Test123456789"
db_name = "dbname"
db_port = 5432
instance_type = "db.r4.large"
vpc_id = "vpc-xxxxxxxx"
security_groups = ["sg-xxxxxxxx"]
subnets = ["subnet-xxxxxxxx", "subnet-xxxxxxxx"]
zone_id = "Zxxxxxxxx"

autoscaling_enabled = true
autoscaling_scale_in_cooldown = 300
autoscaling_scale_out_cooldown = 300
autoscaling_min_capacity = 1
autoscaling_max_capacity = 3
autoscaling_policy_type = "TargetTrackingScaling"
autoscaling_target_metrics = "RDSReaderAverageCPUUtilization" // or "RDSReaderAverageDatabaseConnections"
}

module "rds_cluster_autoscaling_mysql_custom_cluster_level" {
source = "../../"
name = "autoscaling_custom_metrics_cluster"
engine = "aurora-mysql"
cluster_family = "aurora-mysql8.0"
cluster_size = 2
namespace = "eg"
stage = "dev"
admin_user = "admin1"
admin_password = "Test123456789"
db_name = "dbname"
db_port = 5432
instance_type = "db.r4.large"
vpc_id = "vpc-xxxxxxxx"
security_groups = ["sg-xxxxxxxx"]
subnets = ["subnet-xxxxxxxx", "subnet-xxxxxxxx"]
zone_id = "Zxxxxxxxx"

autoscaling_enabled = true
autoscaling_scale_in_cooldown = 300
autoscaling_scale_out_cooldown = 300
autoscaling_min_capacity = 1
autoscaling_max_capacity = 3
autoscaling_policy_type = "TargetTrackingScaling"
autoscaling_target_metrics = "Custom"
autoscaling_target_value = 60
autoscaling_custom_metric = {
namespace = "AWS/RDS"
metric_name = "AuroraReplicaLagMaximum" # any valid Aurora metric under AWS/RDS
statistic = "Average"
# unit = "Milliseconds" # optional, if you want to pin it
dimensions = [
{ name = "DBClusterIdentifier", value = "my-aurora-cluster" }
]
}
}

# WARNING: Edge case for which i could not find a real use yet.
module "rds_cluster_autoscaling_mysql_custom_instances_level" {
source = "../../"
name = "autoscaling_custom_metrics_instances"
engine = "aurora-mysql"
cluster_family = "aurora-mysql8.0"
cluster_size = 2
namespace = "eg"
stage = "dev"
admin_user = "admin1"
admin_password = "Test123456789"
db_name = "dbname"
db_port = 5432
instance_type = "db.r4.large"
vpc_id = "vpc-xxxxxxxx"
security_groups = ["sg-xxxxxxxx"]
subnets = ["subnet-xxxxxxxx", "subnet-xxxxxxxx"]
zone_id = "Zxxxxxxxx"

autoscaling_enabled = true
autoscaling_scale_in_cooldown = 300
autoscaling_scale_out_cooldown = 300
autoscaling_min_capacity = 1
autoscaling_max_capacity = 3
autoscaling_policy_type = "TargetTrackingScaling"
autoscaling_target_metrics = "Custom"
autoscaling_target_value = 60
autoscaling_custom_metric = {
namespace = "AWS/RDS"
metric_name = "CPUUtilization" # any valid Aurora metric under AWS/RDS
statistic = "Average"
# unit = "Percent" # optional, if you want to pin it
dimensions = [
{ name = "DBInstanceIdentifier", value = "my-aurora-reader-1" }
]
}
}
42 changes: 40 additions & 2 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ locals {
ignore_admin_credentials = var.replication_source_identifier != "" || var.snapshot_identifier != null
reserved_instance_engine = var.engine
use_reserved_instances = var.use_reserved_instances && !local.is_serverless

use_predefined_metric = contains([
"RDSReaderAverageCPUUtilization",
"RDSReaderAverageDatabaseConnections",
], var.autoscaling_target_metrics)
}

data "aws_partition" "current" {
Expand Down Expand Up @@ -492,23 +497,56 @@ resource "aws_appautoscaling_target" "replicas" {
max_capacity = var.autoscaling_max_capacity
}

resource "aws_appautoscaling_policy" "replicas" {
count = local.enabled && var.autoscaling_enabled ? 1 : 0
# --- Predefined metric policy (only when using the two reader metrics) ---
resource "aws_appautoscaling_policy" "replicas_predefined" {
count = (local.enabled && var.autoscaling_enabled && local.use_predefined_metric) ? 1 : 0
name = module.this.id
service_namespace = join("", aws_appautoscaling_target.replicas[*].service_namespace)
scalable_dimension = join("", aws_appautoscaling_target.replicas[*].scalable_dimension)
resource_id = join("", aws_appautoscaling_target.replicas[*].resource_id)
policy_type = var.autoscaling_policy_type

target_tracking_scaling_policy_configuration {
disable_scale_in = false
target_value = var.autoscaling_target_value
scale_in_cooldown = var.autoscaling_scale_in_cooldown
scale_out_cooldown = var.autoscaling_scale_out_cooldown

predefined_metric_specification {
predefined_metric_type = var.autoscaling_target_metrics
}
}
}

# --- Customized metric policy (everything else) ---
resource "aws_appautoscaling_policy" "replicas_custom" {
count = (local.enabled && var.autoscaling_enabled && !local.use_predefined_metric) ? 1 : 0
name = module.this.id
service_namespace = join("", aws_appautoscaling_target.replicas[*].service_namespace)
scalable_dimension = join("", aws_appautoscaling_target.replicas[*].scalable_dimension)
resource_id = join("", aws_appautoscaling_target.replicas[*].resource_id)
policy_type = var.autoscaling_policy_type

target_tracking_scaling_policy_configuration {
disable_scale_in = false
target_value = var.autoscaling_target_value
scale_in_cooldown = var.autoscaling_scale_in_cooldown
scale_out_cooldown = var.autoscaling_scale_out_cooldown

customized_metric_specification {
metric_name = var.autoscaling_custom_metric.metric_name
namespace = var.autoscaling_custom_metric.namespace
statistic = var.autoscaling_custom_metric.statistic
unit = try(var.autoscaling_custom_metric.unit, null)

dynamic "dimensions" {
for_each = try(var.autoscaling_custom_metric.dimensions, [])
content {
name = dimensions.value.name
value = dimensions.value.value
}
}
}
}
}

Expand Down
22 changes: 21 additions & 1 deletion variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,27 @@ variable "autoscaling_policy_type" {
variable "autoscaling_target_metrics" {
type = string
default = "RDSReaderAverageCPUUtilization"
description = "The metrics type to use. If this value isn't provided the default is CPU utilization"
description = "The metrics type to use. If this value isn't provided the default is CPU utilization. IF the value is not `RDSReaderAverageCPUUtilization` nor `RDSReaderAverageDatabaseConnections` a custom metric for autoscaling must be specified"
}

variable "autoscaling_custom_metric" {
type = object({
metric_name = string
namespace = string
statistic = string
unit = optional(string)
dimensions = optional(list(object({
name = string,
value = string
})))
})
default = {
metric_name = ""
namespace = ""
statistic = "Average"
dimensions = []
}
description = "Specification for a custom Autoscaling metric to use. Will be used if autoscaling_target_metrics os neither `RDSReaderAverageCPUUtilization` nor `RDSReaderAverageDatabaseConnections`"
}

variable "autoscaling_target_value" {
Expand Down
Loading