タダです.
Amazon OpenSearch Service のインデックス再設計に関わった際に,次の運用上の懸念がありました.
- インデックスは月ごとに生成し,生成したインデックスに対してアプリケーションから見た時のエイリアスとして参照用と書き込み用の2つを貼りたい
- 前月以前のインデックスにも参照用エイリアスを残す形で運用したい
上記の運用を実現するために Lambda で上記の処理を行えないか検証したためその内容をこの記事にまとめます.
Lambda の権限と実行コード
Lambda の権限
Lambda の権限は検証として下記の IAM を付与しています.
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "logs:CreateLogGroup", "Resource": "arn:aws:logs:ap-northeast-1:xxx:*" }, { "Effect": "Allow", "Action": [ "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": [ "arn:aws:logs:ap-northeast-1:xxx:log-group:/aws/lambda/xxx:*" ] }, { "Effect": "Allow", "Action": [ "es:ESHttpPost", "es:ESHttpGet", "es:ESHttpPut", "es:ESHttpDelete" ], "Resource": "*" } ] }
実行コード
コードは Python 3.9 で確認しています.
import boto3 import os from requests_aws4auth import AWS4Auth from elasticsearch import Elasticsearch, RequestsHttpConnection from urllib.request import Request, urlopen from datetime import datetime, timedelta, timezone from dateutil.relativedelta import relativedelta ENDPOINT = os.environ['ES_ENDPOINT'] REGION = os.environ['ES_REGION'] SERVICE = 'es' CREDINTIAL = boto3.Session().get_credentials() AWSAUTH = AWS4Auth(CREDINTIAL.access_key, CREDINTIAL.secret_key, REGION, SERVICE, session_token=CREDINTIAL.token) JST = timezone(timedelta(hours=+9), 'JST') def lambda_handler(event, context): client = Elasticsearch( hosts = [{'host': ENDPOINT, 'port': 443}], http_auth = AWSAUTH, use_ssl = True, verify_certs = True, connection_class = RequestsHttpConnection ) write_alias_name = "test-writer-alias" read_alias_name = "test-reader-alias" index_prefix = "test-index-" new_index = index_prefix + datetime.now(JST).strftime('%Y%m') old_index = index_prefix + datetime.strftime(datetime.today() - relativedelta( months = 1 ), '%Y%m') client.indices.update_aliases( body={ "actions": [ {"remove": {"alias": write_alias_name, "index": old_index}}, {"add": {"alias": write_alias_name, "index": new_index}}, {"add": {"alias": read_alias_name, "index": new_index}}, ] } )
Lambda の実行結果確認
Lambda 実行後の挙動を確認していきます.実行前に予め前月のインデックス test-index-202110
とエイリアスとして test-reader-ailias
(参照用エイリアス)と test-writer-alias
(書き込み用エイリアス)を作った状態で確認しています.本記事は2021年の11月に書いているので,インデックスとして test-index-202111
とエイリアスが書き込み,参照が貼られ,前月にも参照用エイリアスが残った状態にできていたら期待通りです.
Lambda実行前
% curl -XGET 'https://xxx.ap-northeast-1.es.amazonaws.com/_alias?pretty=true' { ".kibana_1" : { "aliases" : { ".kibana" : { } } }, "test-index-202110" : { "aliases" : { "test-reader-alias" : { }, "test-writer-alias" : { } } } }
Lambda を実行してみたところ期待通りの結果が得られました.
Lambda実行後
% curl -XGET 'https://xxx.ap-northeast-1.es.amazonaws.com/_alias?pretty=true' { ".kibana_1" : { "aliases" : { ".kibana" : { } } }, "test-index-202110" : { "aliases" : { "test-reader-alias" : { } } }, "test-index-202111" : { "aliases" : { "test-reader-alias" : { }, "test-writer-alias" : { } } }
まとめ
Elasticsearch のインデックスとエイリアスの運用上の懸念に対して Lambda を使ったプローチで検証したのをまとめました.次は,インデックス再設計するためのインデックス移行について書いていければと思います.