欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 名人名企 > Terraform - 理解 Count 和 For_Each 循环

Terraform - 理解 Count 和 For_Each 循环

2025/4/20 5:18:56 来源:https://blog.csdn.net/weixin_39660059/article/details/147251017  浏览:    关键词:Terraform - 理解 Count 和 For_Each 循环

概述


使用 Terraform 时,您可能需要为同一资源创建多个实例。这时 count 和 for_each 循环就派上用场了。这些循环允许您创建具有相同配置但具有不同值的多个资源。本指南将讲解如何在 Terraform 中使用 count 和 for_each 循环。

Terraform 中的 Count


Terraform 中的 count 参数允许您创建指定数量的相同资源。它是资源块的组成部分,用于定义应创建特定资源的实例数量。

以下是 Terraform 中使用 count 的示例:

resource "azurerm_resource_group" "example" {count    = 3name     = "resourceGroup-${count.index}"location = "East US"tags = {iteration = "Resource Group number ${count.index}"}
}

在上面的示例中,我们使用 count 参数在 Azure 区域“美国东部”中创建了三个名称不同但相同的资源组。

优点:


易于使用:count 参数可直接创建资源的多个实例。
适用于同质资源:当您创建的所有资源除了标识符之外都相同时,count 可能是一个不错的选择。


缺点:


缺乏基于键的标识:count 不提供直接使用唯一键来寻址资源的方法;您必须依赖索引。
不可变:如果您从 count 列表中间删除一个项目,Terraform 会将所有后续资源标记为重新创建,这在某些情况下可能会造成中断。例如:假设您有一个 Terraform 配置,它使用 count 参数管理 Azure 中的一组虚拟机。假设您最初将 count 参数设置为 5,从而预配了 5 个虚拟机:

resource "azurerm_virtual_machine" "vm" {count               = 5name                = "vm-${count.index}"location            = "East US"resource_group_name = azurerm_resource_group.rg.namenetwork_interface_ids = [azurerm_network_interface.nic[count.index].id]# ... (other configuration details)
}

在上面的例子中,假设过了一段时间,您决定不再需要第二个虚拟机(“vm-1”,因为“count.index”从零开始)。要删除此虚拟机,您可以将计数更改为 4,并调整资源名称或索引,这在直观上似乎是正确的方法。

问题就在这里:Terraform 根据资源的索引来决定资源的创建和销毁。如果您只是删除或注释掉“vm-1”的定义,Terraform 将无法识别您确实想要销毁“vm-1”。它会认为从索引 1 开始的所有虚拟机(vm-1、vm-2、vm-3 和 vm-4)都应该被销毁并重新创建,因为它们的索引已更改。

这可能会造成一些破坏性后果:

停机:重新创建虚拟机会导致在其上运行的服务停机,这在生产环境中可能是不可接受的。
数据丢失:如果您未备份虚拟机上的本地数据,则在销毁并重建虚拟机时,这些数据将会丢失。
IP 地址变更:如果虚拟机分配了动态公网 IP,这些 IP 地址可能会发生变化,并可能导致连接问题。
成本:销毁并重建资源可能会产生不必要的成本,例如计算时间的消耗。

为了避免此类count问题,您需要使用 create_before_destroy 生命周期规则,或者考虑 for_each 是否是此类场景的更好选择,因为它提供了一种无需依赖序列即可唯一标识资源的方法。使用 for_each,每个虚拟机将单独管理,您可以移除与不需要的虚拟机对应的单个映射条目,从而只销毁该特定虚拟机,而不会影响其他虚拟机。

Terraform for_each 是什么?


Terraform for_each 是一个元参数,用于创建已定义资源的多个实例。它还使我们能够灵活地根据用于创建实际副本的变量类型,动态设置每个已创建资源实例的属性。

for_each 主要使用字符串集合 (set(string)) 和字符串映射 (map(string))。提供的字符串值用于设置特定于实例的属性。

例如,在创建多个子网时,我们可以为使用同一资源块创建的每个子网指定不同的 CIDR 范围。

当在资源块中使用 for_each 元参数时,会自动提供一个特殊对象 each 来引用由 for_each 创建的每个实例。each 对象用于引用集合中提供的值以及映射类型变量中提供的键值对。

如何在 Terraform 中使用 for each

使用 for_each 元参数的一般语法如下所示。

resource "<resource type>" "<resource name>" {for_each = var.instances// Other attributestags = {Name = each.<value/key>}
}

<resource type> 是 Terraform 资源的类型,例如“aws_vpc”。

<resource name> 是此资源的用户定义名称,用于在 Terraform 配置中的其他位置引用。for_each 属性被赋值为“var.instances”形式的变量值。“var.instances”可以是列表或映射类型。

根据此集合或映射的长度,将创建“<resource type>”类型的资源数量。

最后,each 对象用于为由此创建的每个资源实例分配一个名称标签。如果“var.instances”是集合类型,则“each.value”是唯一可用的属性。如果是映射类型,则可以使用 each.key 和 each.value 同时检索键和值。

在一些高级用例中,也可以将对象映射 (map(object)) 与 for_each 元参数一起使用。我们将在本文的后面部分介绍。

示例 1:使用 for_each 函数处理一组字符串


假设我们需要在 AWS 中创建特定数量的 EC2 实例。

需要创建的实例的具体数量取决于提供的输入。如果输入是“字符串数组”(就 Terraform 而言,即 set(string) )

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词