I am getting error when the module has a count condition within that is checking an input value. And the input value is dependent on the resource that is being created along with module.
resource "aws_kms_key" "this" {
}
module "service_secret" {
source = "./secret"
name = "foo-bar"
kms_arn = aws_kms_key.this.arn
tags = {}
}
in module secret
:
resource "aws_secretsmanager_secret" "this" {
name = var.name
kms_key_id = var.kms_arn == "" ? aws_kms_key.this[0].arn : var.kms_arn
}
resource "aws_kms_key" "this" {
count = var.kms_arn != "" ? 0 : 1
}
Error:
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. count = var.kms_arn != "" ? 0 : 1
2
Answers
That’s correct. You can’t have
count
orfor_each
depend on apply-level variables such asaws_kms_key.this.arn
. Everything must be known atplan
time, which means you have explicitly pass how many instances you want forcount
to work, or use -target to first createaws_kms_key.this
, and then run your code again to create other resources.The
hashicorp/aws
provider is reporting that it doesn’t yet know anything about the final value of thearn
attribute ofaws_kms_key.this
, and so Terraform in turn cannot predict whether that value is different from""
.If you are using Terraform v1.8 or later then you can use the
apparentlymart/assume
provider (disclosure: I wrote this provider) to tell Terraform to make some additional assumptions about this value, to compensate for the AWS provider’s imprecise result.First I’d suggest using
null
instead of""
to represent "no KMS ARN", because that’s the idiomatic way to represent the absence of something in Terraform. In your./secret
module, declare the variable and use it like this:This change alone will not improve the problem, because the current version of the AWS provider at the time I’m writing this also doesn’t assure Terraform that the
arn
attribute is never null. But you can use theapparentlymart/assume
provider in your root module to promise Terraform that this value cannot be null:The expression
provider::assume::notnull(aws_kms_key.this.arn)
uses the provider’snotnull
function to promise Terraform that whatever final value this attribute takes it will definitely not benull
.When Terraform evaluates
var.kms_key != null
inside the module it will then assume the answer istrue
, and thus thecount
will be set to zero.Hopefully in a future version of the
hashicorp/aws
provider the provider itself will tell Terraform that thearn
attribute is never null, avoiding the need for this additionalnotnull
function.Terraform’s ability to track "not null", and some other constraints on unknown values, is a relatively new feature and so most providers are not updated to use it yet. I wrote the
apparentlymart/assume
provider as an interim solution so that module authors don’t need to wait for all providers to be updated.