AWS

CFNでDynamoDBの有効期限(TTL)を有効化する

CloudFormationを使用して、DynamoDBの有効期限(TTL)を有効化する

DynamoDBの機能の1つに、TTLがあります。

Amazon DynamoDB 有効期限 (TTL) では、項目ごとのタイムスタンプを定義して、項目が不要になる時期を特定できます。指定されたタイムスタンプの日付と時刻の直後に、DynamoDB は書き込みスループットを消費することなく、テーブルから項目を削除します。

DynamoDB の有効期限 (TTL) を使用して項目を期限切れにする

TTLの具体的な内容が、AWS公式の以下のページで取り上げられています。

有効期限 (TTL) - Amazon DynamoDB
DynamoDB テーブルで 有効期限 (TTL) を設定および使用して、テーブルの項目を自動的に失効させる方法について説明します。項目の削除では、容量ユニットを使用しません。

本ページでは、CloudFormationを使用して、上記のページを再現することを目的とします。
具体的には、TTLが有効化されたDynamoDBテーブルを作成し、項目の期限が切れた際に、自動的にその項目が削除されることを確認します。

構築する環境

Diagram of enabling DynamoDB Expiration Time (TTL) using CloudFormation.

DynamoDBテーブルを作成します。
テーブルには、通常のパーティションキー・ソートキー等の設定に加えて、TTLの有効化に関する設定も行います。

Lambda関数を作成します。
この関数の働きは、サンプルの項目データを作成し、DynamoDBテーブルに保存することです。
関数のランタイム環境はPython3.8とします。

CloudFormationテンプレートファイル

上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置しています。

awstut-fa/107 at main · awstut-an-r/awstut-fa
Contribute to awstut-an-r/awstut-fa development by creating an account on GitHub.

テンプレートファイルのポイント解説

DynamoDB

Resources:
  Table:
    Type: AWS::DynamoDB::Table
    Properties:
      AttributeDefinitions:
        - AttributeName: UserName
          AttributeType: S
        - AttributeName: SessionId
          AttributeType: S
      BillingMode: PAY_PER_REQUEST
      KeySchema:
        - AttributeName: UserName
          KeyType: HASH
        - AttributeName: SessionId
          KeyType: RANGE
      TableClass: STANDARD
      TableName: !Ref Prefix
      TimeToLiveSpecification:
        AttributeName: TTL
        Enabled: true
Code language: YAML (yaml)

DynamoDBに関する基本的な事項については、以下のページでご確認ください。

パーティションキーに「UserName」を、ソートキーに「SessionId」を設定します。

TTLに関する設定はTimeToLiveSpecificationプロパティで行います。
TTLの期限に関するアトリビュートをAttributeNameプロパティで指定します。
今回は「TTL」という名前のアトリビュートを指定します。

Lambda関数

Resources:
  Function:
    Type: AWS::Lambda::Function
    Properties:
      Environment:
        Variables:
          TABLE_NAME: !Ref Table
      Code:
        ZipFile: |
          import boto3
          import datetime
          import json
          import os
          import random
          import string
          import time
          
          TABLE_NAME = os.environ['TABLE_NAME']
          
          dynamodb_client = boto3.client('dynamodb')
          
          def lambda_handler(event, context):
            now = datetime.datetime.now()
          
            for i in range(10):
              username = 'user' + str(i)
              sessionid = ''.join(random.choices(string.ascii_letters + string.digits, k=10))
              
              ttl = now + datetime.timedelta(minutes=i+5)
              ttl_str = ttl.strftime('%Y-%m-%d %H:%M:%S.%f')
              ttl_unix = str(time.mktime(ttl.timetuple()))
              
              item = {
                'UserName': {'S': username},
                'SessionId': {'S': sessionid},
                'TTL_str': {'S': ttl_str},
                'TTL': {'N': ttl_unix}
              }
              
              dynamodb_response = dynamodb_client.put_item(
                TableName=TABLE_NAME,
                Item=item
              )
              print(dynamodb_response)
      FunctionName: !Sub "${Prefix}-function"
      Handler: !Ref Handler
      Runtime: !Ref Runtime
      Role: !GetAtt FunctionRole.Arn
      Timeout: !Ref Timeout
Code language: YAML (yaml)

Lambda関数で実行するコードをインライン形式で記載します。
詳細につきましては、以下のページをご確認ください。

DynamoDB用クライアントオブジェクトを作成後、put_itemメソッドでテーブルに項目を保存します。
今回はサンプルデータを10個作成し、保存することとします。
各項目に設定する有効期限は、関数を実行した時刻を基準として、1分ずつ増やしていきます。

保存する項目ですが、「TTL」がポイントです。
この値をこの項目の期限として使用します。

TTLとして使用する値については、AWS公式では以下の通り説明されています。

TTL 属性の値は Number データ型である必要があります。

TTL 属性の値は、Unix エポック時間形式のタイムスタンプ (秒単位) である必要があります。

項目の TTL 属性のフォーマット

上記に従い、日時データからUNIX時間を計算し、「TTL」に指定します。

Lambda関数用のIAMロールを確認します。

Resources:
  FunctionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Action: sts:AssumeRole
            Principal:
              Service:
                - lambda.amazonaws.com
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
      Policies:
        - PolicyName: !Sub "${Prefix}-DynamodbPutItemPolicy"
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - dynamodb:PutItem
                Resource:
                  - !Sub "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${Table}"
Code language: YAML (yaml)

DynamoDBテーブルに対して、項目を保存する権限を与えます。

環境構築

CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。

CloudFormationスタックを作成し、スタック内のリソースを確認する

CloudFormationスタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。

各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。

  • DynamoDBテーブル:fa-107
  • Lambda関数:fa-107-function

AWS Management Consoleから各リソースを確認します。

DynamoDBを確認します。

Detail of DynamoDB 1.

確かにTTLが有効化されています。

次にLambda関数を確認します。

Detail of Lambda 1.

こちらも正常に作成されています。
この関数を実行すると、先ほどのDynamoDBテーブルにサンプルデータが保存されます。

動作確認

準備が整いましたので、Lambda関数を実行します。

Detail of Lambda 2.

正常にLambda関数が実行されました。

関数の実行ログも確認します。

Detail of Lambda 3.

確かに10回DynamoDBテーブルにデータを保存したことがわかります。

テーブルを確認します。

Detail of DynamoDB 2.

確かにテーブルに10個のサンプルデータが保存されています。
TTL(TTL)の項目を見ると、UNIX時間形式で有効期限が設定されています。

いくつかの項目の有効期限を過ぎるまで、しばらく待機します。

Detail of DynamoDB 3.

確かに項目数が減りました。
有効期限を過ぎた項目が、自動的に削除されたということです。

さらにしばらく待機します。

Detail of DynamoDB 4.

すべての項目が削除されました。
このようにDynamoDBでTTLを有効化し、各項目で期限日時を設定することによって、自動的に項目を削除できることがわかりました。

まとめ

TTLが有効化されたDynamoDBテーブルを作成し、項目の期限が切れた際に、自動的にその項目が削除されることを確認しました。

タイトルとURLをコピーしました