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

Misleading error:does not have attribute 'private_ip' for variable #19065

Closed
ikekim opened this issue Oct 12, 2018 · 14 comments
Closed

Misleading error:does not have attribute 'private_ip' for variable #19065

ikekim opened this issue Oct 12, 2018 · 14 comments

Comments

@ikekim
Copy link

ikekim commented Oct 12, 2018

Terraform Version

Terraform v0.11.7

Terraform Configuration Files

resource "aws_spot_instance_request" "walker" {
  count = 2
  instance_type = "t2.micro"
  ami = "ami-0922553b7b0369273"
  spot_price = "1"
}

resource "aws_spot_instance_request" "runner" {
  count = 2
  instance_type = "t2.micro"
  ami = "ami-0922553b7b0369273"
  spot_price = "1"

}

output "aws_walker_private_ip_addresses" {
    value = ["${aws_spot_instance_request.walker.*.private_ip}"]
}

output "aws_runner_private_ip_addresses" {
    value = ["${aws_spot_instance_request.runner.*.private_ip}"]
}

I referenced Terraform documentation from here to get the proper syntax for configuring the output:
https://www.terraform.io/docs/configuration/outputs.html

Expected Behavior:

Outputs:

aws_runner_private_ip_addresses = [
x.x.x.x,
x.x.x.x
]
aws_walker_private_ip_addresses = [
x.x.x.x,
x.x.x.x
]

Actual Behavior

  • output.aws_runner_private_ip_addresses: Resource 'aws_spot_instance_request.runner' does not have attribute 'private_ip' for variable 'aws_spot_instance_request.runner.*.private_ip'
    • output.aws_walker_private_ip_addresses: Resource 'aws_spot_instance_request.walker' does not have attribute 'private_ip' for variable 'aws_spot_instance_request.walker.*.private_ip

I do see that there is support for the attribute 'private_ip' according to the documentation here.
https://www.terraform.io/docs/providers/aws/r/spot_instance_request.html

However if I use the code below by removing the brackets for output value, then there is no error and I get the expected result of the ip addresses being displayed as output.

This code works, but isn't this syntax incorrect since my expected value is a list type(list of ip addresses)?

output "aws_walker_private_ip_addresses" {
    value = "${aws_spot_instance_request.walker.*.private_ip}"
}

output "aws_runner_private_ip_addresses" {
    value = "${aws_spot_instance_request.runner.*.private_ip}"
}
@bennycornelissen
Copy link

Since the splat expression you're using already returns a list, the brackets would not be needed. I do understand how the syntax without brackets could throw you off a bit.

Also this seems inconsistent with behaviour in other places, although I'm going from memory here. I'll see if I can find an example for this inconsistency.

@bennycornelissen
Copy link

With regard to my remark about inconsistency, please consider the example below. This excerpt of code is part of a multi-stage infrastructure setup. First the main-infra plan is applied, which contains an output (type list) with an IP whitelist.

variable "whitelist_cidr_additional" {
  default = []
}

resource "aws_security_group_rule" "foo-elb-ingress-https" {
  security_group_id = "${aws_security_group.foo-elb.id}"
  type              = "ingress"
  from_port         = 443
  to_port           = 443
  protocol          = "tcp"

  # the line below takes the 'whitelist_cidr' from main-infra and the
  # optional variable 'whitelist_cidr_additional'. It then concatenates
  # those lists, and removes empty values and duplicates
  cidr_blocks = ["${distinct(compact(concat(data.terraform_remote_state.main-infra.whitelist_cidr, var.whitelist_cidr_additional)))}"]
}

Since the result of "${distinct(compact(concat(data.terraform_remote_state.main-infra.whitelist_cidr, var.whitelist_cidr_additional)))}" is already a list, it shouldn't need brackets. Yet, it works just fine with them (I'm not even sure if it works if I remove them).

I'm not sure if this 'inconsistency' is due to the use of the splat expression, but personally I'd prefer if Terraform would allow the (redundant?) brackets like in @ikekim's example. It makes the code more readable.

@ikekim
Copy link
Author

ikekim commented Oct 12, 2018

@bennycornelissen But in terraform documentation on output syntax shown here shows the example of splat syntax with the brackets. It seems to contradict your statement.

https://www.terraform.io/docs/configuration/outputs.html

output "addresses" {
  value = ["${aws_instance.web.*.public_dns}"]
}

@bennycornelissen
Copy link

It seems to do that, indeed. But I think we’ve established that what the docs suggest, actually doesn’t work in practice.

