云服务器价格_云数据库_云主机【优惠】最新活动-搜集站云资讯

阿里云_空间虚拟主机_哪家好

小七 141 0

HashiCorp terraform0.12预览:For和For Each

这是本系列文章的第三篇,重点介绍terraform0.12中的新特性。作为TerraForm0.12发布前的一部分,我们将发布一系列功能预览博客文章。本周的文章是关于新的迭代特性:for表达式和for-u-each。0.11及更早版本的Terraform配置中的一个常见问题是处理由动态表达式而不是固定计数来决定值或资源的数量的情况。迭代的一般问题是一个需要解决的大问题,terraform0.12引入了一些不同的特性来提高这些能力,即表达式和每个块的性能。我们还将讨论以后的进一步增强。»用于列表和映射转换的表达式使用列表和映射时,通常需要对集合中的每个元素应用筛选器或转换,并生成新的集合。在terraform0.12之前,Terraform仅通过一些定制的插值函数(如formatlist)对此类操作的支持有限。terraform0.12引入了一个名为for expression的新构造,它允许通过转换和过滤另一个列表或映射中的元素来构造列表或映射。下面的示例显示了这一点的使用情况:#Terraform 0.12配置变量"vpc_id"{description="要创建安全组的AWS VPC的ID。"}变量"子网编号"{description="应授予访问权限的base_cidr_块的8位子网的列表。"默认值=[1,2,3]}数据"aws_vpc""示例"{id=变量vpc_id}资源"aws_security_group""示例"{name="友好的_子网"description="允许从友好子网访问"专有网络标识=变量vpc_id入口{从端口=0到端口=0协议=-1#对于子网编号中的每个编号,扩展#请求专有网络生成子网CIDR前缀。#上面的子网号码和VPC CIDR前缀的默认值#在10.1.0.0/16中,这将产生:#10.1.1.0/24","10.1.2.0/24","10.1.3.0/24"]cidr_块=[对于num in变量子网编号:cidrsubnet公司(数据.aws\u专有网络.example.cidr_块,8,数字)]}}如上所示,当for表达式用方括号([和])括起来时,结果是一个列表。用大括号({and})包装的for表达式以类似的方式生成映射。例如:#Terraform 0.12配置输出"实例私有ip地址"{#结果是从实例id到私有IP地址的映射,例如:#{"i-1234"="192.168.1.2","i-5678"="192.168.1.5"}值={例如在aws中_实例.示例:实例.id=> instance.private_ip实例}}可选的if子句也可用于筛选输入集合,以便结果只包含输入项的子集:#Terraform 0.12配置输出"实例公共ip地址"{值={例如在aws中_实例.示例:实例.id=> 实例.public如果instance.associate_public_ip_地址}}最后,for表达式的map表单有一个分组模式,在这种模式下,map键用于将项分组到每个不同键的列表中。此模式通过在值表达式后放置省略号(…)来激活:#Terraform 0.12配置输出"实例按可用性分区"{#结果是从可用区域到实例ID的映射,例如:#{"us-east-1a":i-1234,"i-5678"]}值={例如在aws中_实例.示例:instance.availability_区域=> 实例.id...}}在上面的例子中,我们展示了一个设置了count的资源现在也表现为一个列表,允许aws的所有实例_实例.示例迭代以生成按可用性区域分组。这些新表达式可用于为任何需要列表或映射表达式的参数生成值。在terraform0.12中,这包括接受列表或地图的任何位置,包括模块输入。»动态嵌套块一些资源类型使用嵌套的配置块来定义其配置的可重复部分。terraform0.12引入了一个新的构造,用于动态构造嵌套配置块的集合。例如,aws_autoscaling_组资源类型使用嵌套块来声明标记,这些标记可能会传播到任何创建的EC2实例中,也可能不会。下面的示例显示Terraform 0.11和更早版本的语法:#Terraform 0.11及更早版本的配置资源"aws_autoscaling_group""示例"{# ...标签{key="名称"value="示例asg名称"在启动时传播_=false}标签{key="组件"value="用户服务"在启动时传播_=true}标签{key="环境"value="生产"在启动时传播_=true}}因为这些嵌套块是静态验证的,所以以前很难或不可能实现更动态的行为。一些用户找到了一些方法来利用一些实现细节来诱骗Terraform部分地支持动态生成块,但是这些解决方法是不可靠的,因为Terraform对嵌套块进行了假设,而这些嵌套块不适用于任意表达式。terraform0.12引入了一个特殊的新的动态块构造,以一流的方式支持这些动态配置用例。转换为Terraform 0.12的相同示例:#Terraform 0.12配置当地人{标准标记={Component="用户服务"环境="生产"}}资源"aws_autoscaling_group""示例"{# ...标签{key="名称"value="示例asg名称"在启动时传播_=false}动态"标签"{对于每个=本地标准_标记内容{键=标签键值=标签值在启动时传播_=true}}}一个动态的"tag"块的行为就好像为for_each参数中给定的列表或映射的每个元素编写了一个单独的标记块。因为dynamic本身是作为嵌套块给出的,所以可以在其内容块中使用所有相同的语法构造,而这些内容块通常在文本标记块中有效,并且静态和动态标记块可以混合使用,如上所示。这可以根据需要实现任意复杂的行为。由于for_each参数接受任何列表或映射表达式,因此可以将此功能与如上所述的for表达式结合起来,根据其他列表和映射值的任意转换创建嵌套块:#Terraform v0.12配置可变"子网"{默认值=[{名称="a"数字=1},{name="b"数字=2},{名称="c"数字=3},]}当地人{base_cidr_block="10.0.0.0/16"}资源"azurerm_virtual_network""示例"{name="示例网络"resource_group_name=azurerm_资源_组.test.name地址空间=[local.base_cidr_块]location="美国西部"动态"子网"{for\u each=[子网中的s:{名称=s.name前缀=cidrsubnet(local.base_cidr_块,4,序号)}]内容{名称=子网.值.名称地址前缀=子网.值.前缀}}}Terraform能够以验证静态块的方式验证内容块中的参数,即使for_each表达式的值还不知道。因此,这种方法允许在计划时间,在采取任何实际行动之前,发现更多的问题。我们仍然建议您避免编写过于抽象、动态的配置作为一般规则。这些动态特性在创建可重用模块时非常有用,但是过度使用动态行为会损害可读性和可维护性。显性优于隐性,直接优于间接。»每个人的资源前面描述的动态块构造包含使用for峎each参数迭代列表或映射的思想,与资源上的count参数相比,这是创建动态嵌套块的更直观和有用的方法。在TerraForm0.12的开发过程中,我们还为直接在资源或数据块中支持_each打下了基础,这是为列表或地图中的每个元素创建资源实例的一种更方便的方法。不幸的是,我们无法在terraform0.12的初始版本中完全完成这个特性,但是我们计划在随后的版本中包含这个特性,以便更容易地基于给定映射的元素动态构建同一类型的多个资源实例。下面的示例显示了初始0.12版本中未包含的未来Terraform语法:#计划在v0.12.0之后发布变量"子网编号"{description="从可用区域映射到每个可用区域的子网应使用的编号"默认值={"eu-west-1a"=1"eu-west-1b"=2"eu-west-1c"=3}}资源"aws_vpc""示例"{# ...}资源"aws_subnet""示例"{对于每个=变量子网编号vpc_id=aws_vpc.example.id可用性区=每个.keycidr_block=cidrsubnet(aws_vpc.example.cidr_块八岁,每个值)}每个新对象都有属性每个.key以及每个值,将允许访问for_each表达式中每个元素的键和值,方法与计数.索引对于count参数。当foreach参数值是一个map时,Terraform将通过map元素的字符串键而不是数字索引来标识每个实例,这将避免当前使用count遍历一个列表的模式的许多限制,在该列表中可以添加和删除项,从而更改后续的索引。虽然我们不能在最初的terraform0.12版本中及时完成这个特性,但是Terraform将考虑参数n