filczek
filczek

Reputation: 25

Terraform using random provider with count in module

I am having child module for Windows virtual machine. Then I have root module (main.tf file), where I am using that child module

module "vm-win-resource" {
  source = "./Modules/ServerWindows"

  count         = 2
  vm-name       = "vm-win-${random_string.rnd.result}" #OR "vm-win-${module.rnd-num.rnd-result}"
  vm-rg         = module.rg-resouce.rg-name
  vm-location   = module.rg-resouce.rg-location
  nic-name      = "vm-win-${random_string.rnd.result}-nic1" #OR "vm-win-${module.rnd-num.rnd-result}-nic1"
  nic-rg        = module.rg-resouce.rg-name
  nic-location  = module.rg-resouce.rg-location
  nic-ip-subnet = "HERE IS SUBNET ID"
}

In same main.tf file, if I use random_string provider directly

resource "random_string" "rnd" {
  length      = 4
  min_numeric = 4
  special     = false
  lower       = true
}

or if I create module, for random number and use it in module for virtual machine, result is same.

module "rnd-num" {
  source = "./Modules/RandomNumber"
}

I get same name (generated number for both)

 + vm-win-name = [
      + [
          + "vm-win-6286",
          + "vm-win-6286",
        ],
    ]

So in both cases, value is generated only once.

Question is how can I generate random number for every loop in module for virtual machine?

Thank you for any help!

UPDATE As workaround, I have placed provider to generate random number into virtual machine resource/module specification

resource "azurerm_windows_virtual_machine" "vm-resource" {
  name                = "${var.vm-name}-${random_string.rnd.result}"
  resource_group_name = var.vm-rg
  location            = var.vm-location
  size                = var.vm-size
  admin_username      = var.vm-admin
  admin_password      = var.vm-adminpwd
  network_interface_ids = [
    azurerm_network_interface.nic-resource.id,
  ]

  os_disk {
    caching              = "ReadWrite"
    storage_account_type = var.vm-os-disk-type
  }

  source_image_reference {
    publisher = var.vm-os-image.publisher
    offer     = var.vm-os-image.offer
    sku       = var.vm-os-image.sku
    version   = var.vm-os-image.version
  }

  tags = var.resource-tags
}

resource "random_string" "rnd" {
  length      = 4
  min_numeric = 4
  special     = false
  lower       = true
}

it does the job but I would prefer to use it in main.tf file and not directly in resource/module specification, if it is possible.

Upvotes: 2

Views: 2924

Answers (1)

Ervin Szilagyi
Ervin Szilagyi

Reputation: 16775

A few words about how Terraform random_string works:

  • random_string generates a random string from specific characters. This string is generated once. Referencing its result attribute in multiple places will provide you the same output. Using it as random_string.rnd.result will not act as a function call, this means that it will provide the same value in every place.
  • The result value of a random_string will not change after consecutive applies. This is obvious, if we think about it. If it would change, the usage of random_string would be dangerous, since it would result in re-provisioning the resources which are referencing it.

If we want to have multiple different random strings, we have to define multiple random_string resources. For example:

resource "random_string" "rnd" {
  count       = 2
  length      = 4
  min_numeric = 4
  special     = false
  lower       = true
}

module "vm-win-resource" {
  source = "./Modules/ServerWindows"

  count         = 2
  vm-name       = "vm-win-${random_string.rnd[count.index].result}"
  vm-rg         = module.rg-resouce.rg-name
  vm-location   = module.rg-resouce.rg-location
  nic-name      = "vm-win-${random_string.rnd[count.index].result}-nic1"
  nic-rg        = module.rg-resouce.rg-name
  nic-location  = module.rg-resouce.rg-location
  nic-ip-subnet = "HERE IS SUBNET ID"
}

Please note, we are using a count for the random_string resource as well.

Upvotes: 3

Related Questions