Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

terraform count dependent on data from target environment

I'm getting the following error when trying to initially plan or apply a resource that is using the data values from the AWS environment to a count.

$ terraform plan 
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.


------------------------------------------------------------------------

Error: Invalid count argument

  on main.tf line 24, in resource "aws_efs_mount_target" "target":
  24:   count = length(data.aws_subnet_ids.subnets.ids)

The "count" value depends on resource attributes that cannot be determined
until apply, so Terraform cannot predict how many instances will be created.
To work around this, use the -target argument to first apply only the
resources that the count depends on.

$ terraform --version
Terraform v0.12.9
+ provider.aws v2.30.0

I tried using the target option but doesn't seem to work on data type.

$ terraform apply -target aws_subnet_ids.subnets

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

The only solution I found that works is:

  1. remove the resource
  2. apply the project
  3. add the resource back
  4. apply again

Here is a terraform config I created for testing.

provider "aws" {
  version = "~> 2.0"
}

locals {
  project_id = "it_broke_like_3_collar_watch"
}

terraform {
  required_version = ">= 0.12"
}

resource aws_default_vpc default {
}

data aws_subnet_ids subnets {
  vpc_id = aws_default_vpc.default.id
}

resource aws_efs_file_system efs {
  creation_token = local.project_id
  encrypted = true
}

resource aws_efs_mount_target target {
  depends_on = [ aws_efs_file_system.efs ]
  count = length(data.aws_subnet_ids.subnets.ids)
  file_system_id = aws_efs_file_system.efs.id
  subnet_id = tolist(data.aws_subnet_ids.subnets.ids)[count.index]
}
like image 263
WaltDe Avatar asked Nov 22 '25 05:11

WaltDe


1 Answers

Finally figured out the answer after researching the answer by Dude0001.

Short Answer. Use the aws_vpc data source with the default argument instead of the aws_default_vpc resource. Here is the working sample with comments on the changes.

locals {
  project_id = "it_broke_like_3_collar_watch"
}

terraform {
  required_version = ">= 0.12"
}

// Delete this --> resource aws_default_vpc default {}

// Add this
data aws_vpc default {
  default = true
}


data "aws_subnet_ids" "subnets" {
// Update this from aws_default_vpc.default.id 
  vpc_id = "${data.aws_vpc.default.id}"
}

resource aws_efs_file_system efs {
  creation_token = local.project_id
  encrypted = true
}

resource aws_efs_mount_target target {
  depends_on = [ aws_efs_file_system.efs ]
  count = length(data.aws_subnet_ids.subnets.ids)
  file_system_id = aws_efs_file_system.efs.id
  subnet_id = tolist(data.aws_subnet_ids.subnets.ids)[count.index]
}

What I couldn't figure out was why my work around of removing aws_efs_mount_target on the first apply worked. It's because after the first apply the aws_default_vpc was loaded into the state file.

So an alternate solution without making change to the original tf file would be to use the target option on the first apply:

$ terraform apply  --target aws_default_vpc.default

However, I don't like this as it requires a special case on first deployment which is pretty unique for the terraform deployments I've worked with.

like image 100
WaltDe Avatar answered Nov 24 '25 05:11

WaltDe



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!