Quantcast
Channel: Terraform - HashiCorp Discuss
Viewing all articles
Browse latest Browse all 11361

Getting the "The "for_each" value depends on resource attributes that cannot be determined until apply, so Terraform ..." error

$
0
0

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!

5 posts - 3 participants

Read full topic


Viewing all articles
Browse latest Browse all 11361

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>