ローカルで起動しているElasticsearchにLambdaからアクセスしてみる

2020.04.27

Elasticsearchを使ったシステムを構築するのに、マネージド型サービスであるElasticsearch Serviceを利用しているのですが、開発時は個人で自由に利用でき、コストを抑えて開発するために、ローカル環境に構築したElasticsearchを利用して実装を進めることができますので、そのやり方を紹介します。

やりたいこと

Elasticsearch Serviceの代わりに、LambdaからローカルのDockerで起動したElasticsearch + Kibanaを参照できるように、ngrokでアクセスできるようにします。

実行環境

  • Docker
    • 19.03.8
  • Docker Compose
    • 1.25.4
  • Elasticsearch
    • 7.4.2
  • Kibana
    • 7.4.2
  • ngrok
    • 2.3.35

Elasticsearch + KibanaをDockerで起動

以下を参考にしながら、ElasticsearchとKibanaを起動するよう設定します。

$ tree
.
├── Dockerfile
└── docker-compose.yml

docker-compose.yml

version: '3'

services:
  kibana:
    image: docker.elastic.co/kibana/kibana:7.4.2
    container_name: kibana
    environment:
      - server.name="kibana"
      - elasticsearch.url="http://elasticsearch:9200"
    ports:
      - 5601:5601
    links:
      - elasticsearch
    networks:
      - test

  elasticsearch:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: elasticsearch
    environment:
      - cluster.name=docker-cluster
      - node.name=es-node
      - cluster.initial_master_nodes=es-node
      - bootstrap.memory_lock=true
      - http.host=0.0.0.0
      - transport.host=127.0.0.1
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - $PWD/.local/es:/usr/share/elasticsearch/data
    ports:
      - 9200:9200
    networks:
      - test

networks:
  test:

Dockerfile

FROM docker.elastic.co/elasticsearch/elasticsearch:7.4.2
RUN elasticsearch-plugin install analysis-kuromoji
RUN elasticsearch-plugin install analysis-icu

各種リソース設定など、環境に合わせて設定を変更することができます。 また、追加のプラグインを利用する場合は必要に応じてインストールすることができます。

各種設定できたら、以下のコマンドで起動します。

$ docker-compose up

ngrokを起動

ローカル環境でElasticsearch、Kibanaを起動できたら、インターネットからアクセスできるようにngrokを設定します。 インストールやアカウントのセットアップについては、以下のブログが参考になるかと思います。

セットアップが完了したら、以下のコマンドで起動します。

$ ngrok http 9200

Session Status                online
Account                       [メールアドレス] (Plan: Free)
Version                       2.3.35
Region                        United States (us)
Web Interface                 http://127.0.0.1:4040
Forwarding                    http://[発行されたドメイン] -> http://localhost:9200
Forwarding                    https://[発行されたドメイン] -> http://localhost:9200

これで、ローカルの9200ポートにForwardingに記載されているURLでアクセスすることができます。便利ですね。
少し注意が必要な点としては、今回はFreeプランでアカウントを利用しているので、 ngrokを起動の都度、発行されたドメインが変わります。アクセスするテスト用のドメインをどこかにハードコーディングしてしまうと、都度書き換える必要があるので、外部から設定できるようにしておくことおすすめします。

Lambdaからアクセスしてみる

実際にLambdaからアクセスしてみます。以下の関数を作成し実行してみます。ソースの中で、Elasticsearchのclientを利用しているので、インストールしてzipで固めてアップロードすれば、実行可能となります。
また、今回はElasticsearchのエンドポイントを環境変数で指定しています。この環境変数を変更することで、柔軟に接続先を変更することができて便利です。

index.js

const { Client } = require('@elastic/elasticsearch');

const ELASTICSEARCH_ENDPOINT = process.env.ELASTICSEARCH_ENDPOINT || "";
const client = new Client({
  node: `https://${ELASTICSEARCH_ENDPOINT}`
});

exports.handler = async (event) => {
    const result = await client.search({
        index: 'blog_test',
        pretty: true
    });
    
    return result;
};
$ npm install @elastic/elasticsearch
$ tree -L 1
.
├── index.js
├── node_modules
└── package-lock.json
$ zip -r function.zip ./

作成したLambdaを実行すると、ローカルで起動しているElasticsearchにアクセスできることを確認できました。

さいごに

ローカルで起動したElasticserchを利用することにより

  • 開発中は自分専用の環境がほしい
  • コストを最小限に抑えたい

と言った要望を叶えることができるかなぁと思います。
設定等も比較的簡単にできますので、是非試してみてはいかがでしょうか。