Terraform 使用基于用户输入的动态变量值

Terraform using dynamic variable values based on user input

地形专家,

请建议如何根据用户提供的变量使用不同的预配置变量(最好是地图)。

例如,用户执行terraform apply -var="dc=dc1" 并且 terraform 使用为 dc1 指定的 vsphere 变量(服务器、凭据、虚拟机名称等)。

目前我试过这个代码:

# Variable for dc provided by user
variable "vsphere" {
  type        = string
  description = "VSphere DC: dc1 or dc2"

  validation {
    condition     = var.dc == "dc1" || var.dc == "dc2"
    error_message = "The dc value must be dc1 or dc2"
  }
}

# Provide dc details based on user input
variable "vsphere_data" {
  type = map(string)

  default = {
    user       = "terraform"
    password   = ""
    server     = var.vsphere_dc == "dc1" ? "vcenter" : "vcenter2"
    host_ip    = var.vsphere_dc == "dc1" ? "192.168.1.1" : "192.168.2.1"
    datacenter = var.vsphere_dc == "dc1" ? "DC1" : "DC2"
    datastore  = var.vsphere_dc == "dc1" ? "dc1-ssd" : "dc2-ssd"
    dvs        = var.vsphere_dc == "dc1" ? "dc1-dvs" : "dc2-dvs"
  }
}

# Provider
provider "vsphere" {
  user                 = var.vsphere_data.user
  password             = var.vsphere_data.password
  vsphere_server       = var.vsphere_data.server
}

但是当 运行 terraform validate 我遇到这个错误:

│ Error: Variables not allowed
│
│   on main.tf line 22, in variable "vsphere_data":
│   22:     datacenter = var.vsphere_dc == "dc1" ? "DC1" : "DC2"
│
│ Variables may not be used here.

请指教如何更好地实施这种情况以及为什么我会遇到此错误?是locals还是去掉三元运算就可以解决上面的场景?

使用 locals 而不是变量。

# Variable for dc provided by user
variable "vsphere" {
  type        = string
  description = "VSphere DC: dc1 or dc2"

  validation {
    condition     = var.vsphere == "dc1" || var.vsphere == "dc2"
    error_message = "The dc value must be dc1 or dc2."
  }
}

# Provide dc details based on user input
locals {
  vsphere_data = {
    user       = "terraform"
    password   = ""
    server     = var.vsphere == "dc1" ? "vcenter" : "vcenter2"
    host_ip    = var.vsphere == "dc1" ? "192.168.1.1" : "192.168.2.1"
    datacenter = var.vsphere == "dc1" ? "DC1" : "DC2"
    datastore  = var.vsphere == "dc1" ? "dc1-ssd" : "dc2-ssd"
    dvs        = var.vsphere == "dc1" ? "dc1-dvs" : "dc2-dvs"
  }
}

provider "vsphere" {
  user                 = local.vsphere_data.user
  password             = local.vsphere_data.password
  vsphere_server       = local.vsphere_data.server
}

您可以 运行 此代码的计划:

terraform plan -var="vsphere=dc1"

您的初始代码还有一些其他问题:

variable "vsphere" {
  type        = string
  description = "VSphere DC: dc1 or dc2"  

  validation {
    condition     = var.dc == "dc1" || var.dc == "dc2" # # THIS IS WRONG!!!
    error_message = "The dc value must be dc1 or dc2"
  }
}

为了验证一个变量,您不能引用另一个变量。验证应该只引用它自己。正确的是:

variable "vsphere" {
  type        = string
  description = "VSphere DC: dc1 or dc2"

  validation {
    condition     = var.vsphere == "dc1" || var.vsphere == "dc2"
    error_message = "The dc value must be dc1 or dc2."
  }
}

请注意,您不需要 var.dc 变量。

而且,你没有这个变量var.vsphere_dc。我认为这是一个错字或其他东西,否则就没有意义。是我们计算的局部值。