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

Default ec2 endpoint is ec2.us-east-1.amazonaws.com #27925

Closed
wants to merge 6 commits into from

Conversation

dadoonet
Copy link
Member

Document that we are using by default ec2.us-east-1.amazonaws.com as
the EC2 endpoint if not explicitly set.

Also switch to non deprecated method when building the EC2 Client.

Closes #27464.

Document that we are using by default `ec2.us-east-1.amazonaws.com` as
the EC2 endpoint if not explicitly set.

Also switch to non deprecated method when building the EC2 Client.

Closes elastic#27464.
Copy link
Member

@rjernst rjernst left a comment

Choose a reason for hiding this comment

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

I left a few comments.

String region = buildRegion(endpoint);
// TODO according to the documentation we should set the region instead of setting a endpoint
// See https://github.com/elastic/elasticsearch/issues/27924
logger.debug("Setting endpoint to [{}] with region [{}]", endpoint, region);
Copy link
Member

Choose a reason for hiding this comment

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

We already have a debug level message in findEndpoint that is roughly equivalent.

logger.debug("Setting endpoint to [{}] with region [{}]", endpoint, region);
builder.setEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(endpoint, region));
} else {
logger.debug("No endpoint defined. We are falling back to [ec2.us-east-1.amazonaws.com].");
Copy link
Member

Choose a reason for hiding this comment

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

Normally we wouldn't use "we" in a log message like this. I suggest Using default endpoint [...].

String endpoint = findEndpoint(logger, settings);
if (endpoint != null) {
client.setEndpoint(endpoint);
String region = buildRegion(endpoint);
// TODO according to the documentation we should set the region instead of setting a endpoint
Copy link
Member

Choose a reason for hiding this comment

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

Part of the reason we moved away from region was it required bumping the aws client dep whenever a new region was added. By setting endpoint, we avoid that. For this reason, I do not think we should go back to setting region.

Copy link
Member Author

Choose a reason for hiding this comment

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

Make sense.

import java.io.IOException;
import java.util.Random;

import static com.amazonaws.util.AwsHostNameUtils.parseRegion;
Copy link
Member

Choose a reason for hiding this comment

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

Please don't static import methods like this. I was very confused looking for this method within this file.

@dadoonet
Copy link
Member Author

Thanks @rjernst! I pushed a new commit to address your points.

Copy link
Member

@rjernst rjernst left a comment

Choose a reason for hiding this comment

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

A couple more comments.

figured out by the ec2 client based on the instance location, but
can be specified explicitly. See http://docs.aws.amazon.com/general/latest/gr/rande.html#ec2_region.
The ec2 service endpoint to connect to. See http://docs.aws.amazon.com/general/latest/gr/rande.html#ec2_region.
This will default to `ec2.us-east-1.amazonaws.com`.
Copy link
Member

Choose a reason for hiding this comment

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

nit: will default to -> defaults to

return this.client;
}

protected static String buildRegion(String endpoint) {
Copy link
Member

Choose a reason for hiding this comment

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

This can be private

return this.client;
}

protected static String buildRegion(String endpoint) {
// We try to get the region from the metadata instance information
String region = new InstanceMetadataRegionProvider().getRegion();
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't we only be inferring this if the endpoint is not set?

Copy link
Member Author

Choose a reason for hiding this comment

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

That should come in another PR related to #27924 IMO.
Here, the goal is to call new AwsClientBuilder.EndpointConfiguration(endpoint, region). As we don't have the region anymore, I need to guess the region either from the instance metadata and if not available from the endpoint with AwsHostNameUtils.parseRegion(endpoint, null).

Make sense?

@jasontedor jasontedor added v6.1.3 and removed v6.1.2 labels Jan 16, 2018
@colings86 colings86 added v6.3.0 and removed v6.2.0 labels Jan 22, 2018
@bleskes bleskes added v6.1.4 and removed v6.1.3 labels Jan 29, 2018
@clintongormley clintongormley added :Distributed Coordination/Discovery-Plugins Anything related to our integration plugins with EC2, GCP and Azure and removed :Plugin Discovery EC2 labels Feb 13, 2018
@dadoonet
Copy link
Member Author

@rjernst Could you tell me what you think of the PR now?

Copy link
Member

@rjernst rjernst left a comment

Choose a reason for hiding this comment

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

Looks good, one last request.

String region = new InstanceMetadataRegionProvider().getRegion();
if (region == null) {
// Or we try to get it from the endpoint itself
region = AwsHostNameUtils.parseRegion(endpoint, null);
Copy link
Member

Choose a reason for hiding this comment

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

Don't we need to check for null again here? pareRegion can return null if the endpoint is "non standard". I think we need to throw an error in that case or the endpoint configuration will be incorrect (endpoint but null region)?

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah! Good catch. Indeed the AWS implementation returns null. I'm going to add this. Thanks

@dadoonet
Copy link
Member Author

@rjernst I pushed a new change. LMK. Thanks!

@dadoonet
Copy link
Member Author

jenkins test this please

@rjernst
Copy link
Member

rjernst commented Feb 25, 2018

@dadoonet I think you need to sync with master, it looks like CI failed because it can't find gradlew.

@dadoonet
Copy link
Member Author

dadoonet commented Apr 1, 2018

@elastic/es-distributed Any idea on how to solve the test issue I mentioned earlier on? #27925 (comment)

@wedneyyuri
Copy link

The documentation is the most important part of this pull request (took me hours to discover this behavior).

What do you think about merging only the docs?

@dadoonet
Copy link
Member Author

Yeah. I probably should have start only with that.

Copy link

@wedneyyuri wedneyyuri left a comment

Choose a reason for hiding this comment

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

 The only necessary configuration change to enable the plugin
 is setting the unicast host provider for zen discovery

I guess it's not true if the cluster is not in us-east-1.

dadoonet added a commit to dadoonet/elasticsearch that referenced this pull request May 2, 2018
I split elastic#27925 in two parts:

* The documentation fix (this PR)
* The code fix (still in elastic#27925)

Closes elastic#27464.
@dadoonet
Copy link
Member Author

dadoonet commented May 2, 2018

I opened #30323 to fix only the documentation issue which will leave time to merge this PR.

@javanna
Copy link
Member

javanna commented Aug 16, 2018

any updates here @dadoonet ? do we still want to merge this one?

@dadoonet
Copy link
Member Author

@javanna I'm still waiting for an answer about #27925 (comment)

@javanna
Copy link
Member

javanna commented Aug 17, 2018

thanks @dadoonet . ping @elastic/es-distributed your input is needed here. Can we move this forward?

@bleskes
Copy link
Contributor

bleskes commented Sep 9, 2018

@tlrx can you maybe help?

@vladimirdolzhenko
Copy link
Contributor

@dadoonet
Sorry for the so long delay in response. To your #27925 (comment) :

It looks you need some kind of fixture that mimics ec2 like it is done for repository-s3:

AmazonS3Fixture is started before integration test and passing a system property com.amazonaws.sdk.ec2MetadataServiceEndpointOverride (it is like 127.0.0.1:58245) to integration test:

systemProperty "com.amazonaws.sdk.ec2MetadataServiceEndpointOverride", "http://${-> s3Fixture.addressAndPort}"

AmazonS3Fixture handles some EC2 requests (auth for the case of repository-s3) :

// http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html

At least /latest/dynamic/instance-identity/document has to be handled, so region could be specified in that fixture respone.

minor: within buildRegion the call to InstanceMetadataRegionProvider has to be wrapped with SocketAccess.doPrivileged(() -> {...}).

Hope it helps you to proceed further.

@dadoonet dadoonet removed the v7.0.0 label Feb 5, 2019
# Conflicts:
#	docs/plugins/discovery-ec2.asciidoc
#	plugins/discovery-ec2/src/main/java/org/elasticsearch/discovery/ec2/AwsEc2ServiceImpl.java
#	plugins/discovery-ec2/src/test/java/org/elasticsearch/discovery/ec2/AwsEc2ServiceImplTests.java
@dadoonet
Copy link
Member Author

dadoonet commented Feb 7, 2019

I don't know if this PR is still useful or not. I'd assume it might be useless now. Thoughts?
If not, I'll need to change testClientSettingsReInit test as ec2_endpoint_1 and ec2_endpoint_2 are not valid endpoints so we can not guess a region from those values.

Note that documentation was updated with #30323.

There is something which bugs me though. The fact that we are still using deprecated methods to build the AmazonEc2 client.

new AmazonEC2Client(credentials, configuration);

We should now use instead a builder as proposed with the current PR:

AmazonEC2ClientBuilder builder = AmazonEC2ClientBuilder.standard()
     .withCredentials(credentials)
     .withClientConfiguration(configuration)
     .withEndpointConfiguration(endpointConfiguration);
final AmazonEC2 client = builder.build();

Would you like another PR for this?

Copy link
Contributor

@henningandersen henningandersen left a comment

Choose a reason for hiding this comment

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

@dadoonet having discussed this with @DaveCTurner we think it still makes sense to change the discovery plugin such that it by default uses the endpoint for the current region.

Given that this is potentially a breaking change (with master nodes in us-east-1 and data nodes in some other region, the data nodes will no longer be able to discover the master nodes), we should:

  1. Make the new default for discovery.ec2.endpoint explicit by a magic constant like 'current_region_endpoint' (ie. make that the default value for the setting)
  2. Add a breaking changes documentation piece on it.
  3. Update docs to mention this default (kind of back to what it was?)
  4. Only do this in 8.0

Regarding the test failure, it looks like @tlrx may have addressed this in #31107, please check if that resolves the test issue.

endpointConfiguration = new AwsClientBuilder.EndpointConfiguration(clientSettings.endpoint,
buildRegion(clientSettings.endpoint));
} else {
logger.debug("No endpoint defined. Using default endpoint [ec2.us-east-1.amazonaws.com].");
Copy link
Contributor

Choose a reason for hiding this comment

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

When using the AmazonEC2ClientBuilder, the default endpoint is current regions endpoint, see:
https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/java-dg-region-selection.html

This seems like a good default to use, but is a breaking change. See general review comment.

Choose a reason for hiding this comment

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

@henningandersen @DaveCTurner @dadoonet

Hello All,

We are looking for multiple region ec2-discovery option.

Can you please update where are we with the below comment. Is it already implemented and in-use or its gonna be in future release ?

Given that this is potentially a breaking change (with master nodes in us-east-1 and data nodes in some other region, the data nodes will no longer be able to discover the master nodes)

Thanks

Copy link
Contributor

Choose a reason for hiding this comment

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

@suganselvaraj this is still outstanding, i.e., not implemented into master or any releases yet.

Copy link
Member Author

Choose a reason for hiding this comment

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

Note that:

We are looking for multiple region ec2-discovery option.

This is not something we really support AFAIK. You should have all nodes within the same region for latency reasons.

My 2 cents.

Choose a reason for hiding this comment

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

@suganselvaraj I think it will not work using "ec2-discovery" because under the hood it's searching for nodes inside the same aws region.

You can use a fixed list of IP's, but it can cause latency issues.

if (Strings.hasText(clientSettings.endpoint)) {
logger.debug("using explicit ec2 endpoint [{}]", clientSettings.endpoint);
client.setEndpoint(clientSettings.endpoint);
endpointConfiguration = new AwsClientBuilder.EndpointConfiguration(clientSettings.endpoint,
Copy link
Contributor

Choose a reason for hiding this comment

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

As I understand it, the region and endpoint has to go together and really specifying the endpoint should not be done. The region is used to determine signing as well, which means that using a wrong region for an endpoint is unlikely to work (AFAIK). Given that we calculate the region from the endpoint anyway, we may as well just call AwsClientBuilder.withRegion with the region, this will ensure both the endpoint and signing region are set.

return client;
}

// Package private for tests
static String buildRegion(String endpoint) {
Copy link
Contributor

Choose a reason for hiding this comment

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

We should get the region from the endpoint or if endpoint is not set, simply return null. Ie. we do not really need to lookup the region using the InstanceMetadataRegionProvider since the SDK does that by itself when using the client builder.

@DaveCTurner
Copy link
Contributor

Only do this in 8.0

Note that we can add the new magical value, _current_region_endpoint_, in 7.x. We can then inform people that the default will change to _current_region_endpoint_ in 8.0 via a deprecation warning.

@rjernst rjernst added the Team:Distributed (Obsolete) Meta label for distributed team (obsolete). Replaced by Distributed Indexing/Coordination. label May 4, 2020
@elasticsearchmachine elasticsearchmachine changed the base branch from master to main July 22, 2022 23:15
@arteam
Copy link
Contributor

arteam commented Jul 29, 2022

The documentation change has already been addressed in #30323 and the change about guessing the region is redundant since the AWS SDK already does it implicitly if the endpoint isn't provided.

See #27924, #30723

@arteam arteam closed this Jul 29, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
>bug :Distributed Coordination/Discovery-Plugins Anything related to our integration plugins with EC2, GCP and Azure Team:Distributed (Obsolete) Meta label for distributed team (obsolete). Replaced by Distributed Indexing/Coordination.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ec2-discovery plugin document is not accurate.