I’ve got the idea for a scaling rule define as follows:
#############################################################################################################
# Additional schedules
#############################################################################################################
locals {
// NOTE : This is a UTC timestamp and so will need to change when outside of DST to T09:45:00Z if still required.
client_x_scale_date = "2020-08-03T08:45:00Z"
client_x_scale_required = (formatdate("YYYYMMDDhhmmss", timestamp()) <= formatdate("YYYYMMDDhhmmss", local.client_x_scale_date)) ? true : false
client_x_scaling = var.environment == "production" && local.client_x_scale_required ? {
app = {
name = module.app_asg.autoscaling_group_name
asg_min = var.app_asg_min
scale = 4
}
wildcard = {
name = module.wildcard_asg.autoscaling_group_name
asg_min = var.wildcard_asg_min
scale = 6
}
} : {}
}
resource "aws_autoscaling_schedule" "client_x_scaling_up" {
for_each = local.client_x_scaling
scheduled_action_name = "${each.key}-scheduled-scaling-up-client_x"
min_size = ceil(each.value.asg_min * each.value.client_x_scale)
max_size = -1
desired_capacity = -1
start_time = local.client_x_scale_date
autoscaling_group_name = each.value.name
}
The goal is to allow me to set the date time for an autoscaling rule without needing to come back after this code once the rule has been activated to remove the code. Essentially, build in an expiry date for the rule.
If the time has passed for when this rule is applicable, then don’t have the resource, thus deleting the rule from the state file.
At the moment I’m getting:
Error: Invalid for_each argument
on client-scaling.tf line 23, in resource "aws_autoscaling_schedule" "client_x_scaling_up":
23: for_each = local.client_x_scaling
The "for_each" value depends on resource attributes that cannot be determined
until apply, so Terraform cannot predict how many instances will be created.
To work around this, use the -target argument to first apply only the
resources that the for_each depends on.
If I remove the timestamp() check and put a hard-coded value there, things work appropriately. If my fake timestamp is before the due date, I get the resources in the plan. If it is after the due date, I do not get the resources in the plan.
So, with …
client_x_scale_required = (formatdate("YYYYMMDDhhmmss", "2020-07-29T14:35:32Z") <= formatdate("YYYYMMDDhhmmss", local.client_x_scale_date)) ? true : false
I get …
# aws_autoscaling_schedule.client_x_scaling_up["app"] will be created
+ resource "aws_autoscaling_schedule" "client_x_scaling_up" {
+ arn = (known after apply)
+ autoscaling_group_name = "asg-app - lc-app-20200729115620634100000002"
+ desired_capacity = -1
+ end_time = (known after apply)
+ id = (known after apply)
+ max_size = -1
+ min_size = 8
+ recurrence = (known after apply)
+ scheduled_action_name = "app-scheduled-scaling-up-client_x"
+ start_time = "2020-08-03T08:45:00Z"
}
# aws_autoscaling_schedule.client_x_scaling_up["wildcard"] will be created
+ resource "aws_autoscaling_schedule" "client_x_scaling_up" {
+ arn = (known after apply)
+ autoscaling_group_name = "asg-wildcard - lc-wildcard-20200729115620727100000004"
+ desired_capacity = -1
+ end_time = (known after apply)
+ id = (known after apply)
+ max_size = -1
+ min_size = 12
+ recurrence = (known after apply)
+ scheduled_action_name = "wildcard-scheduled-scaling-up-client_x"
+ start_time = "2020-08-03T08:45:00Z"
}
If I use …
client_x_scale_required = (formatdate("YYYYMMDDhhmmss", "2020-08-03T08:45:01Z") <= formatdate("YYYYMMDDhhmmss", local.client_x_scale_date)) ? true : false
1s after the required datetime, I don’t get any resources in the plan. And if they had existed, I would be expecting them to be deleted.
And so, achieving zero maintenance once the required date has been set.
Is there a way to achieve this sensibly
One horrible option is to put the current datetime into a variable as part of the pre-processing (something I’d rather not do as the pipeline has only terraform in play - no make or other scripting to keep the work down).
The main reason for this is that after the due date, the rule is invalid from AWS’s perspective and so the deployment fails. Which means, I have to be on top of all of these schedules every time one changes.
I’ve not properly mentioned the ongoing frustration of Daylight Savings Time in all of this. Solving that too would be immensely beneficial to my sanity!