You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Terraform无法正确获取AWS带标签/无标签资源的唯一ID

如何用Terraform正确列出AWS带标签和无标签资源的唯一ID

问题场景

尝试用Terraform代码列出AWS中所有带标签和无标签资源,但执行后输出的资源ID均为"aws",而非实际资源的唯一ID。

原代码(main.tf)

data "aws_resourcegroupstaggingapi_resources" "tagged_resources" {
  tag_filter {
    key    = "*"
    values = ["*"]
  }
}

data "aws_resourcegroupstaggingapi_resources" "untagged_resources" {
  tag_filter {
    key    = " "
    values = [" "]
  }
}

resource "terraform_data" "print_resources" {
  count = length(data.aws_resourcegroupstaggingapi_resources.tagged_resources.id) + length(data.aws_resourcegroupstaggingapi_resources.untagged_resources.id)

  triggers_replace =  {
    always_run = timestamp()
  }

  provisioner "local-exec" {
     command = <<-EOT
       echo "Resource ID for tagged resources : ${element(data.aws_resourcegroupstaggingapi_resources.tagged_resources[*].id,count.index)} and Resource ID for untagged resources : ${element(data.aws_resourcegroupstaggingapi_resources.untagged_resources[*].id,count.index)}"
       
     EOT
  }
}

output "tagged_resources_ids" {
  value = data.aws_resourcegroupstaggingapi_resources.tagged_resources[*].id
}

执行输出

data.aws_resourcegroupstaggingapi_resources.untagged_resources: Reading...
data.aws_resourcegroupstaggingapi_resources.tagged_resources: Reading...
data.aws_resourcegroupstaggingapi_resources.tagged_resources: Read complete after 1s [id=aws]
data.aws_resourcegroupstaggingapi_resources.untagged_resources: Read complete after 1s [id=aws]

Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # terraform_data.print_resources[0] will be created
  + resource "terraform_data" "print_resources" {
      + id               = (known after apply)
      + triggers_replace = {
          + always_run = (known after apply)
        }
    }

  # terraform_data.print_resources[1] will be created
  + resource "terraform_data" "print_resources" {
      + id               = (known after apply)
      + triggers_replace = {
          + always_run = (known after apply)
        }
    }

  # terraform_data.print_resources[2] will be created
  + resource "terraform_data" "print_resources" {
      + id               = (known after apply)
      + triggers_replace = {
          + always_run = (known after apply)
        }
    }

  # terraform_data.print_resources[3] will be created
  + resource "terraform_data" "print_resources" {
      + id               = (known after apply)
      + triggers_replace = {
          + always_run = (known after apply)
        }
    }

  # terraform_data.print_resources[4] will be created
  + resource "terraform_data" "print_resources" {
      + id               = (known after apply)
      + triggers_replace = {
          + always_run = (known after apply)
        }
    }

  # terraform_data.print_resources[5] will be created
  + resource "terraform_data" "print_resources" {
      + id               = (known after apply)
      + triggers_replace = {
          + always_run = (known after apply)
        }
    }

Plan: 6 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  ~ tagged_resources_ids = [
      - [],
      + "aws",
    ]
terraform_data.print_resources[5]: Creating...
terraform_data.print_resources[0]: Creating...
terraform_data.print_resources[5]: Provisioning with 'local-exec'...
terraform_data.print_resources[5] (local-exec): Executing: ["/bin/sh" "-c" "echo \"Resource ID for tagged resources : aws and Resource ID for untagged resources : aws\"\n       \n"]
terraform_data.print_resources[0]: Provisioning with 'local-exec'...
terraform_data.print_resources[0] (local-exec): Executing: ["/bin/sh" "-c" "echo \"Resource ID for tagged resources : aws and Resource ID for untagged resources : aws\"\n       \n"]
terraform_data.print_resources[1]: Creating...
terraform_data.print_resources[1]: Provisioning with 'local-exec'...
terraform_data.print_resources[1] (local-exec): Executing: ["/bin/sh" "-c" "echo \"Resource ID for tagged resources : aws and Resource ID for untagged resources : aws\"\n       \n"]
terraform_data.print_resources[5] (local-exec): Resource ID for tagged resources : aws and Resource ID for untagged resources : aws
terraform_data.print_resources[2]: Creating...
terraform_data.print_resources[2]: Provisioning with 'local-exec'...
terraform_data.print_resources[2] (local-exec): Executing: ["/bin/sh" "-c" "echo \"Resource ID for tagged resources : aws and Resource ID for untagged resources : aws\"\n       \n"]
terraform_data.print_resources[4]: Creating...
terraform_data.print_resources[4]: Provisioning with 'local-exec'...
terraform_data.print_resources[4] (local-exec): Executing: ["/bin/sh" "-c" "echo \"Resource ID for tagged resources : aws and Resource ID for untagged resources : aws\"\n       \n"]
terraform_data.print_resources[3]: Creating...
terraform_data.print_resources[3]: Provisioning with 'local-exec'...
terraform_data.print_resources[3] (local-exec): Executing: ["/bin/sh" "-c" "echo \"Resource ID for tagged resources : aws and Resource ID for untagged resources : aws\"\n       \n"]
terraform_data.print_resources[5]: Creation complete after 0s [id=d71ba741-20a2-b2ac-4d55-0513f2a678e1]
terraform_data.print_resources[1] (local-exec): Resource ID for tagged resources : aws and Resource ID for untagged resources : aws
terraform_data.print_resources[1]: Creation complete after 0s [id=d835d78f-93a9-870c-97ed-82daac1f46b7]
terraform_data.print_resources[2] (local-exec): Resource ID for tagged resources : aws and Resource ID for untagged resources : aws
terraform_data.print_resources[2]: Creation complete after 0s [id=f0227bc6-9c3c-d3c0-5986-efeaa0446fcc]
terraform_data.print_resources[4] (local-exec): Resource ID for tagged resources : aws and Resource ID for untagged resources : aws
terraform_data.print_resources[4]: Creation complete after 0s [id=629c2a01-7217-9aad-f4fb-05c663429d8c]
terraform_data.print_resources[0] (local-exec): Resource ID for tagged resources : aws and Resource ID for untagged resources : aws
terraform_data.print_resources[0]: Creation complete after 0s [id=cdb59780-41fe-e427-a536-cf67bfd9cf97]
terraform_data.print_resources[3] (local-exec): Resource ID for tagged resources : aws and Resource ID for untagged resources : aws
terraform_data.print_resources[3]: Creation complete after 0s [id=0beb1fb7-a34a-aae0-85ab-91bb659a318c]

