0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

OpenSearch ServerlessとDynamoDBをクロスリージョンで更新してみた

Posted at

背景・目的

異なるリージョンから、DDBとOpenSearchへの更新を試してみます。

実践

下記のような構成で試してみます。

image.png

① OpenSearch Serverlessの作成

コレクションの作成

  1. AWSにサインインします

  2. OpenSearchに移動します

  3. ナビゲーションペインの「サーバレス>ダッシュボード」に移動します

  4. 「コレクションを作成」をクリックします

  5. 下記を入力し、「次へ」をクリックします

    • コレクション名:任意
    • コレクションタイプ:検索
    • デプロイタイプ:オフ
    • セキュリティ:標準作成
    • 暗号化:AWS 所有キーを使用する
    • ネットワークアクセスの設定
      • 次からコレクションにアクセス:パブリック
      • リソースタイプ
        • OpenSearchエンドポイントへのアクセスを有効にする
        • OpenSearch Dashboardsへのアクセスを有効にする

    image.png
    image.png

  6. データアクセスの設定で、「スキップして後で設定する」をクリックします

  7. 確認画面で、「送信」をクリックします

データアクセス管理

  1. OpenSearchに移動します
  2. ナビゲーションペインで「セキュリティ>データアクセスポリシー」をクリックします
  3. 「アクセスポリシーを作成」をクリックします
  4. 下記を入力し、「作成」をクリックします
    • アクセスポリシー名
    • プリンシパルを選択
    • リソースと許可を付与
      image.png
      image.png

初期データの作成

  1. OpenSearchダッシュボードに移動します

  2. ナビゲーションペインで「Dev Tools」に移動します

  3. インデックスを登録します

    PUT test-index3
    
    ===
    {
      "acknowledged": true,
      "shards_acknowledged": true,
      "index": "test-index3"
    }
    

    image.png

  4. ドキュメントを登録します

    PUT test-index3/_doc/1
    {
      "id":1,
      "data":"text1"
    }
    
    ===
    {
      "_index": "test-index3",
      "_id": "1",
      "_version": 1,
      "result": "created",
      "_shards": {
        "total": 0,
        "successful": 0,
        "failed": 0
      },
      "_seq_no": 0,
      "_primary_term": 0
    }
    
    
  5. 内容を確認します。登録されていました

    GET test-index3/_search
    {
      "query": {
        "match_all": {}
      }
    }
    ====
    
    {
      "took": 18,
      "timed_out": false,
      "_shards": {
        "total": 0,
        "successful": 0,
        "skipped": 0,
        "failed": 0
      },
      "hits": {
        "total": {
          "value": 1,
          "relation": "eq"
        },
        "max_score": 1,
        "hits": [
          {
            "_index": "test-index3",
            "_id": "1",
            "_score": 1,
            "_source": {
              "id": 1,
              "data": "text1"
            }
          }
        ]
      }
    }
    
    

    image.png

② DynamoDBの作成

  1. DynamoDBに移動します
  2. ダッシュボードで「テーブルの作成」をクリックします
  3. 下記を入力し、「テーブルの作成」をクリックします
    • テーブル名:任意
    • パーティションキー:id
    • 設定をカスタマイズ
    • テーブルアクセス:標準IA
      image.png
      image.png
      image.png
      image.png

初期データの作成

  1. 下記の内容を登録します
    % aws dynamodb put-item \                
    --table-name example_table \
    --item '{"id": {"S": "initial_id"}, "data": {"S": "initial_data"}}' \
    --region ap-northeast-1 \
    % 
    
  2. 内容を確認します。作成されていました
    % aws dynamodb get-item \           
        --table-name example_table \
        --key '{"id": {"S": "initial_id"}}' \
        --region ap-northeast-1
    {
        "Item": {
            "id": {
                "S": "initial_id"
            },
            "data": {
                "S": "initial_data"
            }
        }
    }
    %
    

③ 更新用のLambdaを作成

