VPC内にElasticsearchを置く時の注意点
VPC内のプライベートサブネットにElasticsearchを置いたはいいけど、LambdaからAPI叩けないしKibanaもアクセスできなくて困ったときのメモです。
解決策
- BastionServerとして同VPC内にEC2(パブリックサブネット)を置く
- EC2にSSH接続してダイナミックフォワードを行う(ダイナミックフォワードあまりわかっていない...)
- Lambdaを同じVPC内に置く
- 仕様によってプライベートかパブリックかを選択する
- それぞれのリソースに適切なセキュリティグループ(後述)を設定する
セキュリティグループ設定
EC2
Lambda
- 今回はインバウンドの設定は不要(仕様による)
Elasticsearch
ハマりポイント
ElasticsearchのアクセスコントロールでEC2のプライベートIPを許可しようとしたが以下のエラーが出ました。
UpdateElasticsearchDomainConfig: {"message":"You can’t attach an IP-based policy to a domain that has a VPC endpoint. Instead, use a security group to control IP-based access."}
解決策が見つからず2時間くらいはまりましたが、ちゃんと公式に書いてありました。
VPCs ではセキュリティグループを通じてドメインへのアクセスを管理できます。多くのユースケースでは、このセキュリティ機能の組み合わせで十分となり、ドメインにオープンなアクセスポリシーを安心して適用できます。
Amazon Elasticsearch Service ドメインの VPC サポート - Amazon Elasticsearch Service
どうやらセキュリティグループでの制限で十分のようです。
つまりVPC内にElasticsearchを置くケースだとオープンアクセスを選択しておいて、アタッチしているセキュリティグループのみでアクセスの制限を行う形になります。
追記(2021/1/16)
CDKでElasticsearchを作成する時は明示的にオープンアクセスを設定しなければいけないみたいです。
以下がオープンアクセスのポリシーステートメントです。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": "es:*", "Resource": "{domain ARN}/*" } ] }
またKibanaにアクセスするためにSOCKSプロキシを用いたダイナミックフォワード方式ではなく、ローカルフォワード方式でSSHトンネルを掘るときには、EC2にアタッチするセキュリティグループにローカルマシンからの443ポート
アクセスを許可し、8157ポート
を閉じておきましょう。
コマンドもこちらに残しておきます。
$ ssh -i xxxxxxxx.pem ec2-user@{dns} -N -L 9200:{elasticsearch-domain}:443
https://localhost:9200/_plugin/_kibana
へアクセスすると、Kibanaが表示されるはずです。