CloudFormationを使用して、DynamoDBの有効期限(TTL)を有効化する
DynamoDBの機能の1つに、TTLがあります。
Amazon DynamoDB 有効期限 (TTL) では、項目ごとのタイムスタンプを定義して、項目が不要になる時期を特定できます。指定されたタイムスタンプの日付と時刻の直後に、DynamoDB は書き込みスループットを消費することなく、テーブルから項目を削除します。
DynamoDB の有効期限 (TTL) を使用して項目を期限切れにする
TTLの具体的な内容が、AWS公式の以下のページで取り上げられています。
https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/howitworks-ttl.html
本ページでは、CloudFormationを使用して、上記のページを再現することを目的とします。
具体的には、TTLが有効化されたDynamoDBテーブルを作成し、項目の期限が切れた際に、自動的にその項目が削除されることを確認します。
構築する環境
DynamoDBテーブルを作成します。
テーブルには、通常のパーティションキー・ソートキー等の設定に加えて、TTLの有効化に関する設定も行います。
Lambda関数を作成します。
この関数の働きは、サンプルの項目データを作成し、DynamoDBテーブルに保存することです。
関数のランタイム環境はPython3.8とします。
CloudFormationテンプレートファイル
上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置しています。
https://github.com/awstut-an-r/awstut-fa/tree/main/107
テンプレートファイルのポイント解説
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を確認します。
確かにTTLが有効化されています。
次にLambda関数を確認します。
こちらも正常に作成されています。
この関数を実行すると、先ほどのDynamoDBテーブルにサンプルデータが保存されます。
動作確認
準備が整いましたので、Lambda関数を実行します。
正常にLambda関数が実行されました。
関数の実行ログも確認します。
確かに10回DynamoDBテーブルにデータを保存したことがわかります。
テーブルを確認します。
確かにテーブルに10個のサンプルデータが保存されています。
TTL(TTL)の項目を見ると、UNIX時間形式で有効期限が設定されています。
いくつかの項目の有効期限を過ぎるまで、しばらく待機します。
確かに項目数が減りました。
有効期限を過ぎた項目が、自動的に削除されたということです。
さらにしばらく待機します。
すべての項目が削除されました。
このようにDynamoDBでTTLを有効化し、各項目で期限日時を設定することによって、自動的に項目を削除できることがわかりました。
まとめ
TTLが有効化されたDynamoDBテーブルを作成し、項目の期限が切れた際に、自動的にその項目が削除されることを確認しました。