Terraform中处理可选资源数组的正确方式

75次阅读
没有评论

问题描述

在我们的一个Terraform模块中,我们有一个变量,用于可选地创建一个负载均衡器。作为其中的一部分,我们创建了一些子网,代码如下所示:

resource "aws_subnet" "subnet_loadbalancer" {
  count             = var.create_loadbalancer ? length(var.az_names) : 0
  vpc_id            = aws_vpc.vpc_main.id
  cidr_block        = var.lb_subnet_cidrs[count.index]
  availability_zone = var.az_names[count.index]
}

现在,如果我们创建了负载均衡器,我想将第一个子网输出供以后在其他模块中使用,代码如下所示:

output "primary_LB_Subnet" {
  value = aws_subnet.subnet_loadbalancer[0]
}

这在创建负载均衡器时是没问题的,但如果var.create_loadbalancerfalse,就会出现以下错误:

Error: Invalid index on ..\..\modules\vpc\loadbalancer.tf line 19, in output "primary_LB_Subnet":
19:   value = aws_subnet.subnet_loadbalancer[0]    
|----------------    
| aws_subnet.subnet_loadbalancer is empty tuple
The given key does not identify an element in this collection value.

我可以理解为什么会出现这个问题,因为我们还没有创建子网。因此,我最初的想法是进行类似以下的处理:

output "loadbalancer_sg_id" {
  value = var.create_loadbalancer ? aws_subnet.subnet_loadbalancer[0] : null
}

但这并没有解决问题,我仍然遇到相同的错误。在Terraform中,如何正确处理这个问题呢?

解决方案

请注意以下操作注意版本差异及修改前做好备份。

在Terraform中正确处理这个问题的方法是使用try类型转换函数对value进行包装。try函数可以在引用可能不存在的索引或属性时,提供一个默认值以避免错误。以下是解决方案步骤:

步骤1

在你的Terraform代码中,对输出的value使用try函数,如下所示:

output "primary_LB_Subnet" {
  value = try(aws_subnet.subnet_loadbalancer[0], null)
}

在这个例子中,try函数会尝试获取aws_subnet.subnet_loadbalancer[0],如果该索引不存在(即aws_subnet.subnet_loadbalancer为空),则会返回null

这样,在var.create_loadbalancerfalse时,Terraform不会再尝试访问不存在的索引,而是直接返回null

步骤2

执行terraform apply命令来应用这个变更。

通过以上步骤,你就能够正确地在Terraform中处理可选资源数组的情况,并避免由于索引不存在而引起的错误。

总之,使用try函数是在Terraform中处理可能不存在的资源索引或属性时的一种良好实践,它能够有效地提高代码的健壮性和可维护性。

希望这个解决方案能够帮助你在Terraform项目中解决类似的问题!

正文完