関数の作成

  1. Lambdaに移動します
  2. リージョンはus-east-2に移動します
  3. 「関数を作成」ボタンをクリックします
  4. 下記を入力し、「関数の作成」ボタンをクリックします
    • 関数名:任意
    • ランタイム:Python 3.12
    • アーキテクチャ:arm64
  5. 下記のコードを貼り付けて、「Deploy」ボタンをクリックします
    from opensearchpy import OpenSearch, RequestsHttpConnection
    from requests_aws4auth import AWS4Auth
    import boto3
    
    def update_opensearch_index():
        client = boto3.client('opensearchserverless')
        service = 'aoss'
        region = 'ap-northeast-1'
        credentials = boto3.Session().get_credentials()
        awsauth = AWS4Auth(credentials.access_key, credentials.secret_key,
                        region, service, session_token=credentials.token)
    
        host = 'XXXXX.ap-northeast-1.aoss.amazonaws.com'
    
        client = OpenSearch(
            hosts=[{'host': host, 'port': 443}],
            http_auth=awsauth,
            use_ssl=True,
            verify_certs=True,
            connection_class=RequestsHttpConnection,
            timeout=60
        )
    
        index_name ='test-index3'
        response = client.index(
            index=index_name,
            body={
                'data': 'test data 2'
            },
            id='2',
        )
        print('\nDocument added:')
        print(response)
    
    def put_ddb_item():
        dynamodb = boto3.resource('dynamodb',region_name='ap-northeast-1')
        table = dynamodb.Table('example_table')
        response = table.put_item(
            Item={
                'id': 'id:2',
                'data': 'test data 2'
            }
        )
        print('\nItem added:')
        print(response)
    
    
    def lambda_handler(event, context):
        update_opensearch_index()
        put_ddb_item()
    
    

レイヤーの作成

  1. 「レイヤーの追加」をクリックします
    image.png
  2. 下記を入力し、「追加」をクリックします(opensearch-pyが含まれています)
    • レイヤーソース:AWSレイヤー
    • AWSレイヤー:AWSSDKPandas-Python312-Arm64
    • バージョン:15
      image.png

LambdaのIAMロールの作成

  1. Lambdaの「設定」タブの「アクセス権限」をクリックします
  2. ロール名をクリックします
    image.png

OpenSearch Serverless

  1. 許可ポリシーで「許可を追加」>「インラインポリシーを作成」をクリックします
  2. 下記を指定して、「次へ」をクリックします
    • すべての OpenSearch Serverless アクション (aoss:*):チェック
    • このアカウント内のいずれか」チェック
      image.png
  3. ポリシー名を入力し、「ポリシーの作成」をクリックします

DynamodDB

  1. 許可ポリシーで「許可を追加」>「ポリシーを追加」をクリックします
  2. 「AmazonDynamoDBFullAccess」を追加します

OpenSearch Serverlessのデータアクセスコントロール

  1. OpenSearch Serverlessに移動します
  2. 該当するコレクションのアクセスポリシーを選択します
  3. 上記で作成したIAMロールをプリンシパルに追加します

④ 参照用のLambdaを作成

関数の作成

  1. Lambdaに移動します
  2. リージョンはap-northeast-1に移動します
  3. 「関数を作成」ボタンをクリックします
  4. 下記を入力し、「関数の作成」ボタンをクリックします
    • 関数名:任意
    • ランタイム:Python 3.12
    • アーキテクチャ:arm64
  5. 下記のコードを貼り付けて、「Deploy」ボタンをクリックします
    from opensearchpy import OpenSearch, RequestsHttpConnection
    from requests_aws4auth import AWS4Auth
    import boto3
    import json
    
    def get_ddb_item():
    
        dynamodb = boto3.resource('dynamodb', region_name='ap-northeast-1')
        table = dynamodb.Table('example_table')
    
        response = table.get_item(Key={'id': 'id:2'})
        dynamo_data = response.get('Item', {})
        print(f"DynamoDB Data: {dynamo_data}")
    
        return dynamo_data
    
    def get_opensearch_index():
        client = boto3.client('opensearchserverless')
        service = 'aoss'
        region = 'ap-northeast-1'
        credentials = boto3.Session().get_credentials()
        awsauth = AWS4Auth(credentials.access_key, credentials.secret_key,
                        region, service, session_token=credentials.token)
    
        host = 'XXXXX.ap-northeast-1.aoss.amazonaws.com'
    
        client = OpenSearch(
            hosts=[{'host': host, 'port': 443}],
            http_auth=awsauth,
            use_ssl=True,
            verify_certs=True,
            connection_class=RequestsHttpConnection,
            timeout=60
        )
    
        index_name = "test-index3"
        response = client.get(
            index=index_name,
            id='2'
            )
    
        print('\nDocument added:')
        print(response)
    
        return response
    
    
    def lambda_handler(event, context):
        ddb_response = get_ddb_item()
        opensearch_response = get_opensearch_index()
    
        return {
            "statusCode": 200,
            "body": json.dumps({
                    "message":"Update successful",
                    "dynamodb":ddb_response,
                    "opensearch-serverless":opensearch_response
    
            })
        }
    

