Terraform for_each - each.key 在哪里定义?

Posted

技术标签:

【中文标题】Terraform for_each - each.key 在哪里定义?【英文标题】:Terraform for_each - where is each.key defined? 【发布时间】:2021-05-12 03:43:18 【问题描述】:

预期行为

我试图更好地理解 for_each 循环

模块调用中定义的each.key值具体在哪里? 部署 1 个实例的示例是什么?然后是多个实例的示例? 请参阅下面的“模块调用(父模块)”

实际行为

不确定预期的结果

Terraform(和 AzureRM 提供程序)版本

受影响的资源

azurerm_v2.41.0 terraform v0.13.0

Terraform 配置文件

Main.tf

resource "azurerm_resource_group_template_deployment" "sql_mi" 
  for_each            = var.sql_mi_defaults
  
  name                = each.key # provide an example of how this is defined in module call?  # how would I deploy more than one instance?
  resource_group_name = var.resource_group_name
  deployment_mode     = var.deployment_mode
  template_content    = data.local_file.arm_template.content
  parameters_content  = <<PARAMETERS
     
        "managedInstanceName": 
            "value": "$each.value.managedInstanceName" 
        ,
        "location": 
            "value": "$var.location"
        ,
        "skuName": 
            "value": "$each.value.skuName"
        ,
        "storageSizeInGB": 
            "value": "$each.value.storageSizeInGB"
        ,
        "vCores": 
            "value": "$each.value.vCores"
        ,
        "licenseType": 
            "value": "$each.value.licenseType"
        ,
        "collation": 
            "value": "$each.value.collation"
        ,
        "timezoneId": 
            "value": "$each.value.timezoneId"
        ,
        "collation": 
            "value": "$each.value.collation"
        ,
        "proxyOverride": 
            "value": "$each.value.proxyOverride"
        ,
        "publicDataEndpointEnabled": 
            "value": "$each.value.publicDataEndpointEnabled"
        ,
        "administratorLogin": 
            "value": "azadmin-$random_string.mi_name.result"
        ,
        "administratorLoginPassword": 
            "value": "$random_password.admin.result"
        ,
        "managedInstanceTags": 
            "value": "$var.names.product_name-$var.names.service_name-$random_string.mi_name.result"
        ,
        "storageAccountType": 
            "value": "$each.value.storageAccountType"
        ,
        "virtualNetworkName": 
            "value": "$var.virtual_network_name"
        ,
        "virtualNetworkResourceGroupName": 
            "value": "$var.resource_group_name"
        ,
    
    PARAMETERS

Variables.tf

variable sql_mi_defaults 
  type = any
  default = 
    managedInstanceName        = "randomcomputername"
    location                   = "eastus2"
    skuName                    = "Standard_F2"
    storageSizeInGB            = 256
    vCores                     = 8
    licenseType                = "LicenseIncluded"
    collation                  = "SQL_Latin1_General_CP1_CI_AS"
    timezoneId                 = "UTC"
    proxyOverride              = "Proxy"
    publicDataEndpointEnabled  = false
    minimalTlsVersion          = "1.2"
    administratorLogin         = "azadmin"
    administratorLoginPassword = ""
    managedInstanceTags        = ""
    storageAccountType         = "GRS"

  
  description = <<EOT