Apply complete! Resources: 6 added, 0 changed, 0 destroyed.

Outputs:

tagged_resources_ids = [
  "aws",
]

环境信息:

  • Terraform版本:1.4.6
  • AWS Provider版本:hashicorp/aws v5.40.0

解决方法

问题根源

  1. 数据源属性误用:aws_resourcegroupstaggingapi_resources的id字段是数据源自身的标识符(固定为"aws"),并非资源的唯一ID,实际资源信息存储在resource_tag_mapping_list数组中。
  2. 无标签资源筛选错误:原代码用空格作为标签键无法正确筛选无标签资源,需使用空字符串匹配无标签资源。
  3. count逻辑混乱:原代码将两个数据源的id长度相加(每个id是长度为3的字符串,所以总count为6),导致重复打印无效内容。

修正后的代码

# 获取所有带标签的资源
data "aws_resourcegroupstaggingapi_resources" "tagged_resources" {
  tag_filter {
    key    = "*"
    values = ["*"]
  }
}

# 获取所有无标签的资源
data "aws_resourcegroupstaggingapi_resources" "untagged_resources" {
  tag_filter {
    key    = ""
    values = [""]
  }
}

# 从资源ARN中提取唯一ID
locals {
  tagged_resource_ids = [
    for item in data.aws_resourcegroupstaggingapi_resources.tagged_resources.resource_tag_mapping_list :
    split("/", item.resource_arn)[length(split("/", item.resource_arn)) - 1]
  ]
  
  untagged_resource_ids = [
    for item in data.aws_resourcegroupstaggingapi_resources.untagged_resources.resource_tag_mapping_list :
    split("/", item.resource_arn)[length(split("/", item.resource_arn)) - 1]
  ]
}

# 输出带标签资源ID列表
output "tagged_resource_ids" {
  value = local.tagged_resource_ids
}

# 输出无标签资源ID列表
output "untagged_resource_ids" {
  value = local.untagged_resource_ids
}

# 打印带标签资源ID到控制台
resource "terraform_data" "print_tagged_resources" {
  count = length(local.tagged_resource_ids)
  
  triggers_replace = {
    always_run = timestamp()
  }
  
  provisioner "local-exec" {
    command = "echo Tagged Resource ID: ${local.tagged_resource_ids[count.index]}"
  }
}

# 打印无标签资源ID到控制台
resource "terraform_data" "print_untagged_resources" {
  count = length(local.untagged_resource_ids)
  
  triggers_replace = {
    always_run = timestamp()
  }
  
  provisioner "local-exec" {
    command = "echo Untagged Resource ID: ${local.untagged_resource_ids[count.index]}"
  }
}

关键修正说明

  1. 正确获取资源数据:使用resource_tag_mapping_list属性访问实际资源的ARN和标签信息,该数组中的每个元素对应一个AWS资源。
  2. 提取资源ID:通过split函数从资源ARN中截取最后一段,得到资源的唯一ID(AWS资源ARN格式统一,最后一段为资源ID)。
  3. 修正无标签筛选逻辑:使用空字符串的标签键和值,匹配没有任何标签的资源。
  4. 拆分打印逻辑:分别处理带标签和无标签资源的打印操作,确保每个资源对应一次打印,避免逻辑混乱。

内容的提问来源于stack exchange,提问作者user23567280

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 13:37:04