Auroraのカスタムエンドポイント割り当て一覧を出力するスクリプトを書いてみた

2019.11.05

こんにちは、平野です。

Auroraのカスタムエンドポイント便利ですね。

今回私は、 何人かのエンドユーザに同一クラスターにアクセスして頂く場合、 特定のユーザのアクセスによって他のお客様のアクセスに影響が出てしまうのを防ぎたい、 というような用途で使用する機会がありました。

なおカスタムエンドポイント自体の内容については下記の記事をご参照頂くと分かりやすいかと思います。

Amazon Auroraで組み合わせ自由なエンドポイントが設定可能になりました

で、4つのカスタムエンドポイントについてそれぞれ2つのReaderノードがきちんと割り当たっているか(合計8つのReaderノード) を確認したいと思ったのですが、 これがひと目に見る方法が見つかりませんでした。 なので、それを実現すべくスクリプトを書いたので共有します。

Pythonスクリプト

早速ですが、スクリプトを貼ります。

import sys
import boto3

if len(sys.argv) < 2:
    print('Usage: python ' + __file__ + ' <DBクラスター識別子>')
    sys.exit(0)

cluster_id = sys.argv[1]
rds_client = boto3.client('rds')


def get_cluster_instances(cluster_id):
    res = rds_client.describe_db_clusters()['DBClusters']
    cluster_info = list(
        filter(lambda x: x.get('DBClusterIdentifier') == cluster_id, res))[0]
    return {
        x['DBInstanceIdentifier']:
        'Writer' if x['IsClusterWriter'] else 'Reader'
        for x in cluster_info['DBClusterMembers']
    }


def get_custom_endpoints(cluster_id):
    res = rds_client.describe_db_cluster_endpoints()['DBClusterEndpoints']
    return list(
        filter(
            lambda x: x['DBClusterIdentifier'] == cluster_id and x[
                'EndpointType'] == 'CUSTOM', res))


instances = get_cluster_instances(cluster_id)
custom_endpoints = get_custom_endpoints(cluster_id)

print("{}\t{}\t{}\t{}".format('ID', 'TYPE', 'FUTURE', 'INSTANCES'))
for endpoint in custom_endpoints:
    endpoint_id = endpoint['DBClusterEndpointIdentifier']
    endpoint_type = endpoint['CustomEndpointType']
    if len(endpoint['StaticMembers']) == 0 and len(
            endpoint['ExcludedMembers']) == 0:
        feature_instance_add = 'True'
        if endpoint_type == 'ANY':
            members = instances.keys()
        elif endpoint_type == 'READER':
            members = list(
                filter(lambda x: instances[x] == 'Reader', instances.keys()))
    elif len(endpoint['StaticMembers']) > 0:
        feature_instance_add = 'False'
        if endpoint_type == 'ANY':
            members = list(
                filter(lambda x: x in instances, endpoint['StaticMembers']))
        elif endpoint_type == 'READER':
            members = list(
                filter(lambda x: x in instances and instances[x] == 'Reader',
                       endpoint['StaticMembers']))
    elif len(endpoint['ExcludedMembers']) > 0:
        feature_instance_add = 'True'
        if endpoint_type == 'ANY':
            members = list(
                filter(lambda x: x not in endpoint['ExcludedMembers'],
                       instances.keys()))
        elif endpoint_type == 'READER':
            members = list(
                filter(
                    lambda x: x not in endpoint['ExcludedMembers'] and
                    instances[x] == 'Reader', instances.keys()))
    print("{}\t{}\t{}\t{}".format(endpoint_id, endpoint_type,
                                  feature_instance_add, ",".join(members)))

実行例

上記スクリプトを適当な名前でファイルにして、以下のように実行します。

python list-current-endpoint.py <クラスター識別子>

クラスター識別子はここに表示されるものです。

出力は以下のようなタブ区切りの表となります。

カラム名 説明
ID エンドポイントの識別子
TYPE ANY or READER(Writerノードを含むかどうか)
FUTURE 未来に追加されるノードを追加するか
INSTANCES 現在紐づいているインスタンス(カンマ区切り)

実行結果確認

スクリプトを使用

$ python list-current-endpoint.py xxxxxxxxx-dbauroracluster-kexxxxxxxxxx
ID                      TYPE    FUTURE  INSTANCES
xxxxxxxxx-txx-prd       READER  False   bd10xxxxxxxxxxx,bd1axxxxxxxxxxx
xxxxxxxxx-rxx-prd       READER  False   bd3jxxxxxxxxxx,bd33xxxxxxxxxx
xxxxxxxxx-qxx-prd       READER  False   bd11xxxxxxxxxxx,bd1lxxxxxxxxxxx
xxxxxxxxx-fxx-prd       READER  False   bd54xxxxxxxxxx,bd1nxxxxxxxxxxx

マネジメントコンソール

モザイクだらけでエビデンスとしてどうなのかって感じですが、 マネジメントコンソールから確認したものと同じ組み合わせが出力されていることが確認できました。 (画像は「fxx」が入ったカスタムエンドポイントのみ)

スクリプトの概要

カスタムエンドポイントが現在どのインスタンスと紐づいているかという情報は、 私が調べた限り、どこにも格納されていないように見えました。 「Writerも含むか、Readerだけか」と、 「未来のインスタンスも含めるのか」という情報を保持しておき、 都度都度現在のインスタンス一覧から紐付け先を算出しているのではないかと思います(あくまでも予測です)。 ということで、スクリプトもただそれを愚直に実装しただけのものになります。

まとめ

カスタムエンドポイントがそれぞれどのインスタンスに紐づいているのか、 一覧で取得する方法がなかったのでスクリプトを書いてみました。

カスタムエンドポイントはそんなに頻繁にいじるものではないかと思いますが、 フェイルオーバーで、ReaderのWriterへの昇格が生じた場合には カスタムエンドポイントを一部振り直したりということが発生するかと思います。 そのような時の確認や、またそれが起きていないことの確認のために定期的にチェックを実行する場合などでも こちらのスクリプトを活用して頂ければと思います。

以上、誰かの参考になれば幸いです。