How to tag non-root snapshots when creating an AMI?

Hello,
I am creating AMIs from existing EC2 instance, that has 2 ebs volumes. I am using “aws_ami_from_instance”, but then the disk snapshots do not have tags. I found a way from hashi’s github to tag ‘manually’ the root snapshot, since “root_snapshot_id” is exported from the ami resource, but what can I do about the other disk?

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
}

@tyger According to the aws_ami_from_instance resource documentation, it has all of the attributes from the aws_ami resource, which includes ebs_block_device blocks that has a snapshot_id attribute. Perhaps you can use this to get the non-root snapshot IDs with a wildcard.

Thanks for the idea. I tried a few ways, but maybe it’s not possible to refer the id from the set:

│ 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.

You should be able to use the for expression. Here’s the config that I used to create one hardcoded tag for an instance with three EBS volumes (snapshots):

resource "aws_ami_from_instance" "server_ami" {
  name               = "test_ami"
  source_instance_id = "i-0acb85452cfadfd97"
}

resource "aws_ec2_tag" "server_ami_tags" {
  for_each    = toset([for v in aws_ami_from_instance.server_ami.ebs_block_device : v.snapshot_id if v.device_name != "/dev/xvda"])
  resource_id = each.value
  key         = "TestTagName"
  value       = "TestTagValue"
}

You might need to be a bit more creative and use a local map value to achieve a loop of both the snapshot IDs and the tags. Hope this helps.