VPC内に置いたElasticsearch ServiceにEC2のプロキシ経由でアクセスする

※追記
この手順はAmazon Linuxでnginxを使用することを想定しています。
Amazon Linux2の場合のnginxのインストールの仕方やサービスの扱い方が異なるのでその旨追記しました。
Amazon Linuxは2020年6月末でサポート切れになるので、その後はAmazon Linuxの表記を消します。
また、この手順はElasticSearchServiceを対象にしていますが、プライベートサブネットにあるサーバやサービスにプロキシ経由でアクセスしたいケースにも使えると思います。

---
先日のアップデートでElasticsearch ServiceをVPC内で使えるようになりました。
https://aws.amazon.com/jp/blogs/news/amazon-elasticsearch-service-now-supports-vpc/

これまではパブリックなエンドポイントしか使えず、VPC内からアクセスするにはパブリックサブネットからの通信が必要でした。
VPC内に配置できれば、通信も全部VPC内で完結しますし、よりセキュアに使うことができるようになりますね。

さて、VPC内に配置したときに起きる問題の一つが、 <span style="color:red">**直接ローカルからKibanaを見ることができない**</span> という問題です。
パブリックサブネットに配置してセキュリティグループで接続許可すれば行けるだろう、と最初は思ったんですが、どうやら無理みたいです。
※うまく行った、という方がいたらご教示ください…。

これを解決するためにどうするかについてはいろいろ調べてみました。
1. ALBを使う。
こちらを参考
https://dev.classmethod.jp/cloud/aws/make-public-kibana-amazon-es/
メリットは管理するサーバが増えないこと。
デメリットは、Elasticsearch ServiceのプライベートIPは可変なのに対し、ALBはターゲットにIPかEC2インスタンスしか設定できず、ターゲットのIPを定期更新するなどしなければならないこと。
1. EC2にKibanaをインストールして、Elasticsearch Serviceを参照するようにする。
こちらを参考
https://dev.classmethod.jp/cloud/aws/make-public-kibana-amazon-es2/  
メリットは、ドメイン指定が可能なのでElasticsearch ServiceのIPが変わっても大丈夫なことなど。 デメリットは、Kibanaの部分がEC2依存になること。
1. Windowsのインスタンスを立ててそこにリモートデスクトップでアクセスし、Windowsインスタンス内のブラウザからKibanaにアクセスする。
読んで字のごとくです。
メリットはやることが単純明快なことかな？
デメリットは大抵のケースで余計なEC2インスタンスを増やさざるを得ないこと。
1. EC2をプロキシサーバにする。(今回の方法)
EC2にKibanaを入れるパターンに近いですが、KibanaもElasticsearch Serviceのものを使用するので、Kibanaの可用性をElasticsearch Service（つまりAmazon側）に依存させたままにできるのがメリットです。
デメリットはこちらもアクセスがEC2依存になること。

今回は調べてもVPC内に配置したElasticsearch Serviceを参照するために使用したという例が見つからなかった、プロキシサーバを使う例について書いてみます。
※別の目的でプロキシサーバ経由にする例はたくさんありましたが、いずれも今回のアップデート以前の情報でした。
今回の例ではnginxを使用しますが、別にApacheでもSquidでもなんでもいいと思います。

# 方法

## パブリックサブネットにEC2インスタンスを用意する。
特に何も考えずに**Amazon Linux**でよいと思います。
インスタンスタイプはとりあえず**t2.micro**でもいいですが、
使ってるうちに負荷がしんどいなと思ったら適宜変更しましょう。
当然のことながら、SSHに加えhttpでアクセスできるようにセキュリティグループを設定します。
場合によっては踏み台サーバと共用とかでも大丈夫かなと。
※今回の例ではhttpを使用し、httpsではやらないようにします。
httpsを使用する例はこちら。(今回の設定もこちらを参考にしています。)
http://inokara.hateblo.jp/entry/2016/10/22/123538

## 用意したEC2からElasticsearch Serviceクラスタにアクセスできるようにする。
セキュリティグループの設定およびアクセスポリシーを適切に設定します。
セキュリティグループだけにしてもいいですし、リソースベース、IPベース、IAMユーザ・ロールベース等ポリシー設定できるのでその時の要件に沿って適切に設定すればOK。
http://docs.aws.amazon.com/ja_jp/elasticsearch-service/latest/developerguide/es-createupdatedomains.html#es-createdomain-configure-access-policies
余談ですが、Elasticserch Serviceの設定変更には意外と時間がかかるので、なるべく設定変更が少ないほうが気持ちが楽だと思います。

## EC2インスタンスにnginxをインストールする。
深く考えずにyumでOKです。

```bash:AmazonLinuxの場合
sudo yum -y install nginx
```

```bash:AmazonLinux２の場合
sudo amazon-linux-extras -y install nginx
```

## /etc/nginx/nginx.confを編集する。
50行目付近に

```nginx:nginx.confの一部
        include /etc/nginx/default.d/*.conf;
        location / {
        }
```

みたいに空で設定されているところがあるので、下記のようにします。
※抜粋、略記しています。


```nginx:nginx.confの一部
        include /etc/nginx/default.d/*.conf;
        location / {
            proxy_pass https://xxxxxxxxxxxxxx.amazonaws.com/;
        }
```

といった感じに、proxy_pathでVPCエンドポイントを指定します。
httpsじゃなくてもいいみたいですが、httpsで問題なくアクセスできます。

## nginxを起動する。
nginxのサービスを起動します。ついでに自動起動もONにしておきましょう。

```bash:AmazonLinuxの場合
sudo service nginx start
sudo chkconfig nginx on
```

```bash:AmazonLinux２の場合
sudo systemctl start nginx
sudo systemctl enable nginx
```


これで
http://{{設定したインスタンスのパブリックIP}}/_plugin/kibana
にアクセスしてやれば、EC2を経由して該当のElasticsearch ClusterのKibanaにアクセスできます。  

# 課題とかおまけとか
後ろに`_plugin/kibana`をつけないでアクセスするとElasticsearchにもアクセスできちゃうので、それを良しとするかどうかは要検討です。
逆にローカルから手軽にデータ投入できたりもするわけですが…。どこまで許容するかですね。
そこを気にするのであれば、nginxの設定とかでディレクトリごとにアクセス制御するとかが必要かもしれません。

あと、Elasticsearch Serviceを配置したVPCにVPN接続している場合はこんなことしなくてもVPNエンドポイントを指定して直接参照できる気がするので、試した方いたらご教示くださると嬉しいです。

ALBでElasticsearch Serviceのインスタンスを指定できるようになればいいんですけどねえ。