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

标签 terraform terraform-provider-aws

我有一个案例,如果用户不提供 vpc id,我必须创建一个 aws_vpc 资源。之后,我应该使用该 VPC 创建资源。

现在,我在创建 aws_vpc 时应用条件资源。例如,只有在 existing_vpc 时才创建 VPC是假的:

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

接下来,例如,我必须在 VPC 中创建节点。如果existing_vpc是真的,使用 var.vpc_id ,否则使用来自 aws_vpc 的计算出的 VPC ID资源。

但是,问题是,如果 existing_vpc是真的,aws_vpc不会创建新资源,并且三元条件无论如何都会尝试检查 aws_vpc资源是否正在创建。如果它没有被创建,则 terraform 错误。

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}"

如果两者都相互依赖,我们如何创建条件资源并根据它们为其他配置分配值?

最佳答案

以下示例显示如何选择性地指定是否创建资源(使用条件运算符),并显示如何在未创建资源时处理返回的输出。这恰好是使用模块完成的,并使用 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 - 如何在条件运算符中使用有条件创建的资源的输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56257169/

相关文章:

amazon-web-services - Terraform 无法承担启用 MFA 的角色

amazon-web-services - Terraform 多个 s3 存储桶创建

Terraform Azure - 对资源类型的引用必须后跟至少一个属性访问,指定资源名称

postgresql - RDS升级postgres 13.1版,不支持的DB Instance Class

azure terraform 将 azure 文件共享附加到 Windows 计算机

terraform - 子模块不继承提供者

amazon-web-services - terraform 销毁后保留资源

amazon-ec2 - 如何通过 terraform 获取现有 ec2 实例的实例 ID/arn?

amazon-web-services - 你如何忽略 Terraform 中的嵌套字段?

aws-cloudformation - CloudFormation 是否目标名称或资源?