Cloudflaredを使ってLambdaからローカルに構築したOpenSearchへアクセスする
現在、自分はProfllyというプロフィールビューアーサービスの開発を行っています。
Profllyでは、サービス内の検索エンジンとしてAmazon OpenSearch Service(旧Amazon Elasticsearch Service)を採用しています。
システム内においては、OpenSearch Serviceで起動しているOpenSearchドメインのエンドポイントに対しAWS Lambdaからアクセスを行う、という形になっていますが、開発環境ではコストを抑えたり自由に検証するために、OpenSearch Serviceのインスタンスではなく、個人のローカル環境に構築したOpenSearchを利用したい、というニーズがありました。
このエントリでは、CloudflaredというArgo Tunnel Clientを利用して、ローカルのOpenSearchとLambdaを接続するための構築手順をご紹介します。
構築イメージ
上記画像のように、Amazon OpenSearch Serviceをローカルにて構築したOpenSearch(with Docker)に置き換え、Cloudflare Argo Tunnelを経由してLambdaからアクセスできるようにしてみます。
検証環境
- OpenSearch
1.0.1
- OpenSearch Dashboards
1.0.1
- Docker
20.10.8
- Docker Compose
1.29.2
- Cloudflared
2021.9.1 (built 2021-09-21-1033 UTC)
OpenSearchをローカル環境に構築
まず初めに、以下を参考にしてローカル環境にOpenSearch + OpenSearch Dashboardsを構築・起動しておきます。
今回は検証のためにセキュリティプラグインを無効化したため、Dockerで必要な各ファイルは以下のようになりました。
version: '3' services: opensearch-dashboards: build: context: . dockerfile: Dockerfile.dsbd container_name: opensearch-dashboards environment: OPENSEARCH_HOSTS: http://opensearch:9200 ports: - 5601:5601 links: - opensearch networks: - sandbox opensearch: build: context: . dockerfile: Dockerfile.os container_name: opensearch environment: - cluster.name=docker-cluster - node.name=os-node - cluster.initial_master_nodes=os-node - bootstrap.memory_lock=true - http.host=0.0.0.0 - transport.host=127.0.0.1 - "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m" - "plugins.security.disabled=true" ulimits: memlock: soft: -1 hard: -1 volumes: - $PWD/.local/opensearch:/usr/share/opensearch/data ports: - 9200:9200 networks: - sandbox networks: sandbox:
FROM opensearchproject/opensearch:1.0.1 RUN /usr/share/opensearch/bin/opensearch-plugin install https://artifacts.opensearch.org/releases/plugins/analysis-kuromoji/1.0.0/analysis-kuromoji-1.0.0.zip RUN /usr/share/opensearch/bin/opensearch-plugin install https://artifacts.opensearch.org/releases/plugins/analysis-icu/1.0.0/analysis-icu-1.0.0.zip
server.name: opensearch-dashboards server.host: "0" opensearch.hosts: http://localhost:9200
FROM opensearchproject/opensearch-dashboards:1.0.1 RUN /usr/share/opensearch-dashboards/bin/opensearch-dashboards-plugin remove securityDashboards COPY --chown=opensearch-dashboards:opensearch-dashboards opensearch_dashboards.yml /usr/share/opensearch-dashboards/config/
Cloudflaredを使ってOpenSearchを外部からアクセス可能にする
ローカル環境でOpenSearchが起動できたら、Lambdaからインターネット経由でローカルのOpenSearchへアクセスできるように、ローカル環境でCloudflaredを設定していきます。
Cloudflaredについて
Cloudflaredは、Cloudflare社が提供するArgo Tunnel(Tunneling Daemon)のコマンドラインクライアントです。
Cloudflareのネットワークを介して、任意のローカルウェブサーバをプロキシすることができます。
類似する別のサービスとしては、ngrokなどが挙げられます。
Cloudflaredは、開発用途であれば基本的に無償で利用することが可能で、Cloudflareへのサインアップも必要無くインストールするだけですぐに利用することができます。
注意点として、起動時に割り当てられるURLtrycloudflare.com
のサブドメインは起動ごとにランダムで生成されるため、起動ごとに異なるURLとなります。
実際にLambdaからアクセスする際は、これらを考慮しOpenSearchエンドポイントを環境変数などで外部から設定できるようにしておくとよいでしょう。
また、このエントリでは利用していませんが、自分で取得済みのカスタムドメインを割り当てることもできます。
(但し、利用するためにはCloudflareのサインアップおよびドメインの追加が必要となります)
Cloudflaredのセットアップと起動
それでは、実際にCloudflaredを設定してローカルのOpenSearchを外部公開してみます。
まずは、こちらのドキュメントを参考にインストールを行います。
$ brew install cloudflare/cloudflare/cloudflared
インストールできたら、こちらを参考にCloudflare Tunnelを新規作成し、起動済みのローカルOpenSearchのURL/ポートを割り当ててみます。
$ cloudflared tunnel --url http://localhost:9200
... 2021-09-26T02:57:11Z INF Requesting new quick Tunnel on trycloudflare.com... 2021-09-26T02:57:12Z INF +--------------------------------------------------------------------------------------------+ 2021-09-26T02:57:12Z INF | Your quick Tunnel has been created! Visit it at (it may take some time to be reachable): | 2021-09-26T02:57:12Z INF | https://tex-buildings-sandy-live.trycloudflare.com | 2021-09-26T02:57:12Z INF +--------------------------------------------------------------------------------------------+ ...
コマンドを実行すると、Cloudflare側でランダムなURLを生成し、指定したlocalhostのURLに割り当てられます。
今回は、https://tex-buildings-sandy-live.trycloudflare.com
というURLが生成されたようです。
実際にアクセスできるか、割り当てられたURLを指定してcurlを叩いてみます。
$ curl -XGET https://tex-buildings-sandy-live.trycloudflare.com
{ "name" : "os-node", "cluster_name" : "docker-cluster", "cluster_uuid" : "5wu-pBlIQb-64niPP_zY0A", "version" : { "distribution" : "opensearch", "number" : "1.0.0", "build_type" : "tar", "build_hash" : "34550c5b17124ddc59458ef774f6b43a086522e3", "build_date" : "2021-07-02T23:22:21.383695Z", "build_snapshot" : false, "lucene_version" : "8.8.2", "minimum_wire_compatibility_version" : "6.8.0", "minimum_index_compatibility_version" : "6.0.0-beta1" }, "tagline" : "The OpenSearch Project: https://opensearch.org/" }
ひとまず、OpenSearchにはアクセスできているようですね。
LambdaからローカルOpenSearchへアクセスする
これで外部からローカルのOpenSearchにアクセスできるようになったので、実際にLambdaからアクセスできるかを試してみます。
Lambdaのソースコード
今回、検証のために適当にローカルOpenSearch上に準備したdevio_sample
というインデックスにアクセスしてみます。
Lambdaのサンプルコード(ランタイムはNode.14.x
)は、以下のようになります。
const { Client } = require('@opensearch-project/opensearch'); const OPENSEARCH_ENDPOINT = process.env.OPENSEARCH_ENDPOINT || ""; const client = new Client({ node: OPENSEARCH_ENDPOINT }); exports.handler = async (event) => { const result = await client.search({ index: 'devio_sample', pretty: true }); return result; };
なお、OpenSearchのクライアントライブラリopensearch-js
を利用しているので、コードをLambdaへデプロイする際はパッケージに含めておきます。
$ npm install https://github.com/opensearch-project/opensearch-js $ zip -r function.zip ./
また、OPENSEARCH_ENDPOINT
という環境変数でOpenSearchのエンドポイントを指定できるようにしているので、Lambdaの環境変数に先程割り当てられたURL https://tex-buildings-sandy-live.trycloudflare.com
を設定しておきます。
Lambdaを実行してアクセスしてみる
上記ソースコードのzipがデプロイできたら、実際にLambdaを実行してみます。
無事、ローカルのOpenSearchに格納されたインデックスの検索結果が取得できています!
これにて、Lambda -> ローカルのOpenSearchへのアクセスが実現できました。
おわりに
ローカルに構築されたOpenSearchに対し、Cloudflaredを使ってLambdaからアクセスできるようにしてみました。
開発環境においては、OpenSearch Serviceのインスタンス -> ローカル環境に構築したOpenSearchに切り替えることで、よりコストを抑えた開発が実現できるのではないかと思います。
どなたかの参考になれば幸いです。