简体   繁体   中英

terraform plan works one way but not the other?

Terraform v0.12.17

I just have 2 simple files

snapshot_id.tf = gets a list of my completed EBS volume snapshot ids
data "aws_ebs_snapshot_ids" "jenkins_master" {
  filter {
    name   = "tag:Name"
    values = ["jenkins-master"]
  }
  filter {
    name   = "status"
    values = ["completed"]
  }
}

ebs_volume_green.tf = use above data resource to create an EBS volume
resource "aws_ebs_volume" "jenkins_master_ebs_green" {
  availability_zone = var.availability_zones.green
  snapshot_id = data.aws_ebs_snapshot_ids.jenkins_master.id
         size = data.aws_ebs_snapshot_ids.jenkins_master.volume_size
         type = "gp2"
  tags = {
    Name = "jenkins-master-green"
    Environment = "sandbox"
    Product = "Jenkins"
    Role = "master"
  }
}

This passes, so obviously the resource has volume_size defined.

$ terraform plan -target ebs_volume_green.tf -out out.output
$ terraform apply out.output

But this fails, ie, if I don't specify the -target option. Why?

$ terraform plan -out out.output    
Error: Unsupported attribute

  on ebs_volume_green.tf line 4, in resource "aws_ebs_volume" "jenkins_master_ebs_green":
   4:          size = data.aws_ebs_snapshot_ids.jenkins_master.volume_size

This object has no argument, nested block, or exported attribute named
"volume_size".

You have confused the aws_ebs_snapshot_ids and the aws_ebs_snapshot data sources.

You should only be using the plural data sources if you need to return multiple of something. You can then pass these IDs into the individual data source that returns more useful information or just pass the IDs into something that takes a list of IDs such as the aws_autoscaling_group resource's vpc_zone_identifier parameter.

In your case if you just want the most recent snapshot that matches your tags you would just use the following:

data "aws_ebs_snapshot" "jenkins_master" {
  most_recent = true

  filter {
    name   = "tag:Name"
    values = ["jenkins-master"]
  }

  filter {
    name   = "status"
    values = ["completed"]
  }
}

This will then have the volume_size attribute from the data source that you are expecting.

In your question you can see that it plans and applies successfully when you target just the data source but it's only when your plan includes a usage of a resource or data source's output that doesn't exist that Terraform will complain because it's not evaluating everything in -target mode. In general if you have to use -target then something is wrong somewhere and you should see that as a red flag.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM