如何从aws_ami_from_instance的ebs_block_device引用snapshot_id并为非根卷快照打标签?
问题描述
我通过aws_ami_from_instance资源从带有2个EBS卷的EC2实例创建AMI,生成的磁盘快照未自动添加标签。目前已通过AMI资源导出的root_snapshot_id为根快照打上标签,但不知道如何处理非根卷的快照。
现有Terraform代码:
resource "aws_ami_from_instance" "server_ami" { name = "${var.env}.v${local.new_version}.ami" source_instance_id = data.aws_instance.server.id tags = { Name = "${var.env}.v${local.new_version}.ami" Version = local.new_version } } resource "aws_ec2_tag" "server_ami_tags" { for_each = { for tag in var.tags : tag.tag => tag } resource_id = aws_ami_from_instance.server_ami.root_snapshot_id key = each.value.tag value = each.value.value }
尝试引用ebs_block_device的快照ID时报错:
│ 25: resource_id = aws_ami_from_instance.sever_ami.ebs_block_device.snapshot_id │ Block type "ebs_block_device" is represented by a set of objects, and set │ elements do not have addressable keys. To find elements matching specific │ criteria, use a "for" expression with an "if" clause. │ 25: resource_id = aws_ami_from_instance.sever_ami.ebs_block_device[snapshot_id] │ A reference to a resource type must be followed by at least one attribute │ access, specifying the resource name. │ 25: resource_id = aws_ami_from_instance.sever_ami.ebs_block_device["snapshot_id"] │ Block type "ebs_block_device" is represented by a set of objects, and set │ elements do not have addressable keys. To find elements matching specific │ criteria, use a "for" expression with an "if" clause.
请问该需求能否实现,操作上哪里有误?
解决方案
这个需求完全可以实现,问题出在你对ebs_block_device的访问方式上——它是集合(Set)类型,无法直接通过键名或索引访问单个元素,必须用for表达式遍历处理。
你可以新增一个aws_ec2_tag资源,遍历所有非根卷的快照ID,同时结合你的标签列表批量打标签:
# 为根快照打标签(保留原有代码) resource "aws_ec2_tag" "server_ami_root_snapshot" { for_each = { for tag in var.tags : tag.tag => tag } resource_id = aws_ami_from_instance.server_ami.root_snapshot_id key = each.value.tag value = each.value.value } # 为非根卷的快照打标签 resource "aws_ec2_tag" "server_ami_non_root_snapshots" { # 生成唯一键:标签名+快照ID,避免重复;同时过滤掉根快照 for_each = { for tag in var.tags, ebs in aws_ami_from_instance.server_ami.ebs_block_device : "${tag.tag}-${ebs.snapshot_id}" => { tag = tag, ebs = ebs } if ebs.snapshot_id != aws_ami_from_instance.server_ami.root_snapshot_id } resource_id = each.value.ebs.snapshot_id key = each.value.tag.tag value = each.value.tag.value }
关键说明:
- 集合遍历:用
for表达式遍历ebs_block_device集合中的每个EBS卷对象,取出其中的snapshot_id。 - 标签批量处理:通过嵌套遍历标签列表和EBS卷集合,生成唯一的
for_each键(避免资源重复创建)。 - 过滤根快照:通过
if条件排除已处理的根快照,避免重复打标签。
内容的提问来源于stack exchange,提问作者XerX
相关产品推荐
相关产品推荐

