aws-beam/aws-elixir

Wrong region for Route53 requests

Closed this issue ยท 12 comments

I tried to list Route53 hosted zones by name, but it failed:

client = AWS.Client.create("<access-key-id>", "<secret-access-key>", "eu-central-1")
AWS.Route53.list_hosted_zones_by_name(client, "example.com")
# 15:45:02.122 [notice] TLS :client: In state :certify at ssl_handshake.erl:2135 generated CLIENT ALERT: Fatal - Handshake Failure
# - {:bad_cert, :hostname_check_failed}
# {:error, %Mint.TransportError{reason: :closed}}

So I had a look into the request and found this:

%Finch.Request{
  scheme: :https,
  host: "route53.us-east-1.amazonaws.com",
  port: 443,
  # ...
}

I was wondering why it uses us-east-1 although I configured the client to use eu-central-1 ๐Ÿค”

Now I had a look into the code to see where us-east-1 comes from:

def metadata do
%{
api_version: "2013-04-01",
content_type: "text/xml",
credential_scope: "us-east-1",
endpoint_prefix: "route53",
global?: true,

And when building the request for a service that is global, metadata.credential_scope is preferred over client.region:

%{global?: true, endpoint: endpoint} ->
endpoint = resolve_endpoint_sufix(endpoint)
region =
if metadata.credential_scope != nil do
metadata.credential_scope
else
client.region
end

When using AWS.Client.put_endpoint(client, "route53.eu-central-1.amazonaws.com"), the request is successful ๐Ÿฅณ

client = AWS.Client.create("<access-key-id>", "<secret-access-key>", "eu-central-1")
client = AWS.Client.put_endpoint("route53.eu-central-1.amazonaws.com")
AWS.Route53.list_hosted_zones_by_name(client, "example.com")
# {:ok, %{"ListHostedZonesByNameResponse" => %{...}}}

Is it a bug or am I doing something wrong? ๐Ÿค” Setting the endpoint feels wrong, especially because this would mean, all other requests to other services (e.g. S3, RDS, ...) would also use this endpoint.

It seems like #186 could be related ๐Ÿค” It speaks about a change that was introduced by #178.

@janpieper I'll have a look at this tonight. I think the correct (and backwards compatible fix) by just looking at this for a few minutes would be to use region either way if the client.region does not match the metadata.credential_scope but I'll have to carefully test this to avoid breaking #178 again as then the next bug report will be from that reporter... ๐Ÿ˜„

@janpieper Any chance you could try:

client = AWS.Client.create("<access-key-id>", "<secret-access-key>", "eu-central-1")
client = AWS.Client.put_endpoint("route53.amazonaws.com")
AWS.Route53.list_hosted_zones_by_name(client, "example.com")

I have a feeling there's a long-standing bug when it comes to the metadata and regions ๐Ÿค” Something that we missed as well when migrating to the V2 of aws-sdk-go. Unfortunately I don't have a good Elixir environment at hand to try out the above so if you could help with testing the above, I'd greatly appreciate it โค๏ธ

Reason I suspect the above is since AWS documents their "global" endpoints here: global-endpoints and only 8 of them are listed there. Yet aws-elixir has 16 modules with: global?: true in it's metadata which sounds like we're off somewhere. Before I go down that rabbit hole I'd like to understand if the above works which is what my suspicion would be.

The request then looks like this:

%Finch.Request{
  scheme: :https,
  host: "route53.amazonaws.com",
  port: 443,
  method: "GET",
  path: "/2013-04-01/hostedzonesbyname",
  headers: [                                              
    # ...
    {"Host", "route53.amazonaws.com"}
  ],
  body: "",
  query: "dnsname=example.com",
  unix_socket: nil,
  private: %{}
}

And I got a valid response back ๐Ÿ˜‰

{:ok,                             
 %{                            
   "ListHostedZonesByNameResponse" => %{      
     "DNSName" => "example.com",
     "HostedZones" => %{
      # ...
     }
  }
}

Thank you @janpieper for confirming my suspicion ๐Ÿ‘ Now I just gotta figure out a clean way of achieving this ๐Ÿ‘

@janpieper This is gonna require a change in aws-codegen (See linked PR ^) as well as a change to request.ex once that change made it into aws-elixir the night after it's merged. So this will take a few days to fix hope that's ok :-)

Thank you for jumping in so fast and for your help ๐Ÿ‘

So this will take a few days to fix hope that's ok :-)

Yes, that's fine! I have a workaround for the moment ๐Ÿ˜‰

@onno-vos-dev This issue is not fixed yet, right? ๐Ÿค”

@janpieper No it is not :-) I linked the two issues "wrongly" so hence this auto-closed. Tonight aws-elixir should get updated so will implement the fix later tonight/over the weekend. Hoping to get it out on hex.pm by Monday/Tuesday ๐Ÿ‘

@janpieper Will prepare a release during my lunch break and ping you here ๐Ÿ‘

@janpieper Managed to squeeze it in now ๐Ÿ‘ Release is out: https://hex.pm/packages/aws/1.0.1

@onno-vos-dev I just removed the workaround and my application is still working ๐Ÿ˜‰ Thanks ๐Ÿฅณ