Relay70

Terraform Conditional Module Execution

An example of how to setup a conditional execution of a module in Terraform. In this Scenario there are two ProxMox modules. One creates a VM, the other creates an LXC. Terraform will prompt for a the machineType if it is not provided on the command line. It will then execute the appropriate module.
Reference:
https://github.com/relay70/terraform_proxmox
The above link is to the full Terraform code which contains this conditional execution.

Variables.tf

Configuration: variable.tf
variable "hosts" {
  description = "Host names"
  type        = list(string)
}

variable "machineType" {
  description = "VM or LXC"

  validation {
    condition     = var.machineType == "VM" || var.machineType == "LXC"
    error_message = "Need a machine type: VM or LXC"
  }

}
Explanation

The variables “hosts” {} block sets us up to give a list of host names to Terraform. Telling Terraform how many hosts to create, and what to call them. This will be used as a counter in the main.tf later.

This variable “machineType” {} block has two important features

  • It does NOT have a default value set. This will cause Terraform to prompt for the value.
  • The validation requires that the values be set to either “VM” or “LXC”. Terraform will error if it is not one of these values.

Main.tf

Configuration: main.tf
locals {
  isVM  = var.machineType == "VM" ? length(var.hosts) : 0
  isLXC = var.machineType == "LXC" ? length(var.hosts) : 0
}

module "proxmoxCreateVM" {
  source = "./modules/proxmoxCreateVM"
  count    = local.isVM
  hostname = var.hosts[count.index]
  ipaddress = "${module.phpipam[count.index].newIP.ip_address}/24"

}

module "proxmoxCreateLXC" {
  source = "./modules/proxmoxCreateLXC"
  count        = local.isLXC
  hostname     = var.hosts[count.index]
  ipaddress    = "${module.phpipam[count.index].newIP.ip_address}/24"
  rootPassword = data.vault_generic_secret.osInfo.data.rootP assword
}
Explanation
In Terraforms weird way, the locals block checks the value of var.machineType.  If it is VM then it sets isVM to the length of var.hosts (set in the variables section).  Otherwise it sets isVM to 0. It does the same for isLXC.  In this way one of them (isVM or isLXC) will always be set to 0.

Here is the Terraform docs for conditionals:
https://developer.hashicorp.com/terraform/language/expressions/conditionals

The next two modules execute in the same manner. Using count = local.isVM or isLXC it determines how many times it will execute this module. Since one of them will be set to 0, that module will be executed 0 times. So effectively ignored.

The other module that does not equal 0 will be executed however many times it needs to based on the value it received in the locals block from the length of the vars.hosts list.


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *