Terraform - 如何在条件运算符中使用条件创建的资源的输出?



我有一种情况,如果用户不提供VPC ID,则必须创建AWS_VPC资源。之后,我应该使用该VPC创建资源。

现在,在创建aws_vpc资源时,我正在应用条件。例如,仅在existing_vpc为false时创建VPC:

count                = "${var.existing_vpc ? 0 : 1}"

下一步,我必须在VPC中创建节点。如果existing_vpc为TRUE,请使用var.vpc_id,否则使用aws_vpc资源中计算的VPC ID。

但是,问题是,如果existing_vpc为真,则aws_vpc不会创建新资源,并且无论如何,三元条件是试图检查aws_vpc资源是否正在创建。如果没有创建,则会出现错误。

aws_subnet上使用条件操作员时,该错误的示例:

Resource 'aws_subnet.xyz-subnet' not found for variable 'aws_subnet.xyz-subnet.id'

导致错误的代码为:

subnet_id = "${var.existing_vpc ? var.subnet_id : aws_subnet.xyz-subnet.id}"

如果这两个事物彼此取决于彼此,我们如何创建条件资源并根据它们分配值?

您可以按以下方式访问动态创建的模块和资源

output "vpc_id" {
  value = length(module.vpc) > 0 ? module.vpc[*].id : null
}
  • 如果计数= 0,输出为null
  • 如果count>0,输出是VPC ID的列表

如果 count = 1 ,并且您想接收一个可以指定的VPC ID:

output "vpc_id" {
  value = length(module.vpc) > 0 ? one(module.vpc).id : null
}

以下示例显示了如何可选地指定是否创建资源(使用条件运算符(,并显示在未创建资源时如何处理返回输出。这恰好是使用模块完成的,并使用object变量元素作为标志来指示是否应创建资源。

但要专门回答您的问题,您可以使用条件运算符如下:


    output "module_id" {
       value = var.module_config.skip == true ? null : format("%v",null_resource.null.*.id)
    }

并访问呼叫main.tf中的输出:

module "use_conditionals" {
    source = "../../scratch/conditionals-modules/m2" # << Change to your directory
    a = module.skipped_module.module_id # Doesn't exist, so might need to handle that.
    b = module.notskipped_module.module_id
    c = module.default_module.module_id
}

完整示例如下。注意:这是使用Terraform V0.14.2


# root/main.tf
provider "null" {}
module "skipped_module" {
    source = "../../scratch/conditionals-modules/m1" # << Change to your directory
    module_config = { 
        skip = true         # explicitly skip this module.
        name = "skipped" 
    }
}
module "notskipped_module" {
    source = "../../scratch/conditionals-modules/m1" # << Change to your directory
    module_config = { 
        skip = false        # explicitly don't skip this module.
        name = "notskipped"
    }
}
module "default_module" {
    source = "../../scratch/conditionals-modules/m1" # << Change to your directory
    # The default position is, don't skip. see m1/variables.tf
}
module "use_conditionals" {
    source = "../../scratch/conditionals-modules/m2" # << Change to your directory
    a = module.skipped_module.module_id
    b = module.notskipped_module.module_id
    c = module.default_module.module_id
}
# root/outputs.tf
output skipped_module_name_and_id {
    value = module.skipped_module.module_name_and_id
}
output notskipped_module_name_and_id {
    value = module.notskipped_module.module_name_and_id
}
output default_module_name_and_id {
    value = module.default_module.module_name_and_id
}

模块


# m1/main.tf
resource "null_resource" "null" {
    count = var.module_config.skip ? 0 : 1 # If skip == true, then don't create the resource.
    provisioner "local-exec" {
        command = <<EOT
        #!/usr/bin/env bash
        echo "null resource, var.module_config.name: ${var.module_config.name}"
EOT
    }
}
# m1/variables.tf
variable "module_config" {
    type = object ({ 
        skip = bool, 
        name = string 
    })
    default = {
        skip = false
        name = "<NAME>"
        }
}
# m1/outputs.tf
output "module_name_and_id" {
   value = var.module_config.skip == true ? "SKIPPED" : format(
      "%s id:%v",
      var.module_config.name, 
      null_resource.null.*.id
   )
}
output "module_id" {
      value = var.module_config.skip == true ? null : format("%v",null_resource.null.*.id)
}

当您使用更现代版本的Terraform时,此处的当前答案会有所帮助,但是正如OP所指出的那样,当您与Terraform&lt合作时,它们不起作用;0.12(如果您像我一样,并且仍在处理这些较旧的版本,对不起,我会感到您的痛苦。(

请参阅Terraform项目中的相关问题,以获取有关较旧版本需要以下内容的更多信息。

但是,为避免链接腐烂,我将使用github问题中的答案使用ops示例subnet_id参数。

subnet_id = "${element(compact(concat(aws_subnet.xyz-subnet.*.id, list(var.subnet_id))),0)}"

从内而外:

  1. Concat将将SPLAT输出列表连接到列表(var.subnet_id( - 根据count = 0时," splat语法"时。扩展到空列表'
  2. 紧凑型将删除空项目
  3. 元素只有在紧凑的回收splat输出时才会返回您的var.subnet_id。

相关内容

  • 没有找到相关文章

最新更新