VPCアクセスのAmazon Elasticsearch Serviceに外部からアクセスするための方法としてリバプロを試してみた

VPCアクセスで立てたAmazon Elasticsearch Serviceに外部からアクセスするため、リバプロをAmazon ECSで立てるという環境をAWS CDKで構築してみました。
2019.11.26

こんにちは。サービスグループの武田です。

最近はAmazon Elasticsearch Service(以下、ES)を触っていました。最初は、とりあえず起動すればKibanaにもアクセスできてめっちゃ便利やんな!と気軽に考えていたのですが、それはパブリックアクセスの話だったんですね。VPCアクセスとパブリックアクセスのどちらを選択するのかは要件によりますが、今回はVPCアクセスで構築したいという方針がありました。そうすると外部のネットワークからはESに直接はアクセスできません。

Amazon Elasticsearch Service ドメインの VPC サポート - Amazon Elasticsearch Service

そこで、外部のネットワークからアクセスできる方法をいくつか考えてみました。

  1. 前面にLoadBalancerを置いてルーティングさせる
    1. 過去に大瀧が記事を書いていた方法です
      1. VPCにあるAmazon Elasticsearch ServiceにALBを追加してKibanaだけPublicにする
  2. EC2などでKibanaをホスティング
    1. 過去に藤本が記事を書いていた方法です
      1. VPCにあるAmazon Elasticsearch ServiceのKibanaだけPublicにするもう一つの方法
  3. EC2などでリバプロを立てる
    1. リバプロならホスト名でいいので、IPアドレスが変わっても問題ない
    2. ESのKibanaをそのまま使える
  4. VPNで接続する
    1. 今回はスルー

1はALBのターゲットを定期的にメンテナンスする必要があります。2はせっかくESがKibanaもホスティングしてくれているのでそれを使いたい気持ちがあります(そもそも両エントリの目的と、このエントリの目的は少し違いますね)。3は筋がよさそうですがEC2立てたくないな、と。そんなわけで3の方針を取りつつ極力手間のかからない構成として、リバプロをECSで立てることにしました。

構築した構成は、おおむね次のようになっています。

またソースコード全体はGitHubに上げてあります。

TAKEDA-Takashi/aws-es-and-reverse-proxy

環境

検証環境は次のようになっています。

$ sw_vers
ProductName:	Mac OS X
ProductVersion:	10.14.6
BuildVersion:	18G1012

$ node -v
v10.16.3

やってみた

それでは実際に構築した手順をさらっていきます。前述のとおりGitHubにソースコード一式は上げてありますので、試すだけならcloneしてnpx cdk deployすればあとは待っているだけでいいはずです。

まずはプロジェクトを作成して必要なモジュールをインストールします。

$ cd /path/to/
$ mkdir aws-es-and-reverse-proxy && cd $_ && npx -p aws-cdk cdk init --language typescript
$ npm install @aws-cdk/{aws-ec2,aws-iam,aws-elasticsearch,aws-ecr-assets,aws-ecs-patterns}

次にリバプロの準備ですが、今回はnginxを使いました。向ける先であるESのホスト名は作成してみないとわからないため、Dockerfileに埋め込むことはできません。そこで環境変数から受け取り、それを設定ファイルに反映させる方針で実装しました。

proxy_passにESのホスト名を直接指定してしまうと、IPが変わった場合に対応できないため、一度変数に代入してそれを指定しています(最初ハマりました……)。

Module ngx_http_proxy_module

そして用意した設定ファイルを使えるようにDockerfileを用意します。envsubstを使うことでテンプレート内の変数を環境変数に置換しています。

あとは最初の構成図のように各リソースを作成するプログラムをCDKでがりがり書きます。

最後に、このまま実行しようとすると、設定によってはリージョンなどの指定がないと怒られるようです。Stackをnewする際にenvとして渡すように実行ファイルを修正しておきます。

今度こそデプロイします。

$ npx cdk deploy

しばらく待つと環境ができあがります(エラーが起きたら環境依存の問題のはずです)。ALBのホスト名を指定してKibanaにアクセスすると無事に表示されました!

http://${host_name}/_plugin/kibana/

まとめ

マネージドなサービスを組み合わせてVPCアクセスで立てたESにアクセスできる環境を作ってみました。今回はKibanaへのアクセスにALBのホスト名を使っていますが、Route 53にALIASレコードを作成すればきれいな名前でアクセスできます。また手元のマシンとALBはHTTPで通信していますが、AWS Certificate Managerを使えば簡単に証明書を取得してHTTPSで通信することも可能です。CDKを利用するとこれらの設定もかなり簡単にできますので、ぜひやってみてください。

また今回は検証ということでALBのSGを0.0.0.0/0で全開放しています。実際に運用する場合はアクセス元を絞る必要があるはずですので、そこだけ注意してください。