azure sql managed instance settings (only applied to virtual machine settings managed within this module)
    managedInstanceName             = (Required) The name of the Managed Instance.
    location                        = (Required) The location of the Managed Instance
    skuName                         = (Required) Managed instance SKU. If SKU is not set, skuEdition and hardwareFamily values have to be populated."
    storageSizeInGB                 = (Required) Determines how much Storage size in GB to associate with instance. Increments of 32 GB allowed only.
    vCores                          = (Required) The number of vCores.
    licenseType                     = (Optional) Determines license pricing model. Select 'LicenseIncluded' for a regular price inclusive of a new SQL license. Select 'Base Price' for a discounted AHB price for bringing your own SQL licenses.
    collation                       = (Optional) Specifies the priority of this Virtual Machine. Possible values are Regular and Spot. Defaults to Regular. Changing this forces a new resource to be created.
    timezoneId                      = (Optional) Specifies what should happen when the Virtual Machine is evicted for price reasons when using a Spot instance. At this time the only supported value is Deallocate. Changing this forces a new resource to be created. This can only be configured when priority is set to Spot.
    proxyOverride                   = (Optional) Determines connection type for private endpoint. Proxy connection type enables proxy connectivity to Managed Instance. Redirect mode enables direct connectivity to the instance resulting in improved latency and throughput.
    publicDataEndpointEnabled       = (Optional) Determines whether public data endpoint will be enabled, required for clients outside of the connected virtual networks. Public endpoint will always default to Proxy connection mode.
    administratorLogin              = (Required) The login of the Managed Instance admin.
    administratorLoginPassword      = (Required) The password of the Managed Instance admin.
    managedInstanceTags             = (Optional) Resource tags to associate with the instance.
    storageAccountType              = (Required) Option for configuring backup storage redundancy. Selecting 'GRS' will enable 'RA-GRS'.
    virtualNetworkName              = (Required) The virtual network name. Leave empty for the default value.
    virtualNetworkResourceGroupName = (Required) The resource group where the networking resources will be created or updated. Default is the same resource group as Managed Instance.
EOT 


模块调用(父模块)

# azurerm_sql_managed_instance see for more info https://docs.microsoft.com/en-us/azure/azure-sql/managed-instance/sql-managed-instance-paas-overview
module "sql_mi" 
  source = "github.com/[redacted]/azurerm-sql-managed-instance.git?ref=v2.3.1""

  resource_group_name  = module.resource_group.name
  location             = module.resource_group.location
  deployment_mode      = "Complete"
  virtual_network_name = module.virtual_network.subnet_nsg_names["iaas-outbound"]

  name = "example-output-from-each.key" # will the name of the instance be from each.key?

【问题讨论】:

【参考方案1】:

这个:

for_each    = var.sql_mi_defaults

告诉 Terraform 获取 var.sql_mi_defaults 中的任何集合,并为该集合中的每个项目创建一个 azurerm_resource_group_template_deployment 资源。它会自动公开资源块范围内的each.keyeach.value 属性。这都记录在here。


部署 1 个实例的示例是什么?

将大小为 1 的集合作为 var.sql_mi_defaults 传递

然后是多个实例的示例?

将大小 > 1 的集合作为var.sql_mi_defaults 传递

【讨论】:

感谢您抽出宝贵时间做出贡献。我知道 each.value 将遍历项目列表,直到找到所需的值(例如:each.value.skuName) 但是我不确定在哪里定义了 each.key 输入?您能否指出更多示例的方向? “我知道 each.value 将遍历项目列表,直到找到所需的值”不正确。请阅读我链接到的文档。 所以在上面的例子中,each.value.skuName 不会引用名为 skuName 的 var.sql_mi_defaults 变量输入?这就是我所说的 for_each 将迭代直到找到定义的值。 在找到某些东西之前不会进行迭代。它遍历一个列表,并为列表中的每个值创建一个新资源。这里没有发生“搜索”或“发现”。如果var.sql_mi_default 是一个包含 3 个项目的列表,则将创建 3 个资源。定义迭代的是for_eacheach.value 只是指当前迭代中的当前值。 不,each.key 只是引用 var.sql_mi_defaults 集合中的每个键,因为 for_each 迭代该集合。该代码 sn-p 中没有任何内容表明它引用了一个名为“default”的值,所以我不确定你为什么这么认为。您需要在您的问题中包含var.sql_mi_defaults 的定义,以便我对此进行更多扩展。通过查看 terraform plan 输出,您还应该能够轻松地看到这是在做什么。

以上是关于Terraform for_each - each.key 在哪里定义?的主要内容,如果未能解决你的问题,请参考以下文章

Terraform : for_each 一个一个

将 aws 资源导入具有 for_each 的 terraform 模块

Terraform for_each - each.key 在哪里定义?

如何在 terraform 中正确使用 for_each 中的 each.value?

使用 terraform 在 for_each 嵌套资源中循环

Terraform 模块输出用作其他模块中的输入,特别是 for_each