elasticsearch-rubyでAWSのElasticsearch Serviceで構築したElasticsearchに接続したときにはまった
https://dev-nabewata07.hatenablog.com/entry/2019/08/11/183106
上記記事の「アクセスポリシーで権限を設定する」までの手順でドメインの作成、アクセスポリシーの設定を行ったあとにRubyのelasticsearch
とfaraday_middleware/aws_sigv4
というgemを使ってAWSのElasticsearch Serviceで構築したElasticsearchに接続したときにハマったので対応を記録する。
該当のGem
https://rubygems.org/gems/elasticsearch
https://rubygems.org/gems/faraday_middleware-aws-sigv4
環境
Rubyのバージョン
$ ruby -v ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin18]
各Gemのバージョン
aws-sigv4 (1.1.0) elasticsearch (7.3.0) elasticsearch-api (7.3.0) elasticsearch-transport (7.3.0)
結論から
接続先のポート番号が9200
以外のときはElasticsearch::Client.new
でクライアントを作るときは引数でport
も指定する必要がある。
具体的な理由は今回のelasticsearch-ruby
Gemではデフォルトのポート番号が9200
で設定されるがAWSのElasticsearch Serviceで作成したドメインにアクセスするときは80または443番ポートでアクセスする必要があるため。
スクリプトは下記のように記述した。
host = ENV['ES_HOST'] port = 443 client = Elasticsearch::Client.new(host: host, port: port) do |f| f.request :aws_sigv4, service: service, region: region, access_key_id: ENV['AWS_ACCESS_KEY_ID'], secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'] f.adapter Faraday.default_adapter end
最初に記述したスクリプト
require 'elasticsearch' require 'faraday_middleware/aws_sigv4' require 'dotenv' Dotenv.load # e.g. https://my-domain.region.es.com host = ENV['ES_HOST'] region = 'ap-northeast-1' service = 'es' client = Elasticsearch::Client.new(host: host) do |f| f.request :aws_sigv4, service: service, region: region, access_key_id: ENV['AWS_ACCESS_KEY_ID'], secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'] f.adapter Faraday.default_adapter end puts client.cat.indices
実行すると
$ bundle exec ruby sample.rb ... /path/to/ruby/2.6.0/net/http.rb:947:in `initialize': execution expired (Net::OpenTimeout) ... /path/to/ruby/2.6.0/net/http.rb:947:in `initialize': execution expired (Faraday::ConnectionFailed)
上記のように例外が発生して失敗した。
対応
調査したところelasticsearch-transport
のドキュメントにDefult Portの項目があり、別のポート番号の場合は指定するように書いてあった。
https://github.com/elastic/elasticsearch-ruby/tree/master/elasticsearch-transport#default-port
The default port is 9200. Please specify a port for your host(s) if they differ from this default. Please see below for an exception to this when connecting using an Elastic Cloud ID.
もとにしているGemであるelasticsearch-ruby
のドキュメントにも
https://github.com/elastic/elasticsearch-ruby
Usageの項目に
https://github.com/elastic/elasticsearch-ruby#usage
このGemはelasticsearch-transport
とelasticsearch-api
の2つのライブラリのラッパーである旨と
Both of these libraries are extensively documented. Please read the elasticsearch-transport and the elasticsearch-api documentation carefully.
のようにそちらのドキュメントを読むように記述してあった。
具体的には結論から
で書いたようにportを明示的に指定した。
まとめ
当たり前だけどライブラリを使うときはドキュメントを注意深く読む。
心がけていたつもりだったけど時間がないときなどはおろそかにしがちなのでいい反省になった。