Terraform:使用合理的对象填充对象,然后部分覆盖?

时间:2019-06-20 14:33:30

标签: terraform

我正在寻找一种具有“对象”类型的变量(强制某种结构),然后覆盖某些部分的方法。考虑以下变量声明:

variable "prod_vpc" {
  type = object({
        name = string,
        region = string,
        single_nat_gw = bool,
        create = bool,
        supernet = string
    })

  default = {
    name = "PROD"
    region = "eu-central-1"
    single_nat_gw = true
    create = false,
    supernet = "0.0.0.0/0"
  }
}

在这种情况下,我可能想在auto.tfvars中使用它:

prod_vpc = {
    create = true,
    supernet = "10.0.8.0/24"
}

因为所有其他值都很好。我能想到的唯一方法是在本地块中使用type = map(string)和条件句,即:

variable "vpc_defaults" {
  type = object({
        name = string,
        region = string,
        single_nat_gw = bool,
        create = bool,
        supernet = string
    })

  default = {
    name = "PROD"
    region = "eu-central-1"
    single_nat_gw = true
    create = false,
    supernet = "0.0.0.0/0"
  }
}


variable "prod_vpc" {
  type = map(string)
  default = {}
}

然后

prod_vpc = {
    create = true,
    supernet = "10.0.8.0/24"
}

然后:

locals {
    create = coalesce(var.prod_vpc["create"], vpc_defaults.create)
}

(我还没有尝试过,但是我认为应该遵循这些原则)

还有其他用于预定义默认值并且仅在需要时才覆盖的想法吗?

致谢

橡胶

1 个答案:

答案 0 :(得分:1)

即使您使用的是普通地图而不是对象类型,也无法以这种方式执行此操作,并且推理在文档here中进行了说明。建议在那里使用locals来提供默认值,然后显式合并它们。

同时,正如James Bardin在this相关的GitHub问题中指出的那样,需要使用对象密钥来设置默认值。如果您希望将它们设置为null,则必须明确地将其设置为这样。

已添加詹姆斯:

  

您还可以选择将默认值设置为null(或没有默认值,并要求调用方设置一个值)。但是,在那种情况下,您需要避免将null对象传递到merge中,您可以使用条件或合并来做到这一点:

merged_map_keys = merge(local.default_map_keys, coalesce(var.prod_vpc, {}))

如果您可以执行以下操作,那将是

variable "prod_vpc" {
  type = object({
    name          = string,
    region        = string,
    single_nat_gw = bool,
    create        = bool,
    supernet      = string
  })
  default = {}
}

locals {
  default_map_keys = {
    name          = "PROD"
    region        = "eu-central-1"
    single_nat_gw = true
    create        = false,
    supernet      = "0.0.0.0/0"
  }
  merged_map_keys = merge(local.default_map_keys, var.prod_vpc)
}

然后您可以通过以下方式调用它:

prod_vpc = {
  create   = true,
  supernet = "10.0.8.0/24"
}

GitHub公开问题中有更多信息。