Terraform Try for Argument 存在

Posted

技术标签:

【中文标题】Terraform Try for Argument 存在【英文标题】:Terraform Try for Argument existence 【发布时间】:2021-08-05 19:53:40 【问题描述】:

我们已经为给定的模块定义了变量。这是一个样本

    variable "kv_name_solution"  
    variable "kv_name_seqnr"  
    variable "kv_name_purpose"  
...    
    variable "location_name"  default = "Europe" 
    variable "location_tier"  default = "Primary"   
    variable "rg_name_solution"  default = "edw"
    variable "rg_name_seqnr"  default = "001"

在我们的 tfvars 中准备了很多 kv。 所以在模板中我们使用这段代码

module "kv_create" 
  for_each = var.resources_kv
  source = "../../_modules/security/kv_create"

  kv_name_solution        = each.value["kv_name_solution"]
  kv_name_seqnr           = each.value["kv_name_seqnr"]
  kv_name_purpose         = each.value["kv_name_purpose"]
...
  location_name        = each.value["location_name"]
  location_tier        = each.value["location_tier"]
  rg_name_solution     = each.value["rg_name_solution"]
  rg_name_seqnr        = each.value["rg_name_seqnr"]

但是,我试图找到一种方法,例如在 tfvars 中省略 rg_name_solution 和 rg_name_seqnr 时,for_each 中的代码仍然有效。 一直在用 try 搜索,但目前还没有找到。

因为location_name = try(each.value["location_name"], null) 似乎取消了我对变量的默认设置。

有什么建议吗?

这些是“完整的文件”

terraform.tfvars

rg_resources = 
        "edw-common" = 

                rg_name_solution        = "edw"
                rg_name_seqnr           = "001"

                rg_location_name        = "Europe"
                rg_location_tier        = "Primary"
        


kv_resources = 
        "adf-001" = 
                kv_name_solution        = "edw"
                kv_name_seqnr           = "001"
                kv_name_purpose         = "adfxx"

                

main.tf

....
module "provision_keyvaults" 
  count     = (var.MODULE == "KV") || ((var.MODULE == "ALL" && var.APPLY == "false")) ? 1 : 0
  source    = "./_templates/kv"

  resources_kv = var.kv_resources

....

模板\kv\main.tf

module "kv_create" 
  for_each = var.resources_kv
  source = "../../_modules/security/kv_create"

  kv_location_name        = try(each.value["kv_location_name"],null)
  kv_location_tier        = try(each.value["kv_location_tier"],null)

  kv_name_solution        = each.value["kv_name_solution"]
  kv_name_seqnr           = each.value["kv_name_seqnr"]
  kv_name_purpose         = each.value["kv_name_purpose"]

  rg_name_solution        = try(each.value["rg_name_solution"],null)
  rg_name_seqnr           = try(each.value["rg_name_seqnr"],null)

 

模板\kv\variables.tf

variable "resources_kv"  

_modules\kv_create\variables.tf

variable "kv_location_name" 
                              default = "Europe"
                            
variable "kv_location_tier" 
                              default = "Primary"
                            

variable "kv_name_solution"  
variable "kv_name_seqnr"  
variable "kv_name_purpose"  

variable "rg_name_solution" 
                              default = "edw"
                            
variable "rg_name_seqnr" 
                           default = "001"
                         

_modules\kv_create\main.tf

module "subscription" 
  source = "../../general/subscription_getdetails"


module "kv_location" 
  source = "../../general/location_getdetails"
  location_name = var.kv_location_name
  location_tier = var.kv_location_tier


module "resourcegroup" 
  source = "../../general/rg_getdetails"
  rg_name_solution = var.rg_name_solution
  rg_name_seqnr    = var.rg_name_seqnr


data "azurerm_client_config" "current" 

resource "azurerm_key_vault" "kv" 
  count                       = var.kv_provision ? 1 : 0

  name                        = "kv-$module.kv_location.sitecode-$module.subscription.environment-$var.kv_name_solution-$var.kv_name_seqnr-$var.kv_name_purpose"

....

  resource_group_name         = module.resourcegroup.rg.name
  location                    = module.kv_location.azure
...

最后,错误

╷
│ Error: Invalid template interpolation value
│ 
│   on _modules/general/rg_getdetails/main.tf line 18, in data "azurerm_resource_group" "rg":
│   18:   name = "rg-$module.subscription.environment-$var.rg_name_solution-$var.rg_name_seqnr"
│     ├────────────────
│     │ var.rg_name_solution is null
│ 
│ The expression result is null. Cannot include a null value in a string
│ template.
╵

【问题讨论】:

var.resources_kv的例子是什么? kv_resources = "adf-001" = ​​ kv_name_solution = "edw" kv_name_seqnr = "001" kv_name_ purpose = "adfxx" ... , 它是来自 tfvars 的映射(对象),其中包含(在本例中为要创建的 key-vaults。 进展如何?还是不清楚该怎么做? 【参考方案1】:

如果没有明确给出,我只会使用lookup 来提供默认值。例如:

  kv_name_solution        = lookup(each.value, "kv_name_solution", var.kv_name_solution)
  kv_name_seqnr           = lookup(each.value, "kv_name_seqnr", var.kv_name_seqnr)
  kv_name_purpose         = lookup(each.value, "kv_name_purpose", var.kv_name_purpose)

【讨论】:

谢谢提示!!

以上是关于Terraform Try for Argument 存在的主要内容,如果未能解决你的问题,请参考以下文章

Terraform:来自yaml的嵌套for循环

具有下游依赖项的 Terraform 条件“for_each”

Terraform : for_each 一个一个

Terraform 嵌套 for 循环

Code as IaaS for Azure : Terraform 初步

Terraform Collaboration for Everyone