AWS

CFNカスタムリソースでDynamoDBを初期セットアップ

スポンサーリンク
CloudFormationカスタムリソースでDynamoDBを初期セットアップ AWS
スポンサーリンク
スポンサーリンク

CloudFormationカスタムリソースでDynamoDBを初期セットアップを実行する

CloudFormationでDynamoDB作成時に、DBの初期化として、テストレコードの追加を併せて実行することを考えます。

今回はCloudFormationカスタムリソースを使用して、DynamoDBテーブルの初期セットアップを実施します。

構築する環境

Diagram of initial setup of DynamoDB with CloudFormation custom resources

CloudFormationでDynamoDBテーブルを作成します。

合わせてLambda関数も作成します。
この関数がCloudFormationスタック作成時に自動的に実行されるように、CloudFormationカスタムリソースに関数を関連づけます。
この関数の働きは、DynamoDBテーブルを初期化することです。
初期化処理は、S3バケットに配置されているJSONデータを読み込み、DynamoDBテーブルにアイテムとして登録する処理を行います。
関数のランタイム環境はPython3.8です。

CloudFormationテンプレートファイル

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

awstut-fa/105 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: Artist AttributeType: S - AttributeName: SongTitle AttributeType: S BillingMode: PROVISIONED KeySchema: - AttributeName: Artist KeyType: HASH - AttributeName: SongTitle KeyType: RANGE ProvisionedThroughput: ReadCapacityUnits: !Ref ReadCapacityUnits WriteCapacityUnits: !Ref WriteCapacityUnits TableClass: STANDARD TableName: !Sub "${Prefix}-Music"
Code language: YAML (yaml)

特別な設定は不要です。
以下のAWS公式ページの設定をCloudFormationテンプレートに書き出しました。

ステップ 1: テーブルを作成します - Amazon DynamoDB
コンソールまたは AWS CLI を使用して新しいテーブルを作成することで、Amazon DynamoDB の使用をスタートします。

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

Lambda関数

Resources: Function: Type: AWS::Lambda::Function Properties: Environment: Variables: JSON_S3_BUCKET: !Ref JsonS3Bucket JSON_S3_KEY: !Ref JsonS3Key TABLE_NAME: !Ref Table Code: ZipFile: | import boto3 import cfnresponse import json import os JSON_S3_BUCKET = os.environ['JSON_S3_BUCKET'] JSON_S3_KEY = os.environ['JSON_S3_KEY'] TABLE_NAME = os.environ['TABLE_NAME'] CREATE = 'Create' response_data = {} s3_client = boto3.client('s3') dynamodb_client = boto3.client('dynamodb') def lambda_handler(event, context): try: if event['RequestType'] == CREATE: s3_response = s3_client.get_object( Bucket=JSON_S3_BUCKET, Key=JSON_S3_KEY) body = s3_response['Body'].read() json_data = json.loads(body.decode('utf-8')) print(json_data) for item in json_data: dynamodb_response = dynamodb_client.put_item( TableName=TABLE_NAME, Item=item ) print(dynamodb_response) cfnresponse.send(event, context, cfnresponse.SUCCESS, response_data) except Exception as e: print(e) cfnresponse.send(event, context, cfnresponse.FAILED, response_data) FunctionName: !Sub "${Prefix}-function" Handler: !Ref Handler Runtime: !Ref Runtime Role: !GetAtt FunctionRole.Arn Timeout: !Ref Timeout
Code language: YAML (yaml)

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

cfnresponseモジュールを使用して、関数をLambda-backedカスタムリソースとして実装します。
詳細につきましては、以下のページをご確認ください。

Variablesプロパティで環境変数を定義することができます。
環境変数は関数内から参照することができます。
今回は初期化処理用のデータを格納しているS3バケット名や、ファイル名を環境変数として渡します。

