How to avoid errors when there are no data results

Hi guys I’m a engineer in Korea.

I’ve been trying to program EC2 replica.

I was going to program next step

  1. make a root_ebs snapshot
  2. Check if already there is AMI
  3. If there is no AMI make AMI in the snapshot
  4. make a ec2 in the AMI

But there is one problem.
I chcek existence AMI through data.aws_ebs_snapshot.
but if there is no result, error occured

data "aws_ebs_snapshot" "ebs_volume" {
  filter {
    name                = "tag:Name"
    values              = ["snapshot-${var.name}"]
  }
}

Hi @kyo-hyun, you cannot check existence of AMI using the aws_ebs_snapshot data source, since EBS snapshots and AMIs are two different resource types. You can use the aws_ami data source to get AMI information, however it will fail if the AMI does not exist or there are multiple AMIs matching the provided filters similar to the error you see with the aws_ebs_snapshot data source that you encountered.

What you could do is to instead use the aws_ami_ids data source which returns a list of IDs in the ids attribute. You can check whether ids contains one ID which is the AMI that you are looking for.

If I am misreading your question and you are checking for EBS snapshots instead, you can do something similar with the aws_ebs_snapshot_ids data source.

1 Like

Wow Thank you for your greate answer!
Can I ask one more question?

I’m going to check through data.aws_ebs_snapshot_ids if there is already ebs_sanpshot or not.
so if already exist ami I’m not going to make a ami but don’t exist I’m going to make a AMI.
So I used count funtion.
But one problem is that The “count” value depends on resource attributes that cannot be determined until apply, so Terraform cannot predict how many instances will be created.
what am I going to do to resolve this problem.

data "aws_instance" "selected_instance" {
  filter {
    name                = "tag:Name"
    values              = [var.source_ec2]
  }
  filter {
    name                = "instance-state-name"
    values              = ["running"]
  }
}

data "aws_ebs_snapshot_ids" "ebs_volumes" {

  filter {
    name                = "tag:Name"
    values              = ["snapshot-${var.name}"]
  }
}

resource "aws_ebs_snapshot" "root_ebs_snapshot" {
    count               = length(data.aws_ebs_snapshot_ids.ebs_volumes.ids) == 0 ? 1 : 0
    volume_id           = flatten([for block in data.aws_instance.selected_instance.root_block_device : block.volume_id])[0]
    tags = {
      Name              = "snapshot-root-${var.source_ec2}"
    }
}

Unfortunately there isn’t much you can do - Terraform just aren’t designed to handle conditional logics like what you need in this case.

Another approach I can think of is to use the aws_ami_from_instance resource which encapsulates the snapshotting. There are implications of using this resource about source instance inspection, so make sure you read the resource documentation. It also means you’ll end up replacing the AMI on every run depending on how you manage re-creation/update of the aws_ami_from_instance resource.

There is also a ec2-ami-snapshot module but it’s just a simple wrapper of the aws_ami_from_instance resource with a bit more control.

1 Like

Thank you for your answer.
I’ll do what you said!