DynamoDBのテーブルをCloudFormationでデプロイする(YAML)

もくじ

はじめに

やること

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

つまり、DynamoDBをコード化してデプロイします。

以前、CloudFront→API Gateway→Lambda→DynamoDBの簡単なアプリを作ってみたのですが、IaC(Infrastructure as Code)を学ぶにあたり、これらをコード化しようと考えました。

独自ドメイン→CloudFront→S3のHTMLフォームを表示。API Gateway経由でDynamoDBにデータ登録

まずはDynamoDBを行います。(CloudFront、API Gateway、Lambdaも後日コード化すると思います)

コードはYAMLで記述しますが、コードの各プロパティの説明も行います

こんな方々向け

以下のような方々の参考になれば幸いです。

  • DynamoDBのことはよくわからないが、とりあえずDynamoDBをコード化してデプロイしたい
  • CloudFormationを使ったことがないが、とりあえずCloudFormationでコードを書いてみたい

前提

DynamoDBの構造

デプロイするDynamoDBの構造は以下のようになっています。

項目設定値
テーブル名デプロイ時に設定する
テーブルの項目Email(String型)
Name(String型)
Gender(String型)
Inquiry(String型)
パーティションキーEmail
ソートキーName
テーブルのキャパシティRCU:3
WCU:3
グローバルセカンダリインデックス①インデックス名:GSI-Name
パーティションキー:Name
ソートキー:Inquiry
射影される属性:Email
RCU:1
WCU:1
グローバルセカンダリインデックス②インデックス名:GSI-Gender
パーティションキー:Gender
ソートキー:Inquiry
射影される属性:Email
RCU:1
WCU:1

YAMLコード

DynamoDBをデプロイするためのコードは下記になります。

「DynamoDB.yml」というファイル名で保存しました。

---
AWSTemplateFormatVersion: 2010-09-09
Description: "Code for DynamoDB"

Parameters:
  TableName:
    Type: String
    Description: "Name of DynamoDB Table"

Resources:
  DynamoDBTable:
    Type: AWS::DynamoDB::Table
    Properties:
      AttributeDefinitions:
        - AttributeName: "Email"
          AttributeType: "S"
        - AttributeName: "Name"
          AttributeType: "S"
        - AttributeName: "Gender"
          AttributeType: "S"
        - AttributeName: "Inquiry"
          AttributeType: "S"
      KeySchema:
        - AttributeName: "Email"
          KeyType: "HASH"
        - AttributeName: "Name"
          KeyType: "RANGE"
      ProvisionedThroughput:
        ReadCapacityUnits: "3"
        WriteCapacityUnits: "3"
      GlobalSecondaryIndexes:
        - IndexName: "GSI-Name"
          KeySchema:
            - AttributeName: "Name"
              KeyType: "HASH"
            - AttributeName: "Inquiry"
              KeyType: "RANGE"
          Projection:
            NonKeyAttributes:
              - "Email"
            ProjectionType: "INCLUDE"
          ProvisionedThroughput:
            ReadCapacityUnits: "1"
            WriteCapacityUnits: "1"
        - IndexName: "GSI-Gender"
          KeySchema:
            - AttributeName: "Gender"
              KeyType: "HASH"
            - AttributeName: "Inquiry"
              KeyType: "RANGE"
          Projection:
            NonKeyAttributes:
              - "Email"
            ProjectionType: "INCLUDE"
          ProvisionedThroughput:
            ReadCapacityUnits: "1"
            WriteCapacityUnits: "1"
      TableName: !Ref TableName

やってみる

デプロイ

AWSコンソールからCloudFormationダッシュボードに移動して、「スタック」から「スタックの作成」をクリックします。

「テンプレートの準備完了」を選択、「テンプレートファイルのアップロード」を選択、「ファイルの選択」ボタンを押してコードファイル(ここでは「DynamoDB.yml」)を選択して、「次へ」をクリックします。

「スタックの名前」にはCloudFormationのスタック名を入力します。スタックとはCloudFormationの概念で、デプロイするリソースの集まりのようなものです。ひとつのスタックに複数のリソースのデプロイを記述することもできます。ここでは、DynamoDBのみのデプロイを記述したスタックとなります。

スタックの操作

パラメータは、yamlコードで「Parameters」セクションを記述しているので、ここで「テーブルの名前はどうするか?」と聞かれています(後述)。テーブル名を入力して「次へ」をクリックします。

「スタックオプションの設定」画面では今回は特に何も追加せず、「次へ」をクリックします。

最後に「レビュー」画面が表示されるので、内容を確認して「スタックの作成」をクリックします。

スタックの進行ステータスが「CREATE_COMPLETE」になれば成功です。

コード解説

では、コードの中のどの部分が、CloudFormationやDynamoDBのパラメータと紐付いているのか、一つひとつ解説していきます。