レイヤーの作成

  1. 「レイヤーの追加」をクリックします
  2. 下記を入力し、「追加」をクリックします(opensearch-pyが含まれています)
    • レイヤーソース:AWSレイヤー
    • AWSレイヤー:AWSSDKPandas-Python312-Arm64
    • バージョン:15

LambdaのIAMロールの指定

すでに作成したIAMロールを指定します。

  1. Lambdaの「設定」タブの「アクセス権限」をクリックします
  2. 「編集」をクリックします
  3. 実行ロールを「既存のロールを使用する」を選択後、上記で作成済みのものを指定します

⑤ API Gatewayの作成

  1. API Gatewayに移動します

  2. REST APIで構築をクリックします

  3. 下記を入力し、「APIを作成」をクリックします

    • 新しいAPIを選択
    • API名:任意
    • API エンドポイントタイプ:リージョン
  4. 「メソッドを作成」をクリックします

  5. 下記を入力して、「メソッドを作成」をクリックします

    • メソッドタイプ:GET
    • 統合タイプ:Lambda関数
    • Lambda関数
      • リージョン:ap-northeast-1
      • 関数:上記で作成した関数を指定
        image.png
  6. 「APIをデプロイ」をクリックします

  7. 下記を入力し、「デプロイ」をクリックします

    • ステージ:新しいステージ
    • ステージ名:prd

⑥ 登録

  1. ③で作成したLambda関数を開きます
  2. 「テスト」タブをクリックし、テストをクリックします
  3. 成功しました
    START RequestId: XXXXX Version: $LATEST
    Document added:
    {'_index': 'test-index3', '_id': '2', '_version': 14, 'result': 'updated', '_shards': {'total': 0, 'successful': 0, 'failed': 0}, '_seq_no': 0, '_primary_term': 0}
    Item added:
    {'ResponseMetadata': {'RequestId': 'XXXXXX', 'HTTPStatusCode': 200, 'HTTPHeaders': {'server': 'Server', 'date': 'Sat, 28 Dec 2024 14:20:00 GMT', 'content-type': 'application/x-amz-json-1.0', 'content-length': '2', 'connection': 'keep-alive', 'x-amzn-requestid': 'XXXXXXX', 'x-amz-crc32': '2745614147'}, 'RetryAttempts': 0}}
    END RequestId: XXXXX
    REPORT RequestId: XXXXX	Duration: 4362.21 ms	Billed Duration: 4363 ms	Memory Size: 128 MB	Max Memory Used: 102 MB	Init Duration: 1226.51 ms	
    

⑦ 確認

  1. ブラウザからAPI Gatewayのエンドポイントにアクセスします
  2. 成功しました
    {
      "statusCode": 200,
      "body": "{\"message\": \"Update successful\", \"dynamodb\": {\"id\": \"id:2\", \"data\": \"test data 2\"}, \"opensearch-serverless\": {\"_index\": \"test-index3\", \"_id\": \"2\", \"_version\": 14, \"_seq_no\": 13, \"_primary_term\": 1, \"found\": true, \"_source\": {\"data\": \"test data 2\"}}}"
    }
    
    image.png

考察

今回、AWS Lambdaを利用したクロスリージョンアクセスを試してみました。
出来ることは理解しておりましたが、実際に試したことはなかったので良い経験になりました。
次回は、LambdaをVPC内に配置して、Transit Gatewayでリージョン間を接続した構成で試してみようと思います。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?