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
解决方法
问题根源
- 数据源属性误用:
aws_resourcegroupstaggingapi_resources的id字段是数据源自身的标识符(固定为"aws"),并非资源的唯一ID,实际资源信息存储在resource_tag_mapping_list数组中。 - 无标签资源筛选错误:原代码用空格作为标签键无法正确筛选无标签资源,需使用空字符串匹配无标签资源。
- 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]}" } }
关键修正说明
- 正确获取资源数据:使用
resource_tag_mapping_list属性访问实际资源的ARN和标签信息,该数组中的每个元素对应一个AWS资源。 - 提取资源ID:通过
split函数从资源ARN中截取最后一段,得到资源的唯一ID(AWS资源ARN格式统一,最后一段为资源ID)。 - 修正无标签筛选逻辑:使用空字符串的标签键和值,匹配没有任何标签的资源。
- 拆分打印逻辑:分别处理带标签和无标签资源的打印操作,确保每个资源对应一次打印,避免逻辑混乱。
内容的提问来源于stack exchange,提问作者user23567280
相关产品推荐
相关产品推荐