@ikekim
Copy link
Author

ikekim commented Oct 13, 2018

Upon further testing, the syntax with the brackets seems to be correct because once I test with the following code, the output syntax works according to Terraform documentation.

resource "aws_instance" "walker" {
  ami           = "ami-0922553b7b0369273"
  instance_type = "t2.micro"
  count = 2
}

output "aws_ec2_walker_private_ip_addresses" {
    value = ["${aws_instance.walker.*.private_ip}"]
}

This means there is something not right about the "aws_spot_instance_request" output attribute "private_ip". The documentation does say "These attributes are exported, but they are expected to change over time and so should only be used for informational purposes, not for resource dependencies:" So my question would be, can the 'private_ip' exported for "aws_spot_instance_request"? And how can I get around the error that I'm encountering?

@bennycornelissen
Copy link

bennycornelissen commented Oct 13, 2018

You may be on to something here. Although in that case it would be a provider specific issue.

Edit:
It seems to be exported, but only if an instance actually exists? Not sure if I’m reading that right, it’s still early over here. Haven’t really used spot instances before so I might be overlooking some particulars.

https://github.com/terraform-providers/terraform-provider-aws/blob/efcbb7cd91a3fdfaa92769275cc4fc7927a185fe/aws/resource_aws_spot_instance_request.go#L307

@bennycornelissen
Copy link

Upon reading https://www.terraform.io/docs/providers/aws/r/spot_instance_request.html https://www.terraform.io/docs/providers/aws/r/spot_instance_request.html again, I think this isn’t a bug in terraform or the provider. Since you’re only requesting a spot instance, and there’s no guarantee it will actually be delivered due to the spot market, the docs specifically state the exported private_ip should only be used for informational purposes.

So it’s possible that your original code works sometimes but not all the time. You could try to use the ‘compact’ interpolation to deal with empty results but I’m not sure if it will work.

@ikekim
Copy link
Author

ikekim commented Oct 13, 2018

After the running the code, even after getting the error, I do see the spot request getting filled and see the ec2 instances so there is real private_ip addresses are available but it doesn't seem to make it in to the "terraform.tfstate" file.

However, if I run the "terraform refresh" command I do see that all the ip addresses gets populated into the "terraform.tfstate" file and also displays the output value in the command window.

I also found this posting which I believe is tagged as a bug.
hashicorp/terraform-provider-aws#4313

The person reported also mentioned he has implemented the workaround, but there is no details on how. I think I need to do some sort of workaround at this point, but looking for a simpler solution than perhaps writing boto3 codes to get the private_ip addresses.

@ikekim
Copy link
Author

ikekim commented Oct 13, 2018

It's interesting that you mentioned about the provider issue.

When I run the same code on Terraform version 0.9.6, I do not get the error messages and I also do not get the output value. I need to know why why the 0.9.6 version there is no error messages and was wondering if it has to do with the provider? On 0.11.7 I can see something like terraform-"provider-aws_v1.40.0_x4" in the hidden folder, but I don't see something like this in the 0.9.6.

@ikekim
Copy link
Author

ikekim commented Oct 14, 2018

I found a solution & this worked for me.

wait_for_fulfillment = true

@ikekim ikekim closed this as completed Oct 14, 2018
@bennycornelissen
Copy link

@ikekim Terraform split off the providers into separate entities as of Terraform 0.10. One of the reasons for this is to make development of both Terraform and provider specific implementation easier (as they can be developed and released independently). You can read more about that here: https://www.hashicorp.com/blog/upcoming-provider-changes-in-terraform-0-10

Regarding your workaround: that should indeed work. One possible side-effect is that if fullfillment takes a very long time, your Terraform run could fail. If that happens, just run Terraform again.

@ikekim
Copy link
Author

ikekim commented Oct 15, 2018

My workaround seems to be a hit and miss. The below is Terraform doc and the 10m doesn't seem to be enough. I don't see anyway to modify this value.

Terraform documentation

wait_for_fulfillment - (Optional; Default: false) If set, Terraform will wait for the Spot Request to be fulfilled, and will throw an error if the timeout of 10m is reached.

@ghost
Copy link

ghost commented Oct 26, 2018

This issue has been automatically migrated to hashicorp/terraform-provider-aws#6283 because it looks like an issue with that provider. If you believe this is not an issue with the provider, please reply to hashicorp/terraform-provider-aws#6283.

@ghost ghost closed this as completed Oct 26, 2018
@ghost
Copy link

ghost commented Apr 1, 2020

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 Apr 1, 2020
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants