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

Add public_dns to Elastic Ips #3731

Closed
wants to merge 1 commit into from
Closed

Add public_dns to Elastic Ips #3731

wants to merge 1 commit into from

Conversation

appilon
Copy link
Contributor

@appilon appilon commented Mar 9, 2018

Fix #1149
Fix #3474 (modify config to reference the eip)

Uses net.LookupAddr to find public dns name based on ip address. In scenarios where DNS is not working correctly simply set to empty string (soft failure).

Also included minor refactor and cleanup of the data source acceptance tests.

@ghost ghost added size/M Managed by automation to categorize the size of a PR. labels Mar 9, 2018
@ghost ghost added the size/M Managed by automation to categorize the size of a PR. label Mar 12, 2018
- uses net.LookupAddr
- set to empty string on error/no results
- update docs
- cleanup/refactor tests
@ghost ghost added the size/M Managed by automation to categorize the size of a PR. label Mar 12, 2018
@bflad bflad added enhancement Requests to existing resources that expand the functionality or scope. service/ec2 Issues and PRs that pertain to the ec2 service. labels Mar 13, 2018
Copy link
Contributor

@apparentlymart apparentlymart left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Some style-related feedback is inline. Since style is always subjective, feel free to disregard that feedback after considering it. 😀

@@ -48,3 +48,6 @@ All of the argument attributes are also exported as result attributes. This
data source will complete the data by populating any fields that are not
included in the configuration with the data for the selected Elastic IP.

* `public_dns` - DNS name of the allocated EIP

__Note__: The `public_dns` attribute is provided as a convenience, it is computed via Go's built-in reverse lookup and we select only the first result returned. Depending on how and where Terraform is run this lookup may fail, in which case we simply leave it as an empty string `""`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for including this note. I wonder if this is important enough to justify use of the ~> extension to create a warning box:

~> **Note:** The `public_dns` attribute ....

Also, we usually try to write our documentation as if it's in the voice of a "narrator" that is monitoring Terraform's progress and describing what it is doing, which tends to lead to sentences using the active voice rather than the passive voice. I think this would suggest wording like the following:

This resource exports the public_dns attribute as a convenience by performing a reverse-DNS lookup and taking the first record returned. In some environments this DNS request may fail, in which case the resource exports the empty string "".

(Note also that we don't generally talk about Go features because that's an implementation detail rather than something the user needs to worry about. Users shouldn't feel like they need to be familiar with Go in order to use Terraform.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noted, I will try and remember that and stay consistent going forward.


import "net"

func reverseLookup(ip string) (name string) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the context of this function is the entire aws package, I'd suggest the name reverseDNSLookup, just to make it clearer at the call site what sort of lookup this function does.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍


func reverseLookup(ip string) (name string) {
if names, err := net.LookupAddr(ip); err == nil && len(names) > 0 {
name = names[0]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although this is valid Go, I think normal idiom in this case would be to use an unnamed return value and have multiple return statements:

if ... {
    return names[0]
}
return ""

This makes the result in the unsuccessful case more obvious. Named return values are usually used only where the name adds useful context in package documentation for functions with multiple return values of the same type.

This is discussed in the common Go code review comments. This is of course a subjective thing, so feel free to ignore this if you'd made a conscious decision here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@appilon
Copy link
Contributor Author

appilon commented Mar 14, 2018

@apparentlymart I think @radeksimko had some questions/comments (he was sick I believe when we originally discussed this in the slack channel).

Copy link
Member

@radeksimko radeksimko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My concern with this enhancement is that it's introducing quite a lot of (hidden) complexity into otherwise simple resource.

The resource is suddenly responsible for a direct reverse DNS resolution which then brings in the burden of related DNS issues I'd expect to be already handled in the DNS provider.

e.g. what happens if there's firewall in the way blocking the resolution - then we're going to silently fail? or what if the user wants to set custom DNS servers for the resolution?

TL;DR Why can't this reside in the DNS provider instead?

@bflad
Copy link
Contributor

bflad commented Mar 20, 2018

Another option is that we could just synthesize these according to the VPC DNS documentation?

A public (external) DNS hostname takes the form ec2-public-ipv4-address.compute-1.amazonaws.com for the us-east-1 region, and ec2-public-ipv4-address.region.amazonaws.com for other regions.

I'm pretty sure that applies to EIPs as well, but probably worth verifying (potentially with AWS support). We can also submit an AWS feature support request to provide this value in the API. Worst case, I also lean towards recommending the DNS provider here as well to keep the complexity down. 👍

That said, DNS resolution could potentially be an issue if the resolver is also in EC2 within the same region/network (again, I think this also applies to EIPs):

We resolve a public DNS hostname to the public IPv4 address of the instance outside the network of the instance, and to the private IPv4 address of the instance from within the network of the instance.

@appilon
Copy link
Contributor Author

appilon commented Mar 22, 2018

@bflad

We resolve a public DNS hostname to the public IPv4 address of the instance outside the network of the instance, and to the private IPv4 address of the instance from within the network of the instance.

This was the goal of this PR, to address this issue: #1149

In some AWS forums the "recommended" way of referencing an EIP is the public DNS so that internal and external networks will resolve to the same machine.

I actually added the reverse lookup to the dns provider, is there some way I could recommend leveraging that? Another issue: #3474 wants to be able to pass the DNS name to route53 in one pass, would that be possible with the DNS provider in conjunction with the AWS provider.

@catsby
Copy link
Contributor

catsby commented Apr 25, 2018

Hello – this is a month old, if possible let's please resolve what's left and merge, or close the PR. Thanks 😉

@appilon
Copy link
Contributor Author

appilon commented Apr 25, 2018

I stopped working on this PR hoping for a consensus, from the comments it still appears to be debatable where or not we want this. I actually implemented the reverse lookup in the dns provider a while back, maybe the suggestion is to pass the EIP address to the dns provider for a reverse lookup and thus the user will have reference the the allocated DNS name of the elastic IP? If that is the accepted official workaround I can close this PR and comment on the associated issues?

Please react with 👍 if we want to merge (after code changes) this code, or 👎 if we would prefer suggest a workaround?

@catsby
Copy link
Contributor

catsby commented Jul 26, 2018

@appilon based on Radek's objection and this doc note:

Depending on how and where Terraform is run this lookup may fail, in which case we simply leave it as an empty string

I suggest we close this PR. If AWS does not provide a way to do this via API, then our attempts to do so in code can be subject to painful cat-and-mouse updates to support varied scenarios. I like Brian's suggestion of putting in a feature request, so we're not just throwing our hands up completely ¯_(ツ)_/¯

@catsby catsby closed this Jul 26, 2018
@appilon
Copy link
Contributor Author

appilon commented Jul 26, 2018

Yup I agree having code do things beyond what the provider API providers is probably a bad idea. I added functionality to the DNS provider a while ago that they could use in conjunction with their EIPs to get the DNS name.

@ghost
Copy link

ghost commented Apr 4, 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 feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thanks!

@ghost ghost locked and limited conversation to collaborators Apr 4, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement Requests to existing resources that expand the functionality or scope. service/ec2 Issues and PRs that pertain to the ec2 service. size/M Managed by automation to categorize the size of a PR.
Projects
None yet
5 participants