Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

terraform validating resources even when conditionally skipped #16798

Closed
sudhakar-mnsr opened this issue Nov 30, 2017 · 8 comments
Closed

terraform validating resources even when conditionally skipped #16798

sudhakar-mnsr opened this issue Nov 30, 2017 · 8 comments

Comments

@sudhakar-mnsr
Copy link

sudhakar-mnsr commented Nov 30, 2017

Terraform Version

Terraform v0.10.8
...

Terraform Configuration Files

resource "aws_iam_instance_profile" "master_instance_profile" {
    count = "${var.enable_sc == "yes" ? 1 : 0}"
    name = "master_instance_profile"
    role = "k8sMaster"
}

resource "aws_instance" "dumb-master" {
  connection {
    timeout     = "${var.connection_timeout}"
    user        = "${var.ansible_user}"
    private_key = "${file(var.private_key)}"
  }

  count                       = "${var.num_masters}"
  ami                         = "${var.aws_ami}"
  instance_type               = "${var.aws_instance_type}"
  key_name                    = "${aws_key_pair.keypair.key_name}"
  vpc_security_group_ids      = ["${var.aws_security_group_id}"]
  subnet_id                   = "${var.aws_subnet_id}"
  iam_instance_profile        = "${var.enable_sc == "yes" ? "${aws_iam_instance_profile.master_instance_profile.id}" : ""}"
……………………….

}

Debug Output

Crash Output

Expected Behavior

it should have run without validating the skipped resource.

Actual Behavior

If the policy and role is all set then I will enable by setting enable_sc to yes otherwise I will set it to no. For the case of enable_sc=yes this works fine.

For the case enable_sc is no terraform fails with below error.

[root@sdl04422 aws]# terraform apply -var-file=aws.local.tfvars.sep30
data.template_file.ansible_config: Refreshing state...

Error: Error running plan: 1 error(s) occurred:

  • aws_instance.dumb-master: 1 error(s) occurred:

  • aws_instance.dumb-master: Resource 'aws_iam_instance_profile.master_instance_profile' not found for variable 'aws_iam_instance_profile.master_instance_profile.id'

The reason is quite obvious but seems not logical. Terraform is verifying master_instance_profile resource exists even in case of enable_sc is no i.e iam not at all using this resource. This behavior seems incorrect to me.

Steps to Reproduce

Important Factoids

References

@CrankyDragon
Copy link

I don't believe this is a problem at all since you are essentially attempting to access an attribute of a resource that cannot exist. When you create a resource conditionally, you either need to make sure that any dependent resources are also created conditionally, or ensure that dependent resources have a conditional dependency on the resource. One way of solving this problem is to use the splat syntax:

iam_instance_profile        = "${join("", aws_iam_instance_profile.master_instance_profile.*.id)}"

This simply creates a list of all the possible resource ids which you can then join into a string.

@sudhakar-mnsr
Copy link
Author

In the above Iam accessing resource master_instance_profile if var.enable_sc is yes. However in case of var.enable_sc is no it should go to the else part which is null. however in this scenario it is validating master_instance_profile.

The above alternative will not work for me. My requirement is if the var.enable_sc is no then no roles will be present and master_instance_profile will return error as there is no role. So Iam conditionally skipping the resource. But iam unable to conditionally eliminate the resource key iam_instance_profile in aws_instance resource. Could you please suggest an alternative for my scenario.
Please let me know if you need more information.

@CrankyDragon
Copy link

That's precisely what the above does, albeit in a roundabout way. If look closely at what is actually happening you'll see that if no resource ids exist, an empty list will be created. Joining an empty list using an empty string produces an empty string which is the output you are expecting.

This

"${var.enable_sc == "yes" ? "${aws_iam_instance_profile.master_instance_profile.id}" : ""}"

produces the same value as

"${join("", aws_iam_instance_profile.master_instance_profile.*.id)}"

however the later will not generate an error if the master_instance_profile resource does not exist.

@sudhakar-mnsr
Copy link
Author

Thanks for your help. It worked
However just my curiosity...
I still feel in both statements should result in error when condition skipped master_instance_profile resource creation
"${join("", aws_iam_instance_profile.master_instance_profile.*.id)}"
"${var.enable_sc == "yes" ? "${aws_iam_instance_profile.master_instance_profile.id}" : ""}"
it would be great if you could clarify me on why the first statement is not resulting in error though master_instance_profile is referenced (enabled_sc = no).

@CrankyDragon
Copy link

I'm afraid the specifics as to why "splatting" works when direct references don't are nestled in code that I haven't read, and little documentation on the subject exists, but If I had to take a guess, I'd assume that splats cause attributes to be accessed lazily.

resources = []
for resource in resources:
    resource['id']

Basically, in order to access the id attribute for a list of resources, you would need to iterate over the list of resources first. When the number of items in that list is zero, the loop cannot execute, therefore the attribute can't be accessed. On the other hand, when you attempt to access the attribute for a resource that can never exist:

if False:
    resource = { 'id' : None }
resource.id

things blow up and rightly so.

@jbardin
Copy link
Member

jbardin commented Dec 1, 2017

Hi,

Thanks for filing the issue. The Interpolation feature you want is being tracked here hashicorp/hil#50,

And we also tracking this in terraform via #11566 and #15605,

Thanks!

@jbardin jbardin closed this as completed Dec 1, 2017
sdurrheimer added a commit to cycloid-community-catalog/stack-concourse-server that referenced this issue Feb 11, 2019
sdurrheimer added a commit to cycloid-community-catalog/stack-concourse-server that referenced this issue Feb 11, 2019
@styk-tv
Copy link

styk-tv commented Aug 21, 2019

@CrankyDragon you want Python not Terraform :)

@ghost
Copy link

ghost commented Aug 22, 2019

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@ghost ghost locked and limited conversation to collaborators Aug 22, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants