Equal attribution of value to objects with Terraform

67 views Asked by At

I would like your technical advice on the way to achieve a specific variable attribution with Terraform. Regardless of the context, I have n objects to which I would like to attribute a value between [1-3] so that the values are equally distributed (whether it is in a sequential or random way does not really matter).

To be more explicit here are the two ways I thought of :

  1. randomly selects starting value (1 or 2 or 3)
  2. selects the next index (if 2 were to be selected as starting value, 3 would be selected next)
  3. if there are 4 or more objects on total the loop should start over and over as long as there are remaining objects

OR

  1. randomly selects starting value (1 or 2 or 3)
  2. selects randomly any of the remaining value
  3. if there are 4 or more objects on total, randoms values would be selected so the global distribution would be equal

I can easily achieve the first step with the random provider, but I have no clue on how to proceed for the other steps. I mean I know how to increment a value, but how to proceed when the value is 3 and I want to start the loop over and come back to value 1 ? Or how to randomly select values between remaining ones ?

1

There are 1 answers

2
Helder Sepulveda On BEST ANSWER

sequential

You mentioned that the way doesn't really matter... I think in a sequential way is simpler, using range and a loop with a math trick (i % 3) + 1 to get the value between [1-3] like you want

variable "objects" {
  default = 12
}

locals {
    distrib = [ for i in range(var.objects) : (i % 3) + 1 ]
}

output "test" {
    value = local.distrib
}

a terraform plan on that:

Changes to Outputs:
  + test = [
      + 1,
      + 2,
      + 3,
      + 1,
      + 2,
      + 3,
      + 1,
      + 2,
      + 3,
      + 1,
      + 2,
      + 3,
    ]

sequential with random start

We can do a random start with the help of the random_integer resource and using the start and limit parameters in the range function

variable "objects" {
  default = 12
}

resource "random_integer" "extra" {
  min = 0
  max = 2
}

locals {
  start   = random_integer.extra.result
  distrib = [for i in range(local.start, var.objects + local.start) : (i % 3) + 1]
}

output "test" {
  value = local.distrib
}

random

Randomization is also possible using the random_shuffle resource:
https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/shuffle

variable "objects" {
  default = 12
}

locals {
    distrib = [ for i in range(var.objects) : (i % 3) + 1 ]
}

resource "random_shuffle" "random" {
  input        = local.distrib
  result_count = var.objects
}

output "test" {
    value = random_shuffle.random.result
}

and a terraform apply on that:

Apply complete! Resources: 1 added, 0 changed, 1 destroyed.

Outputs:

test = tolist([
  "3",
  "1",
  "3",
  "2",
  "2",
  "3",
  "1",
  "1",
  "2",
  "2",
  "1",
  "3",
])

more complex


We can also use other values instead of [1-3] see sample below using colors

variable "objects" {
  default = 9
}

variable "items" {
  default = ["red", "blue", "cyan"]
}

locals {
  distrib = [for i in range(var.objects) : element(var.items, (i % length(var.items)))]
}

resource "random_shuffle" "random" {
  input        = local.distrib
  result_count = var.objects
}

output "test" {
  value = random_shuffle.random.result
}