AWSTemplateFormatVersion

「形式バージョン」になり、2022年5月20日執筆時点で、「2010-09-09」のみが有効な値となっています。固定値です。

形式バージョン

その下の「Description」説明となり、CloudFormationのスタック「説明」欄に記述されるものとなります。

Parameters

「Parameters」セクションは、CloudFormationでデプロイ時に指定するパラメータを定義する場所です。

CloudFormationでデプロイを実行するとき、下記の「スタックの詳細を指定」ウィンドウで「パラメータ」の入力箇所が出てきましたが、こちらの設定値になります。(下図参照)

“Parameters”のすぐ下に記述した”TableName”の箇所は、任意の文字列を書くことができ、CloudFormationデプロイ時の画面に表示されます。(下図参照)

「Type」には値の型(文字列型や数値型など)を指定し、今回はString型としました。

Descriptionにはパラメータの説明を記述し、こちらもCloudFormationの画面に表示されます。(下図参照)

Resources

「Resources」セクションの直下に”DynamoDBTable”と記載していますが、こちらはCloudFormationの論理IDとなります。自分で任意の文字列を指定できます。

Properties

論理ID(ここでは「”DynamoDBTable」)の中で指定している「Properties」には、作成するDynamoDBの設定値を記述します。

「AttributeDefinitions」DynamoDBテーブル「項目」のことです。「AttributeType」項目の型で、ここでは“S”(String型)を指定しています。その他に、“N”Number型で、“B”Binary型になります。

「KeySchema」ではパーティションキーソートキー定義します。ここでは、”Email”という項目をパーティションキーにして、”Name”という項目をソートキーにしています。コード上で“HASH”と記述するとパーティションキーとなり、“RANGE”と記述するとソートキーとなります。

「ProvisionedThroughput」では、プロビジョンされた読み込み書き込みキャパシティーユニットを記述します。コード上で「ProvisionedThroughput」は2箇所記述していますが、コードの上の方がテープルのキャパシティーユニットで、コードの下の方がインデックスのキャパシティーユニットになります。(下図はテーブルのキャパシティーユニットの設定箇所)

コードの続きを見ていきます。

「GlobalSecondaryIndexes」ではグローバルセカンダリインデックス設定を記述します。

ここでは2つのグローバルセカンダリインデックスを定義していて、”GSI-Name”と”GSI-Gender”になります。「IndexName」の箇所で記述します。

それぞれのグローバルセカンダリインデックスについて、パーティションキーソートキーを記述する箇所が、「KeySchema」の中になります。「AttributeName」キーの名前を記述し、「KeyType」キーのタイプを記述します。キーのタイプは“HASH”パーティションキーとなり、“RANGE”ソートキーとなります。

「Projection」の中では「射影される属性」を記述します。「NonKeyAttributes」射影される属性項目を記述して、「ProjectionType」には“KEYS_ONLY”“INCLUDE”“ALL”を指定します。ここでは”INCLUDE”を指定しています。

「ProvisionedThrouput」ではプロビジョンされた読み込みと書き込みのスループットを記述しますが、こちらはグローバルセカンダリインデックスのものとなります。

最後に「TableName」の欄を見ていきます。

「TableName」はその名のとおり、DynamoDBのテーブル名になります。

ここでは「!Ref」(参照)を使用して、「Parameters」セクションで記述した値テーブル名に使用するようにしています。つまり、CloudFormationでデプロイ時に入力した値が、テーブル名設定されるようにしています。

補足

今回の検証で遭遇したエラーとトラブルシュートを記載します。

ソートキーを2つ指定してしまった

(省略)
'keySchema' failed to satisfy constraint: Member must have length less than or equal to 2 (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException;
(省略)

こちらは、DynamoDBテーブルに2個以上のソートキーを指定しようとして発生しました。(DynamoDBの理解が浅く。。)

DynamoDBテーブルのパターンとしては、「パーティションキーがひとつ」の場合と「パーティションキーとソートキー」の場合があります。

プライマリキー

つまり、パーティションキーとソートキーの個数の合計が2以上になることはないので、上のようなエラーが発生しました。

テーブルの項目をKeySchemaに記載しなかった

One or more parameter values were invalid: Some AttributeDefinitions are not used. AttributeDefinitions: [Gender, Email, Inquiry, Name], keys used: [Email, Inquiry, Name] (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException; 
(省略)

AttributeDefinitionsプロパティで記述したものを、KeySchemaプロパティで記述しなかったときに発生しました。

「KeySchemaプロパティの属性は、AttributeDefinitionsプロパティでも指定する必要がある」とAWSドキュメントに書いてありました。

KeySchema

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!

コメント

コメントする

コメントは日本語で入力してください。(スパム対策)

CAPTCHA

もくじ
閉じる