実行するコードの内容ですが、以下の通りです。

  • os.environにアクセスして、CloudFormationテンプレートで定義した環境変数を取得する。
  • Boto3でS3用クライアントオブジェクトを作成して、S3バケットから初期化用のJSONファイルを取得する。
  • Boto3でDynamoDBクライアントオブジェクトを作成して、サンプルデータをテーブルに保存する。
  • cfnresponseモジュールのsend関数を使用して、カスタムリソースが正常に完了した旨のメッセージをCloudFormationに通知する。

S3バケットから読み込むJSONファイルの内容は以下の通りです。

[ {"Artist": {"S": "No One You Know"}, "SongTitle": {"S": "Call Me Today"}, "AlbumTitle": {"S": "Somewhat Famous"}, "Awards": {"N": "1"}}, {"Artist": {"S": "No One You Know"}, "SongTitle": {"S": "Howdy"}, "AlbumTitle": {"S": "Somewhat Famous"}, "Awards": {"N": "2"}}, {"Artist": {"S": "Acme Band"}, "SongTitle": {"S": "Happy Day"}, "AlbumTitle": {"S": "Songs About Life"}, "Awards": {"N": "10"}}, {"Artist": {"S": "Acme Band"}, "SongTitle": {"S": "PartiQL Rocks"}, "AlbumTitle": {"S": "Another Album Title"}, "Awards": {"N": "8"}} ]
Code language: JSON / JSON with Comments (json)

このデータもAWS公式ページで紹介されているデータです。

ステップ 2: コンソールまたは AWS CLI を使用して、テーブルにデータを書き込みます - Amazon DynamoDB
DynamoDB のテーブルに、コンソールまたは AWS CLI を使用してデータを書き込む方法を説明します。

関数用の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}-S3GetObjectPolicy" PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - s3:GetObject Resource: - !Sub "arn:aws:s3:::${JsonS3Bucket}/*" - 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)

AWS管理ポリシーであるAWSLambdaBasicExecutionRoleに加えて、インラインポリシーで2つの権限を与えます。

1つ目はS3バケットからオブジェクトを取得する権限です。
これはサンプルデータであるJSONファイルを取得するために必要な権限です。

2つ目はDynamoDBにアイテムを保存する権限です。
JSONファイル内のデータをDynamoDBテーブルに書き込むために必要な権限です。

CloudFormationカスタムリソース

続いてCloudFormationカスタムリソース本体を確認します。

Resources: CustomResource: Type: Custom::CustomResource Properties: ServiceToken: !Ref FunctionArn
Code language: YAML (yaml)

カスタムリソースに、先述のLambda関数を関連付けます。

環境構築

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

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

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

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

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

AWS Management Consoleから各リソースを確認します。
まずCloudFormationカスタムリソースおよびLambda関数を確認します。

Detail of CloudFormation Custom Resources 1.
Detail of CloudFormation Custom Resources 2.

確かにLambda関数とカスタムリソース本体が正常に作成されていることがわかります。
つまりCloudFormationスタック作成時に、自動的にLambda関数が作成・実行されたことになります。

次にDynamoDBを確認します。

Detail of DynamoDB 1.
Detail of DynamoDB 2.

CloudFormationテンプレートで指定した通りに、DynamoDBテーブルが作成されています。

動作確認

CloudFormationカスタムリソースの動作状況を確認します。

CloudFormationカスタムリソースに紐づけたLambda関数の実行ログを確認します。

Detail of CloudFormation Custom Resources 3.

S3バケットに設置されているJSONデータを読み込んで、1行ずつDynamoDBテーブルに保存しています。
最後にCloudFormationにメッセージを通知しています。

DynamoDBテーブルの内容を確認します。

Detail of DynamoDB 3.

確かにテーブルにアイテムが保存されています。

以上のことから、CloudFormationスタック作成時に、CloudFormationカスタムリソースによって、これに紐づくLambda関数が自動的に実行されて、DynamoDBテーブルにアイテムが保存されたことが確認できました。

まとめ

CloudFormationカスタムリソースを使用して、DynamoDBテーブルの初期セットアップを実施する方法を確認しました。

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